慕课网Socket实例-文件上传

根据慕课网的Socket通信实例课程,完成的文件上传器实例。某些小问题导致我卡了很久

1.未对实体类进行序列化

2.数据库blob类型反向工程在java中实体类对应字段生成String类型,由于理解有问题,本想将图片信息的字节信息转成字符串信息,但是无法保存图片信息,怎么保存都是11个字节。现在还是不知道BufferedInputStream的read(buff)方法,buff里面存的11个字节的信息代表了什么,感觉像是hashcode地址。

后来直接将对象字段改成byte[]类型,BufferedInputStream的read(buff)方法读取存入buff数组,然后包装成file类型,终于能成功保存到数据库了。


主要是按照老师的思路来,然后自己加了一个Hibernate框架,感觉Hibernate框架不熟练对我来说也是一个坑。


实体类:

文件实体类TbFfile:

package com.imooc.entity;

import com.mysql.jdbc.Blob;

/**
 * TbFile entity. @author MyEclipse Persistence Tools
 */

public class TbFile implements java.io.Serializable {

	// Fields

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer fid;
	private String fname;
	private byte[] fcontent;

	// Constructors

	/** default constructor */
	public TbFile() {
	}

	/** minimal constructor */
	public TbFile(Integer fid, String fname) {
		this.fid = fid;
		this.fname = fname;
	}
	
	

	public TbFile(String fname, byte[] fcontent) {
		super();
		this.fname = fname;
		this.fcontent = fcontent;
	}

	/** full constructor */
	public TbFile(Integer fid, String fname, byte[] fcontent) {
		this.fid = fid;
		this.fname = fname;
		this.fcontent = fcontent;
	}

	// Property accessors

	public Integer getFid() {
		return this.fid;
	}

	public void setFid(Integer fid) {
		this.fid = fid;
	}

	public String getFname() {
		return this.fname;
	}

	public void setFname(String fname) {
		this.fname = fname;
	}

	public byte[] getFcontent() {
		return this.fcontent;
	}

	public void setFcontent(byte[] fcontent) {
		this.fcontent = fcontent;
	}

}

用户实体类 TbUser:

package com.imooc.entity;

/**
 * TbUser entity. @author MyEclipse Persistence Tools
 */

public class TbUser implements java.io.Serializable {

	// Fields

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String username;
	private String password;

	// Constructors

	/** default constructor */
	public TbUser() {
	}
	
	
	public TbUser(String username, String password) {
		this.username = username;
		this.password = password;
	}


	/** full constructor */
	public TbUser(Integer id, String username, String password) {
		this.id = id;
		this.username = username;
		this.password = password;
	}

	// Property accessors

	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUsername() {
		return this.username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}

业务类(主要实现用户类和文件类和数据库的交互):

文件业务操作FileService:

package com.imooc.service;

import java.io.File;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.imooc.entity.TbFile;
import com.imooc.util.HibernateSessionFactory;

/*
 * 文件业务处理
 */
public class FileService {
	
	public void save(TbFile file){
		SessionFactory sessionFactory=HibernateSessionFactory.getSessionFactory();
		Session session=sessionFactory.getCurrentSession();
		Transaction transaction=session.beginTransaction();
		
		session.save(file);
		
		transaction.commit();
//		session.close();
	}
}

用户业务操作UserService:

package com.imooc.service;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import com.imooc.entity.TbUser;
import com.imooc.util.HibernateSessionFactory;
/*
 * 用户业务处理
 */
public class UserService {
	
	SessionFactory sessionFactory=HibernateSessionFactory.getSessionFactory();
	Session session=sessionFactory.getCurrentSession();
	Transaction transaction=session.beginTransaction();
	
	//注册
	public boolean signUp(TbUser user){
		
		String hql="from TbUser as u where u.username=?";
		Query query=session.createQuery(hql);
		query.setString(0, user.getUsername());
		
		List<TbUser> users=query.list();
		transaction.commit();
		
		if(users.size()!=0){
			return false;//根据用户查询到数据说明用户名已存在,注册失败
		}else{
			session=sessionFactory.getCurrentSession();
			transaction=session.beginTransaction();
			session.save(user);
			transaction.commit();
			return true;//查不到说明改用户名有效,注册到数据库并返回true
		}
		
		

	}
	
	//登陆
	public boolean signIn(TbUser user){
//		user.getUsername();
		String hql="from TbUser as u where u.username=? and u.password=?";
		Query query=session.createQuery(hql);
		query.setString(0, user.getUsername());
		query.setString(1, user.getPassword());
		List<TbUser> users=query.list();
		transaction.commit();
//		session.close();
		if(users.size()!=0){
			return true;
		}else{
			return false;
		}
	}
}

Socket通讯类,主要是实现服务器和客户端Socket通信的实现

服务器线程类ServerThread:

package com.imooc.socket;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;

import com.imooc.entity.TbFile;
import com.imooc.entity.TbUser;
import com.imooc.service.FileService;
import com.imooc.service.UserService;
import com.imooc.util.CommandTransfer;


public class ServerThread extends Thread {
	
	private OutputStream os=null;//输出流
	private ObjectOutputStream oos=null;//对象输出流
	private InputStream is=null;//输入流
	private ObjectInputStream ois=null;//对象输入流
	private FileInputStream fis=null;//文件输入流
	
	public Socket socket;
	public ServerThread(Socket socket){
		this.socket=socket;
	}
	
	public void run(){
		CommandTransfer transfer=new CommandTransfer();
		UserService us=new UserService();//用户业务操作对象
		FileService fs=new FileService();//文件业务操作对象
		try {
			
			TbFile file=new TbFile();
			TbUser user=new TbUser();
			transfer=getData();
			
			
			//服务器关于客户端 注册 的 响应
			if(transfer.getCmd().equals("signUp")){
				
				user=(TbUser) transfer.getData();
				boolean flag=us.signUp(user);//注册
				if(flag){
					transfer.setResult("注册成功,请登录!");
					transfer.setFlag(true);
				}else{
					transfer.setResult("注册失败,该用户名已存在!");
					transfer.setFlag(false);
				}
				
				
				sendData(transfer);//发送给客户端
				
				
			}
			
			//服务器关于客户端 登陆 的响应
			if(transfer.getCmd().equals("signIn")){
				user=(TbUser) transfer.getData();
				boolean flag=us.signIn(user);
				if(flag){
					transfer.setFlag(true);
					transfer.setResult("登陆成功,请上传文件!");
				}else{
					transfer.setFlag(false);
					transfer.setResult("账号或密码错误,请重新输入!");
				}
				
				sendData(transfer);//发送给客户端
			}
			
			//服务器关于客户端 上传文件 的响应
			if(transfer.getCmd().equals("upFile")){
				file= (TbFile) transfer.getData();//读取来自客户端的文件信息
				fs.save(file);
				
				transfer.setFlag(true);
				transfer.setResult("文件上传成功!");
				
				sendData(transfer);//发送给客户端
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally{
			closeAll();//关闭所有资源
		}
		
		
	}
	
	
		//向客户端发送数据
		public void sendData(CommandTransfer transfer) throws IOException{
			os=null;
			oos=null;
			os=socket.getOutputStream();
			oos=new ObjectOutputStream(os);
			oos.writeObject(transfer);
			oos.flush();
			
		}
		
		//从客户端接受数据
		public CommandTransfer getData() throws IOException, ClassNotFoundException{
			is=null;
			ois=null;
			CommandTransfer transfer=null;
			is=socket.getInputStream();
			ois=new ObjectInputStream(is);
			transfer = (CommandTransfer) ois.readObject();
			return transfer;
		}
		
		//关闭所有资源
		public void closeAll(){
			
				try {
					if(ois!=null){
						ois.close();
					}
					
					if(is!=null){
						is.close();
					}
					
					if(oos!=null){
						oos.close();
					}
					
					if(os!=null){
						os.close();
					}
					
					if(socket!=null){
						socket.close();
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
}

客户端Socket类,实现客户端的操作逻辑以及和服务器的通信实现:

package com.imooc.socket;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

import com.imooc.entity.TbFile;
import com.imooc.entity.TbUser;
import com.imooc.util.CommandTransfer;

public class SocketClient {
	Scanner input=new Scanner(System.in);
	private Socket socket=null;//客户端Socket
	private OutputStream os=null;
	private ObjectOutputStream oos=null;
	private InputStream is=null;
	private ObjectInputStream ois=null;
	private FileInputStream fis=null;
	
	//显示主菜单
	public void showMenu(){
		System.out.println("*****欢迎使用文件上传器*****");
		System.out.println("1.登陆\n2.注册\n3.退出");
		System.out.println("**********************");
		System.out.println("请选择:");
		int choice=input.nextInt();
		switch(choice){
		case 1:
			showSignIn();
			break;
		case 2:
			showSignUp();
			break;
		case 3:
			System.out.println("再见,感谢您对本系统的支持");
			System.exit(0);
		default:
			System.out.println("输入有误!");
			System.exit(0);
		}
		
	}
	//登陆
	public void showSignIn(){
		TbUser user= new TbUser();
		CommandTransfer transfer=new CommandTransfer();
		int count=0;//登陆次数
		while(true){
			count++;
			if(count>3){
				System.out.println("您已连续三次登陆失败,程序退出!");
				System.exit(0);
			}
			System.out.println("请输入用户名:");
			user.setUsername(input.next());
			System.out.println("请输入密码:");
			user.setPassword(input.next());
			transfer.setCmd("signIn");
			transfer.setData(user);
			
			try {
				socket=new Socket("127.0.0.1",8888);
				sendData(transfer);//将数据发送到服务器
				transfer=getData();//从服务器接受数据
				System.out.println("**********************");
				System.out.println(transfer.getResult());//输出显示结果
				if(transfer.isFlag()){
					
					break;//如果登陆成功则不再重复登陆
				}
				
			} catch (UnknownHostException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}finally{
				closeAll();//关闭所有资源
			}
		}
		showUpFile();//登陆完之后上传文件
	}
	
	//注册
	public void showSignUp(){
		TbUser user= new TbUser();
		CommandTransfer transfer=new CommandTransfer();
		while(true){
			System.out.println("请输入用户名:");
			user.setUsername(input.next());
			System.out.println("请输入密码:");
			user.setPassword(input.next());//注册时第一次输入的密码
			System.out.println("请再次输入密码:");
			//确认密码
			if(!user.getPassword().equals(input.next())){
				System.out.println("两次输入的密码不一致,请重新输入");
				System.out.println("**********************");
				continue;
			}	
			transfer.setCmd("signUp");
			transfer.setData(user);
			
			try {
				socket=new Socket("127.0.0.1",8888);
				sendData(transfer);
				
				transfer=getData();
				
				System.out.println(transfer.getResult());//输出显示结果
				if(transfer.isFlag()){
					break;//若注册成功则不再重复注册
				}
				System.out.println("**********************");	
			} catch (IOException e) {
				e.printStackTrace();
			} catch (ClassNotFoundException e) {
				e.printStackTrace();
			}finally{
				closeAll();//关闭所有资源
			}
		}
		System.out.println("**********************");
		showSignIn();//注册完之后登陆
	}
	
	//上传文件
	public void showUpFile(){
		System.out.println("**********************");
		System.out.println("请输入文件的绝对路径");
		CommandTransfer transfer=new CommandTransfer();//创建命令传输对象,准备传送命令
		TbFile tbFile=new TbFile();//创建实体类TbFile对象,准备接受文件信息
		File file=new File(input.next());//读入文件地址,创建File对象
		
		try {
			fis=new FileInputStream(file);
			BufferedInputStream bis=new BufferedInputStream(fis);
			byte[] fcontent=new byte[fis.available()];//定义缓冲区,准备把文件信息写入缓冲区
			bis.read(fcontent);			
			
			tbFile.setFname(file.getName());//文件名字
			tbFile.setFcontent(fcontent);//文件内容
			
			//发送文件数据到服务器
			socket=new Socket("127.0.0.1",8888);
			transfer.setCmd("upFile");
			transfer.setData(tbFile);
			sendData(transfer);
			
			//从服务器接受信息
			transfer=getData();
			System.out.println(transfer.getResult());//输出显示结果
			
//			System.exit(0);//上传文件后退出
			
			
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally{
			closeAll();//关闭所有资源
		}
		
			
			
		
		
	}
	
	
	//向服务器发送数据
	public void sendData(CommandTransfer transfer) throws IOException{
		os=null;
		oos=null;
		os=socket.getOutputStream();
		oos=new ObjectOutputStream(os);
		oos.writeObject(transfer);
		oos.flush();
		
	}
	
	//从服务器接受数据
	public CommandTransfer getData() throws IOException, ClassNotFoundException{
		is=null;
		ois=null;
		CommandTransfer transfer = null;
				
		is=socket.getInputStream();
		ois=new ObjectInputStream(is);
		
		transfer = (CommandTransfer) ois.readObject();
		
		return transfer;
	}
	
	//关闭所有资源
	public void closeAll(){
		
			try {
				if(ois!=null){
					ois.close();
				}
				
				if(is!=null){
					is.close();
				}
				
				if(oos!=null){
					oos.close();
				}
				
				if(os!=null){
					os.close();
				}
				
				if(socket!=null){
					socket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
	}
}

启动客户端StartClient:

package com.imooc.socket;
/*
 * 启动客户端
 */
public class StartClient {

	public static void main(String[] args) {
		SocketClient socketClient=new SocketClient();
		socketClient.showMenu();
	}

}

启动服务器StartServer:

package com.imooc.socket;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class StartServer {

	public static void main(String[] args) throws IOException {
		ServerSocket serverSocket=new ServerSocket(8888);
		System.out.println("***服务器已就绪,等待客户端访问***");
		while(true){
			//启动服务器,开始监听
			Socket socket=serverSocket.accept();
			ServerThread serverThread=new ServerThread(socket);
			serverThread.start();
		}
	}

}

com.imooc.util主要就是工具类:

CommandTransfer主要是传递命令和数据,返回操作结果(因为服务器Socket接受一次输入流,无法分清楚客户端想让服务器对这个输入流进行什么操作,因此把操作命令和数据重新包装成一个对象,在服务器端接受了输入流之后就有更多的操作空间)

package com.imooc.util;

import java.io.Serializable;

public class CommandTransfer implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private String cmd;
	private Object data;
	private boolean flag;
	private String result;
	

	public String getCmd() {
		return cmd;
	}

	public void setCmd(String cmd) {
		this.cmd = cmd;
	}

	public Object getData() {
		return data;
	}

	public void setData(Object data) {
		this.data = data;
	}

	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	

}

HibernateSessionFactory类是Hibernate框架自动生成的。

另外Hibernate.xml文件配置如下:



数据库的设置和慕课网中课程一样。


运行结果:



另外我看到博客上一片是UI版的,感觉很酷炫,大家自行学习查看

http://blog.youkuaiyun.com/su20145104009/article/details/52843735


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值