文件上传Servlet例子

public class UploadServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Upfile upfile = new Upfile();
		try {
			doUpload(request,upfile);
		} catch (Exception e) {
			e.printStackTrace();
			request.setAttribute("message", "上传失败!!");
			request.getRequestDispatcher("/message.jsp").forward(request, response);
			return;
		} 
		
		
		BusinessService service = new BusinessService();
		service.addUpfile(upfile);
		
		request.setAttribute("message", "上传成功!!");
		request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		doGet(request, response);
	}
	
	//把表单中的普通输入项的数据保存到map中,把上传文件保存到硬盘中
	private void doUpload(HttpServletRequest request, Upfile upfile) throws FileUploadException, IllegalAccessException, InvocationTargetException, IOException{
		
		DiskFileItemFactory factory = new DiskFileItemFactory();
//设置上传文件的临时目录。后面用item.delete()方法删除临时目录里的没用的文件。
		String temppath = this.getServletContext().getRealPath("/WEB-INF/temp");
		String path = this.getServletContext().getRealPath("/WEB-INF/upload");
//设置临时文件目录一定要放在ServletFileUpload创建之前
		factory.setRepository(new File(temppath));
		
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding("UTF-8");
		List<FileItem> list = upload.parseRequest(request);
		for(FileItem item : list){
			if(item.isFormField()){
				String name = item.getFieldName();  //username description
				String value = item.getString("UTF-8");  
				BeanUtils.setProperty(upfile, name, value);
			}else{
				String filename = item.getName();
				int pos = filename.lastIndexOf("\\");
				if(pos>0){
					filename = filename.substring(pos+1);
				}
				
				InputStream in = item.getInputStream();
				
				//得到文件写到服务器硬盘哪个目录中
				String realpath = makeDir(path,filename);
				//得到文件数据写到服务器硬盘的哪个文件中
				String realfilename = makeFileName(filename);
				
				//把文件真实名、在硬盘中的名称和文件的保存目录封装到实体中
				upfile.setFilename(filename);
				upfile.setPath(realpath);
				upfile.setRealfilename(realfilename);
				
				FileOutputStream out = new FileOutputStream(realpath + "\\" + realfilename);
				byte buffer[] = new byte[1024];
				int len = 0;
				while((len=in.read(buffer))>0){
					out.write(buffer, 0, len);
				}
				in.close();
				out.close();
				item.delete();//临时文件删除要在流关闭之后,不然删除不掉,流没有完全关闭的话,会出现占用资源windows系统的问题
				upfile.setUptime(new Date());
			}
		}
	}
	
//打散存储
	private String makeDir(String path,String filename){
		int hashcode = filename.hashCode();
		int dir1 = hashcode&0xf;
		int dir2 = (hashcode>>4)&0xf;
		
		String realpath = path + "\\" + dir1 + "\\" + dir2;
		File file = new File(realpath);
		if(!file.exists()) file.mkdirs();
		
		return realpath;
	}
//防止后来上传文件覆盖存在的文件	
	private String makeFileName(String filename){
		int pos = filename.lastIndexOf(".");
		String ext = filename.substring(pos);
		return UUID.randomUUID().toString() + ext;
	}

}

文件上传的细节处理:

1.上传文件名的中文乱码问题
 解决方案:调用ServletFileUpload.setHeaderEncoding方法即可
 
2.上传表单中的普通字段乱码问题
 解决方案:获取数据时调用FileItem.getString(charset)方法指定字符集即可
 
3.服务器安全性问题
 解决方案:把上传文件保存到外界无法直接访问到的目录,例如WEB-INF目录中

 
4.为防止上传文件被覆盖的问题,要保证上传文件的唯一性
 解决方案:用UUID算法为每一个上传文件生成一个唯的文件名
 
5.为防止一个目录下文件过多,影响系统性能,要打散存储上传文件
 解决方案:用文件名的hash值,生成对应的文件保存目录


6.临时文件的删除问题
 解决方案:在处理完FileItem后,要记得在finally代码块中调用item.delete方法删除临时文件

7.阻止上传非法格式文件
 解决方案:获取到上传文件后,栽取文件的后缀名,根据后缀名判断上传文件是否为合法文件
 
8.监听上传进度

9.在页面里面动态添加文件上传输入项

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值