java文件上传总结
2017-09-05 14:06
441 查看
最近公司项目用到文件上传,总结一下
第一种 传统表单上传比较简单,网上也有好多文章介绍,推荐一篇:表单方式文件上传和下载
再此只提醒两点:
一,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
后台是Java
第三种 用Ajax和FormData
第四种 用jquery.form.js里的ajaxForm(我没成功,有兴趣的可以用用)
第一种 传统表单上传比较简单,网上也有好多文章介绍,推荐一篇:表单方式文件上传和下载
再此只提醒两点:
一,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$InvalidContentTypeException processData: false, //不加前台会报错Illegal invocation success: function(data){ alert(data.msg); }, error: function(data) { alert("操作失败!!!"); } }); }
第四种 用jquery.form.js里的ajaxForm(我没成功,有兴趣的可以用用)
相关文章推荐
- javaweb之文件上传总结
- java上传下载文件的总结
- 利用Spring MVC 上传图片文件 博客分类: Java总结文档
- 【总结】java 后台文件上传整理
- 文件上传(java后台)的小知识总结
- JavaWeb开发知识总结(七)-(struts2_文件上传_Ajax)
- JAVA文件上传总结
- JavaWeb开发知识总结(annotation,Servlet3.0,文件上传,动态代理)
- Java 上传文件总结
- Java网络编程实践和总结 --- 基于TCP的Socket编程之实现文件上传和下载服务
- WebUploader插件上传大文件单文件和多文件JAVA版使用总结
- 关于使用FTP上传文件到服务器的小总结-java
- 学习总结之JavaWeb实现文件上传
- JavaWeb文件上传与文件下载归纳总结
- JAVA 文件上传总结
- FCKeditor在java下的文件上传运用
- 自己编写JAVA环境下的文件上传组件
- java web 上传保存xml文件
- 用java做c/s架构的文件上传功能
- ASP.NET中文件上传下载方法总结