java文件上传总结

来源:互联网 发布:淘宝怎么加入天猫 编辑:程序博客网 时间:2024/05/17 22:33

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

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

再此只提醒两点:

一,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请求时候,表单<form>属性enctype共有二个值可选,这个属性管理的是表单的MIME编码:

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

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

<bean id="multipartResolver"
  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
  <!-- 设置上传文件大小的参数 ,当前为100M -->
  <property name="maxUploadSize" value="104857600" />
 </bean>

表单提交提醒很不方便,

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

前台用的是jsp

<%@ page language="java" contentType="text/html; charset=GBK"    pageEncoding="GBK"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=GBK"><meta http-equiv="X-UA-Compatible" content="IE=edge"><title>上海电信</title><jsp:include page="main.jsp"></jsp:include><script type="text/javascript">function deviceTotal_check(){var result=true;var deviceTotal = $("#deviceTotal").val().trim();var reg=/^[0-9]*$/;if (deviceTotal == null || deviceTotal.length == 0){result = false;}if(!reg.test(deviceTotal)){result = false;}return result;}function enterFile_check(){var result=true;var enterFile = document.getElementById("enterFile").value;if (enterFile == null || enterFile.length == 0){result = false;}return result;}function deviceFile_check(){var result=true;var deviceFile = document.getElementById("deviceFile").value;if (deviceFile == null || deviceFile.length == 0){result = false;}return result;}//XMLHttpRequest 对象var xhr = new XMLHttpRequest();function UpladFile() {if(!enterFile_check()){alert("企业附件不能为空!");return false;}if(!deviceFile_check()){alert("分机附件不能为空!");return false;}if(!deviceTotal_check()){alert("分机总数不合法!");return false;}    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);                           // 文件对象        xhr.onreadystatechange = callBack;    xhr.open("post", FileController, true);    xhr.upload.addEventListener("progress", progressFunction, false);    xhr.send(form);}function progressFunction(evt) {    var progressBar = document.getElementById("progressBar");    var percentageDiv = document.getElementById("percentage");    if (evt.lengthComputable) {    //$("#alertModal").modal({show:true});        progressBar.max = evt.total;        progressBar.value = evt.loaded;        percentageDiv.innerHTML = Math.round(evt.loaded / evt.total * 100) + "%";    }    if(evt.total==evt.loaded){    //$("#alertModal").modal('hide');        }}  function callBack(){if(xhr.readyState==4){if(xhr.status==200){var msg=$("#message").val();clearInput();    alert("操作完成!"+msg)//xhr.responseText;}}}function clearInput(){$("#enterFile").val("");$("#deviceFile").val("");$("#deviceTotal").val("");}</script><style>body {   font-family: "Times New Roman", "Microsoft YaHei", "微软雅黑", STXihei, "华文细黑", serif;   background-color: #F0F0F2;}</style></head><body><div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true" style="width:500px;margin-top:20px; margin-left: auto; margin-right: auto;">    <div class="panel panel-default">    <div class="panel-heading" role="tab" id="headingOne" style="background-color: #404f64;color: #ffffff;">      <h4 class="panel-title">        <a role="button" data-toggle="collapse" data-parent="#accordion" href="#collapseOne" aria-expanded="true" aria-controls="collapseOne">         <b> 数据采集  </b>        </a>      </h4>    </div>    <div id="collapseOne" class="panel-collapse collapse in" role="tabpanel" aria-labelledby="headingOne">      <div class="panel-body">      <input type="hidden" id="message" value="${msg }">            <table align="center" width="100%" class="form-inline">               <tr height="60px;">                  <td align="right"><label >企业附件:</label></td>  <td>    <input class="form-control" style="width:230px;" type="file" id="enterFile" name="enterFile"/>                  </td>               </tr>               <tr height="60px;">                  <td align="right"><label >分机附件:</label></td>  <td>   <input class="form-control" style="width:230px;" type="file" id="deviceFile" name="deviceFile"/>                  </td>               </tr>               <tr height="60px;">                  <td align="right"><label >分机总数:</label></td>  <td>     <input name="deviceTotal" id="deviceTotal" class="form-control" style="width: 230px;height: 35px;"/>                  </td>               </tr>               <tr>                 <td style="padding-left:80px;" colspan="2">                   <button type="button" onclick="UpladFile()" class="btn mybtn" style="width: 115px;height: 30px;background-color: #404f64;color: #ffffff">提交</button>  <button type="button" onclick="clearInput()" class="btn mybtn" style="width: 115px;height: 30px;background-color: #ff634d;color: #ffffff">清空</button>                  </td>               </tr></table>      </div>    </div>  </div>  </div></body><div class="modal fade" id="alertModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" >   <div class="modal-dialog">      <div class="modal-content">         <div class="modal-header">            <h4 class="modal-title" id="myModalLabel">提示</h4>         </div>         <div class="modal-body">         <progress id="progressBar" value="0" max="100"></progress>  <span id="percentage"></span> </div>      </div></div></div></html>

后台是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>集合,每一个FileItem对应一个Form表单的输入项            List<FileItem> 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$InvalidContentTypeExceptionprocessData: false, //不加前台会报错Illegal invocationsuccess: function(data){alert(data.msg);},error: function(data) {alert("操作失败!!!");}});}


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

原创粉丝点击