一、功能描述
使用eclipse+jdbc+mysql完成用户注册
登陆
以及文件上传操作
文件会保存在mysql数据库中,如图所示
其中会包括一些诸如用户名输入检查等操作
二、代码描述
dao包下的类主要完成与数据库的交互
entity包下的类描述文件、用户、以及TCP传输数据
socket包下的类主要完成客户端与服务器的相关操作
util包下完成jdbc连接数据库的相关工作
注意要将mysql-connector-java-5.1.41-bin.jar包导入项目中
com.imooc.util包
DBUtil.java
package com.imooc.util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 数据库工具类,为java程序提供与数据库的连接
* @author longshao
*
*/
public class DBUtil {
//用于进行数据库连接的URL,如果不加useSSL=false,控制台会发出警告信息
private static final String URL = "jdbc:mysql://127.0.0.1/imooc_taobao?useSSL=false";
//用户名默认为root
private static final String USER = "root";
//此处密码应为连接数据库时所需要的密码
private static final String PASSWORD = "xueminglong@1112";
//工具类提供与数据的连接
private static Connection connection;
/**
* 提供public方法以便项目中其他类能够获取与数据库的连接
* @return 与数据库的连接connection
*/
public static Connection getConnection() {
return connection;
}
//静态块会优先执行,为connection变量赋值
static{
try {
//加载jdbc驱动,对于最新版本的mysql,
//因为采用了最新的SPI技术,驱动的类名在jar包的
//META-INF/services/java.sql.Driver文件里。
// Class.forName("com.mysql.jdbc.Driver");
//为conenction变量赋值
connection = DriverManager.getConnection(URL, USER, PASSWORD);
} catch(SQLException e){
e.printStackTrace();
}
}
}
com.imooc.dao包
UserDao.java
package com.imooc.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.imooc.entity.User;
import com.imooc.util.DBUtil;
/**
* Data access object 用来完成数据的基本操作,如增删改查
* UserDao——数据库db_user的基本操作
* @author longshao
*
*/
public class UserDao {
/**
* 添加用户信息
* @param user
* @throws SQLException
*/
public void insert(User user) throws SQLException{
//获取与数据库的连接
Connection connection = DBUtil.getConnection();
//sql语句,向数据库中添加新的user信息
String sql = "insert into db_user(name,password)"
+ " values (?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setString(1, user.getName());
statement.setString(2, user.getPassword());
//执行insert语句向数据库中添加user信息
statement.executeUpdate();
}
/**
* 获取数据库中全部user信息
* @return
* @throws SQLException
*/
public List query() throws SQLException{
List users = new ArrayList<>();
//获取与数据库的连接
Connection connection = DBUtil.getConnection();
//sql语句,获取全部user信息
String sql = "select * from db_user";
PreparedStatement statement = connection.prepareStatement(sql);
//执行查询语句返回user信息存入结果集
ResultSet set = statement.executeQuery();
//遍历结果集,将查询结果存入user数组中
while (set.next()) {
User user = new User();
user.setId(set.getInt("id"));
user.setName(set.getString("name"));
user.setPassword(set.getString("password"));
users.add(user);
}
return users;
}
}
FileDao.java
package com.imooc.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.imooc.entity.File;
import com.imooc.util.DBUtil;
public class FileDao {
/**
* 添加文件信息
*
* @param user
* @throws SQLException
*/
public void insert(File file) throws SQLException {
// 获取与数据库的连接
Connection connection = DBUtil.getConnection();
// sql语句,向数据库中添加新的user信息
String sql = "insert into db_file(name,content)"
+ " values (?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
//设置插入文件名
statement.setString(1, file.getName());
//设置插入文件内容
statement.setBytes(2, file.getContent());
// 执行insert语句向数据库中添加user信息
statement.executeUpdate();
}
}
com.imooc.entity包
User.java
package com.imooc.entity;
import java.io.Serializable;
/**
* 用户信息类,存储用户名与密码,实现可序列化接口以便使用TCP协议传输
* @author longshao
*
*/
public class User implements Serializable{
/**
* serialVersionUID作用是序列化时保持版本的兼容性,
* 即在版本升级时反序列化仍保持对象的唯一性
*/
private static final long serialVersionUID = 3L;
//id——记录ID信息
private int id;
//name——记录用户姓名信息
private String name;
//password——记录用户密码信息
private String password;
public User() {
}
public User(String name, String password){
this.name = name;
this.password = password;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
//改写该类的toString()方法,以便调试
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", password=" + password + "]";
}
}
File.java
package com.imooc.entity;
import java.io.Serializable;
import java.util.Arrays;
/**
* 文件信息类,存储文件姓名与内容信息,实现可序列化接口以便使用TCP协议传输
* @author longshao
*
*/
public class File implements Serializable{
/**
* serialVersionUID作用是序列化时保持版本的兼容性,
* 即在版本升级时反序列化仍保持对象的唯一性
*/
private static final long serialVersionUID = 2L;
//id——记录ID信息
private int id;
//name——记录文件姓名信息
private String name;
//content——记录文件内容信息
private byte[] content;
public File(){
}
public File(String name, byte[] content) {
this.name = name;
this.content = content;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public byte[] getContent() {
return content;
}
public void setContent(byte[] content) {
this.content = content;
}
//改写该类的toString()方法,以便调试
@Override
public String toString() {
return "File [id=" + id + ", name=" + name + ", content=" + Arrays.toString(content) + "]";
}
}
CommandTransfer.java
package com.imooc.entity;
import java.io.Serializable;
/**
* 传输信息类,存储传输类与命令等信息,实现可序列化接口以便使用TCP协议传输
* @author longshao
*
*/
public class CommandTransfer implements Serializable{
/**
* serialVersionUID作用是序列化时保持版本的兼容性,
* 即在版本升级时反序列化仍保持对象的唯一性
*/
private static final long serialVersionUID = 1L;
private Object data;
private String cmd;
private String result;
private boolean flag;
public CommandTransfer(){
}
public CommandTransfer(String cmd){
this.cmd = cmd;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public String getCmd() {
return cmd;
}
public void setCmd(String cmd) {
this.cmd = cmd;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
@Override
public String toString() {
return "CommandTransfer [data=" + data + ", cmd=" + cmd + ", result=" + result + ", flag=" + flag + "]";
}
}
com.imooc.socket包
Client.java
package com.imooc.socket;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Scanner;
import com.imooc.entity.CommandTransfer;
import com.imooc.entity.File;
import com.imooc.entity.User;
/**
* 客户端程序,实现用户登录,注册,文件上传等功能
*
* @author longshao
*
*/
public class Client {
private int choice;
private Socket socket;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private Scanner input;
private CommandTransfer transfer;
private User user;
private FileInputStream fileInputStream;
private boolean isLogin = false;
private String userName;
private String userPwd;
public static void main(String[] args) {
Client client = new Client();
client.showMainMenu();
}
/**
* 显示客户端主菜单
*/
public void showMainMenu() {
input = new Scanner(System.in);
try {
socket = new Socket("127.0.0.1", 8800);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
//用户可以一直进行发送文件上传或者注册操作,直到用户执行退出操作
while (true) {
System.out.println("*****欢迎使用imooc文件上传器*****");
//判断用户是否处于登陆状态
//未登录,则会提示输入用户名密码
//已登录,则会跳过输入用户名密码操作
if (!isLogin) {
System.out.println("1.登陆");
} else {
System.out.println("1.上传文件");
}
System.out.println("2.注册\n3.退出");
System.out.println("****************************");
System.out.print("请输入数字(1-3)");
// 检查输入,如果不是数字类型或数字不在规定范围内,则提示用户重新输入
while (true) {
// 判断输入是否是数字类型
if (input.hasNextInt()) {
choice = input.nextInt();
// 判断输入是否在规定范围之内
if (choice > 0 && choice < 4) {
// 满足条件,退出循环检查块
break;
}
} else {
// 如果输入不是int类型,要如下刷新输入缓冲区防止程序进入无限循环
input.next();
}
System.out.println("请输入数字(1-3)!");
}
// 根据用户输入的指令代码选择接下来要执行的操作
switch (choice) {
// 输入指令'1',执行用户登录,上传文件操作
case 1:
while(true){
showLogin();
//在登陆后,会提示用户进行文件操作
CommandTransfer transfer = (CommandTransfer) ois.readObject();
//若登陆成功,则会进行文件上传操作
if (transfer.getCmd().equals("success")) {
System.out.println("登陆成功");
isLogin = true;
break;
//若未登录成功,则重新返回主界面
} else {
System.out.println("登录失败");
}
}
showUpload();
break;
// 输入指令'2',执行用户注册操作
case 2:
showRegister();
break;
// 输入指令'3',退出程序
case 3:
System.out.println("谢谢您使用系统,再见!");
oos.writeObject(new CommandTransfer("exit"));
closeAll();
return;
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* showLogin()方法完成用户的登陆操作
*
* @throws IOException
*/
private void showLogin() throws IOException {
transfer = new CommandTransfer("login");
if(!isLogin){
System.out.println("请输入用户名");
userName = input.next();
System.out.println("请输入密码");
userPwd = input.next();
}
user = new User();
user.setName(userName);
user.setPassword(userPwd);
transfer.setData(user);
oos.writeObject(transfer);
oos.flush();
}
/**
* showRegister()方法完成用户的注册操作
*
* @throws IOException
*/
private void showRegister() throws IOException {
transfer = new CommandTransfer("register");
user = new User();
System.out.println("请输入注册用户名");
user.setName(input.next());
while (true) {
System.out.println("请输入密码");
user.setPassword(input.next());
System.out.println("请重新输入密码");
String rePassword = input.next();
if (user.getPassword().equals(rePassword)) {
break;
}
System.out.println("两次密码输入不一致!");
}
transfer.setData(user);
oos.writeObject(transfer);
oos.flush();
System.out.println("注册成功");
}
/**
* showUpload()方法
*
* @throws IOException
*/
private void showUpload() throws IOException {
transfer = new CommandTransfer("upload");
System.out.println("请输入文件的绝对路径,如e:/imooc/dog.jpg");
String path = input.next();
String fileName = path.substring(path.lastIndexOf('/') + 1);
fileInputStream = new FileInputStream(path);
byte[] content = new byte[fileInputStream.available()];
fileInputStream.read(content);
File file = new File(fileName, content);
transfer.setData(file);
oos.writeObject(transfer);
}
/**
* closeAll()关闭所有输入、输出流
*
* @throws IOException
*/
private void closeAll() throws IOException {
if (socket != null) {
socket.close();
}
if (ois != null) {
ois.close();
}
if (oos != null) {
oos.close();
}
if (input != null) {
input.close();
}
if (fileInputStream != null) {
fileInputStream.close();
}
}
}
Server.java
package com.imooc.socket;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 服务器程序 服务器会保持在运行状态,每当一个客户端连接到服务器时, 服务器会自动开启 一个线程用来与客户端进行交互
*
* @author longshao
*
*/
public class Server {
public static void main(String[] args) {
ServerSocket serverSocket = null;
int count = 1;
try {
// 新建服务器连接端口号为8800
serverSocket = new ServerSocket(8800);
// 服务器将会一直运行直到内部发生错误
while (true) {
// 调用ServerSocket的accept方法会阻塞进程直到新的客户端连入服务器
Socket socket = serverSocket.accept();
// 使用我们编写的线程处理程序,新建一条线程用来处理客户端请求
ServerThread thread = new ServerThread(socket);
// 线程启动运行
thread.start();
// 每当连入一个新的客户端时,count变量会自增以便记录连入到服务器的进程数
System.out.println("当前客户端连接ID:" + count++);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
// 若在服务器程序运行过程中发生错误,关闭serversocket
try {
serverSocket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
ServerThread.java
package com.imooc.socket;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.SQLException;
import java.util.List;
import com.imooc.dao.FileDao;
import com.imooc.dao.UserDao;
import com.imooc.entity.CommandTransfer;
import com.imooc.entity.File;
import com.imooc.entity.User;
public class ServerThread extends Thread {
private boolean isLogin = false;
private Socket socket;
private UserDao userDao;
private User user;
private ObjectOutputStream oos;
private ObjectInputStream ois;
private CommandTransfer transfer;
private File file;
private FileDao fileDao;
/**
* 改写线程的run()方法,处理客户端请求
*/
@Override
public void run() {
execute(socket);
}
/**
* 构造类方法,接收一个socket变量以便完成处理工作
*
* @param socket
*/
public ServerThread(Socket socket) {
this.socket = socket;
}
/**
* execute()方法处理客户端请求
*
* @param socket
*/
private void execute(Socket socket) {
//判断客户端所请求的操作
String order = "";
// 新建用户数据库辅助操作类,以便完成与用户数据库的交互
userDao = new UserDao();
try {
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// 当用户处于未登录状态时,服务器会一直等待用户完成登陆上传操作
// 当用户登陆后,服务器会向文件数据库提交文件并关闭线程
while (!order.equals("exit")) {
//接收客户端发来的CommandTransfer对象
transfer = (CommandTransfer) ois.readObject();
//提取出CommandTransfer对象所包含的指令信息
order = transfer.getCmd();
//判断指令信息进行相应操作
switch (transfer.getCmd()) {
//处理客户端登陆操作
case "login":
executeLogin(transfer);
//若登陆成功,则会向客户端发送成功信息并等待客户端提交所上传的数据
if (isLogin) {
oos.writeObject(new CommandTransfer("success"));
oos.flush();
//接收文件信息以便与数据库进行交互
transfer = (CommandTransfer) ois.readObject();
executeUpload(transfer);
} else {
oos.writeObject(new CommandTransfer("fail"));
oos.flush();
}
break;
//处理客户端注册操作
case "register":
executeRegister(transfer);
isLogin = false;
break;
//处理客户端退出操作
case "exit":
System.out.println("客户端退出登录");
isLogin = false;
break;
}
}
closeAll();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 服务器完成用户登陆操作
*
* @param transfer
* @throws SQLException
* @throws ClassNotFoundException
* @throws IOException
*/
private void executeLogin(CommandTransfer transfer) throws SQLException, ClassNotFoundException, IOException {
user = (User) transfer.getData();
List users = userDao.query();
//遍历所有数据库中的用户信息,判断其中是否含有该用户信息
for (User u : users) {
if (u.getName().equals(user.getName())) {
if (u.getPassword().equals(user.getPassword())) {
System.out.println("登陆成功");
isLogin = true;
break;
}
}
}
System.out.println(user);
}
/**
* 服务器完成用户注册操作
*
* @param transfer
* @throws SQLException
*/
private void executeRegister(CommandTransfer transfer) throws SQLException {
userDao = new UserDao();
user = (User) transfer.getData();
userDao.insert(user);
}
/**
* 服务器完成文件上传操作
*
* @param transfer
* @throws SQLException
*/
private void executeUpload(CommandTransfer transfer) throws SQLException {
file = (File) transfer.getData();
fileDao = new FileDao();
fileDao.insert(file);
}
/**
* 关闭所有输入输出流
*
* @throws IOException
*/
private void closeAll() throws IOException {
socket.close();
ois.close();
oos.close();
}
}