java实现文件上传及要考虑的问题

java文件上传

文件上传三个条件,

1,表单的提交方式是POST   2,enctype类型是multipart/form-data   3,提供文件上传域

常见的文件上传问题:

1,保证服务器的安全,意思是上传的文件的路径不能直接被用户访问到                  ---------> 解决方案: 一般把上传的文件放在WEB-INF目录下
2,如果上传的文件足够多时,可能会出现重名的情况,而一旦重名就会被覆盖      --------->解决方案:  可以使用UUID让文件名唯一
3, 一个目录中的文件可能会很多                                                                                       ----------->解决方案: 1,用日期打散目录   2,用文件名的hashcode打散目录,不过我觉得这个会带来新的问题,比如以后要找某个文件会难找
4,文件上传的大小,一般来说,web方式都不适合上传太大的文件                         ------------>解决方案:  单个文件大小  ServletFileUpload.setFileSizeMax(字节),总的文件大小ServletFileUpload.setSizeMax(字节)
5,用户 没有上传文件                                                                                                           ------------->解决方案: 只要判断文件名是否为空即可
6,临时文件的问题,使用DiskFileItemFactory产生FileItem对象的时候,内部有一个缓存,默认情况下,当上传的文件大小大于10kb时,把文件用磁盘缓存下来,放在系统的临时目录下                                                                                                                                   -------------->解决方案: 如果是使用io,则在关闭流之后, 清理临时文件 FileItem.delete();

使用两个jar包  :commons-fileupload-1.2.2.jar      commons-io-2.2.jar

下面是servlet的代码

UploadServlet.java
package com.it.web.servlet;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;

public class UploadServlet extends HttpServlet{
	public void doGet(HttpServletRequest request,HttpServletResponse response){
		//判断 表单是否支持上传文件(也就是enctype类型是否为multipart/form-data
		boolean isMulitpart=ServletFileUpload.isMultipartContent(request);
		if(!isMulitpart){
			throw new RuntimeException("你的表单不适合上传文件");
		}
		DiskFileItemFactory factory=new DiskFileItemFactory();//创建磁盘文件项工厂对象
		ServletFileUpload sfu=new ServletFileUpload(factory); //通过工厂对象创建核心对象
		sfu.setHeaderEncoding("UTF-8");//解决上传文件乱码
		sfu.setFileSizeMax(1024*1024*3); //限制单个文件大小3m
		//解析request,返回装有文件项的list集合
		try {
			List<FileItem> lists=sfu.parseRequest(request);
			for(FileItem fileItem:lists){
				//判断表单项是普通文本类型还是上传文件类型
				if(fileItem.isFormField()){
					OrdinaryFormField(fileItem); //普通
				}else{
					UploadFormField(fileItem,request,response);  //上传文件类型
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 文件上传类型
	 * @param fileItem
	 * @param request
	 * @param response
	 * @throws IOException 
	 * @throws ServletException 
	 */
	private void UploadFormField(FileItem fileItem, HttpServletRequest request,
			HttpServletResponse response){
		//1,得到文件名
		String fileName=fileItem.getName();//问题1 : fileName可能包含路径
		if(fileName==null || "".equals(fileName.trim())){
			request.setAttribute("fileEmpty","您还未选文件");
			try {
				request.getRequestDispatcher("/upload1.jsp").forward(request, response);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}
		//解决问题1
		if(fileName!=null){
			fileName=FilenameUtils.getName(fileName);
		}
		//解决文件重名问题
		fileName=UUID.randomUUID()+"_"+fileName;
		//上传文件的存储路径
		String realPath=this.getServletContext().getRealPath("/WEB-INF/upload");//该目录浏览器不能直接访问
		File storyDirectory=new File(realPath);
		if(!storyDirectory.exists()){
			storyDirectory.mkdirs();
		}
		//解决同一个 目录下文件太多的问题,用天数大散目录
		String childDirectory=makeChildDirectory(storyDirectory);
		//将时间目录添加到路径下
		File file=new File(storyDirectory,childDirectory+File.separator+fileName);
		try {
			fileItem.write(file);
			response.sendRedirect(request.getContextPath()+"/success.jsp");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	/**
	 * 按天数大散目录
	 * @param storyDirectory
	 * @return
	 */
	private String makeChildDirectory(File storyDirectory) {
		Date date=new Date();
		SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
		String dateDirectory=format.format(date);
		File file=new File(storyDirectory,dateDirectory);
		if(!file.exists()){
			file.mkdirs();
		}
		return dateDirectory;
	}
	/**
	 * 普通文本类型
	 * @param fileItem
	 */
	private void OrdinaryFormField(FileItem fileItem) {
		//得到字段名
		String fieldName=fileItem.getFieldName();
		//字段值
		String fieldValue=null;
		try {
			fieldValue = fileItem.getString("UTF-8");//解决编码问题
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		System.out.println(fieldName+"\t"+fieldValue);
	}
	public void doPost(HttpServletRequest request,HttpServletResponse response){
		this.doGet(request, response);
	}
}

下面是jsp的代码和运行视图

upload1.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
   	<title>上传文件</title>
  </head>
  <body>
		<form action="${pageContext.request.contextPath }/upload1Servlet" method="POST" enctype="multipart/form-data">
			用户名:<input type="text" name="username"><br/>
			上传:<input type="file" name="uploadfile"><br/>${fileEmpty}		
			<input type="submit" value="提交"/>
		</form>   
  </body>
</html>


上传成功后会在WEB-INF目录 下多了一个upload目录,里面有上传的文件


  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值