java文件上传总结

最近公司项目用到文件上传,总结一下

第一种 传统表单上传比较简单,网上也有好多文章介绍,推荐一篇:表单方式文件上传和下载

再此只提醒两点:

一,form表单中要加入enctype="multipart/form-data" method="post"

POST上传文件

最早的HTTP POST是不支持文件上传的,在1995年,ietf出台了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。所以Content-Type的类型扩充了multipart/form-data用以支持向服务器发送二进制数据。因此发送post请求时候,表单

属性enctype共有二个值可选,这个属性管理的是表单的MIME编码:

 ①application/x-www-form-urlencoded(默认值)
 ②multipart/form-data

二, 如果使用ssm框架时,不要有如下配置,不然会报错:fileupload插件调用upload.parseRequest(request)解析得到空值

  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  
  
 

表单提交提醒很不方便,

第二种 写原生的Ajax,用XMLHttpRequest 和FormData对象

前台用的是jsp

<%@ page language="java" contentType="text/html; charset=GBK"
    pageEncoding="GBK"%>





上海电信







后台是Java

	@RequestMapping("/uploads")
	public String uploads(HttpServletRequest request,HttpServletResponse response){
		
		logger.debug("进入 DataAcquisitionController.uploads");
		//得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
		Date date=new Date();
		SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
		StringBuffer path=new StringBuffer();
		path.append("/WEB-INF/upload/");
		path.append(sdf.format(date));
        String savePath = request.getSession().getServletContext().getRealPath(path.toString());
        //上传时生成的临时文件保存目录
        String tempPath = request.getSession().getServletContext().getRealPath("/WEB-INF/temp");
        File tmpFile = new File(tempPath);
        File saveFile = new File(savePath);
        if (!tmpFile.exists()) {
            //创建临时目录
            tmpFile.mkdir();
        }
        if(!saveFile.exists() && !saveFile.isDirectory()){
        	saveFile.mkdirs();
        }
        //消息提示
        String message = "";
        try{
            //使用Apache文件上传组件处理文件上传步骤:
            //1、创建一个DiskFileItemFactory工厂
            DiskFileItemFactory factory = new DiskFileItemFactory();
            //设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
            factory.setSizeThreshold(1024*100);//设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
            //设置上传时生成的临时文件的保存目录
            factory.setRepository(tmpFile);
            //2、创建一个文件上传解析器
            ServletFileUpload upload = new ServletFileUpload(factory);
            //监听文件上传进度
            upload.setProgressListener(new ProgressListener(){
                public void update(long pBytesRead, long pContentLength, int arg2) {
                	logger.debug("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
                }
            });
             //解决上传文件名的中文乱码
//            upload.setHeaderEncoding("UTF-8"); 
            //3、判断提交上来的数据是否是上传表单的数据
            if(!ServletFileUpload.isMultipartContent(request)){
                //按照传统方式获取数据
            	request.setAttribute("msg", "form表单为空");
        		return "dataAcquisition";
            }
            
            //设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
            upload.setFileSizeMax(1024*1024);
            //设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
            upload.setSizeMax(1024*1024*10);
            //4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List集合,每一个FileItem对应一个Form表单的输入项
            List list = upload.parseRequest(request);
            DataAcquisitionPo dataAcquisitionPo=new DataAcquisitionPo();
            OperationDataPo operationDataPo=new OperationDataPo();
            for(FileItem item : list){
            	String name = item.getFieldName();
                //如果fileitem中封装的是普通输入项的数据
                if(item.isFormField()){
                    String value = item.getString();
                    if("remark".equals(name)){
                    	dataAcquisitionPo.setRemark(value);
                    }
                    if("deviceTotal".equals(name)){
                    	dataAcquisitionPo.setDeviceTotal(value);
                    	operationDataPo.setCount(Integer.valueOf(value));
                    }
                }else{//如果fileitem中封装的是上传文件
                    //得到上传的文件名称,
                    String filename = item.getName();
                    filename=java.net.URLDecoder.decode(filename,"UTF-8");
                    logger.debug("filename:"+filename);
                    if(filename==null || filename.trim().equals("")){
                        continue;
                    }
                    //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:  c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
                    //处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                    filename = filename.substring(filename.lastIndexOf("\\")+1);
                    //得到上传文件的扩展名
                    String fileExtName = filename.substring(filename.lastIndexOf(".")+1);
                    //如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
                    logger.debug("上传的文件的扩展名是:"+fileExtName);
                    //获取item中的上传文件的输入流
                    InputStream in = item.getInputStream();
                    //得到文件保存的名称
                    SimpleDateFormat sd=new SimpleDateFormat("yyyyMMddhhmmssSSS");
                    Date dating=new Date();
                    String saveFilename = sd.format(dating)+"."+fileExtName;
//                    String saveFilename = sd.format(dating) + "_" + filename;
                    //创建一个文件输出流
                    FileOutputStream out = new FileOutputStream(savePath + "\\" + saveFilename);
                    if("enterFile".equals(name)){
                    	dataAcquisitionPo.setAttachmentEnterprise(savePath + "\\" + saveFilename);
                    }
                    if("deviceFile".equals(name)){
                    	dataAcquisitionPo.setAttachmentDevice(savePath + "\\" + saveFilename);;
                    }
                    //创建一个缓冲区
                    byte buffer[] = new byte[1024];
                    //判断输入流中的数据是否已经读完的标识
                    int len = 0;
                    //循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
                    while((len=in.read(buffer))>0){
                        //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
                        out.write(buffer, 0, len);
                    }
                    //关闭输入流
                    in.close();
                    //关闭输出流
                    out.close();
                    //删除处理文件上传时生成的临时文件
                    //item.delete();
                    message = "文件上传成功!";
                }
            }
            String userName=((UserPo) request.getSession().getAttribute("user")).getUserName();
            dataAcquisitionPo.setOperator(userName);
//            dataAcquisitionService.insert(dataAcquisitionPo);
            
            operationDataService.insert(operationDataPo);
        }catch (FileUploadBase.FileSizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("msg", "单个文件超出最大值!!!");
    		return "dataAcquisition";
        }catch (FileUploadBase.SizeLimitExceededException e) {
            e.printStackTrace();
            request.setAttribute("msg", "上传文件的总的大小超出限制的最大值!!!");
            return "dataAcquisition";
        }catch (Exception e) {
            message= "文件上传失败!";
            e.printStackTrace();
        }
		request.setAttribute("msg", message);
		return "dataAcquisition";
	}

第三种 用Ajax和FormData

function doUpload() {
	var fileObj1 = document.getElementById("enterFile").files[0]; // js 获取文件对象
    var fileObj2 = document.getElementById("deviceFile").files[0]; // js 获取文件对象
    var fileObj3 = $("#deviceTotal").val(); // js 获取文件对象
    var FileController = "${pageContext.request.contextPath}/mvc/dataAcquisition/uploads";                    // 接收上传文件的后台地址 
    // FormData 对象
    var form = new FormData();
    //form.append("author", "hooyes");                        // 可以增加表单数据

    form.append("enterFile", fileObj1);                           // 文件对象
    form.append("deviceFile", fileObj2);                           // 文件对象
    form.append("deviceTotal", fileObj3);                           // 文件对象
	$.ajax({
		url: contextPath + "/mvc/dataAcquisition/doUploads",
		type: "post",
		data: form,
		dataType : "json",
		//async: false,
		contentType: false, //不加后台会报异常FileUploadBase$InvalidContentTypeException
		processData: false, //不加前台会报错Illegal invocation
		success: function(data){
			alert(data.msg);
		},
		error: function(data) {
			alert("操作失败!!!");
		}
	});
}


第四种 用jquery.form.js里的ajaxForm(我没成功,有兴趣的可以用用)

你可能感兴趣的:(Java基础)