一、fileupload
这种方式也是目前网上主要绝大部分 Ajax 文件上传的方法,前台代码如下:
1 2 3 <input type ="file" id ="uploadFile" > <button onclick ="uploadFile()" > 上传文件</button >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <script> var fileSize; var fileName; $("#uploadFile" ).change(function ( ) { var file = this .files[0 ]; fileName = file.name; fileSize = file.size; }); function uploadFile ( ) { var formData = new FormData(); var file = document .getElementById("uploadFile" ).files[0 ]; formData.append("file" ,file); formData.append("fileName" ,fileName); formData.append("fileSize" ,fileSize); sendFile("/uploadFile" ,formData,true ,function (res ) { },function (XMLHttpRequest, textStatus, errorThrown ) { }); } function sendFile (_url, _data, _async, _successCallback, _errorCallback ) { $.ajax({ type : "post" , async : _async, url : _url, dataType : 'json' , processData : false , contentType : false , data : _data, success : function (msg ) { _successCallback(msg); }, error : function (error ) { _errorCallback(error); } }); </script>
在后台,首先导入 commons-fileupload
包,我还用到了 connons-io
包,一并导入。
1 2 3 4 5 6 7 8 9 10 <dependency > <groupId > commons-fileupload</groupId > <artifactId > commons-fileupload</artifactId > <version > 1.3.1</version > </dependency > <dependency > <groupId > commons-io</groupId > <artifactId > commons-io</artifactId > <version > 2.5</version > </dependency >
在 controller 层编写接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 package jit.wxs.web;import org.apache.commons.io.FileUtils;import org.apache.commons.fileupload.FileItem;import org.apache.commons.fileupload.disk.DiskFileItemFactory;import org.apache.commons.fileupload.servlet.ServletFileUpload;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletRequest;import java.io.File;import java.util.List;@Controller public class FileController { @PostMapping("/uploadFile") public String uploadFile (HttpServletRequest request) throws Exception { int sizeThreshold = 1024 * 1024 ; File repository = new File("/temp" ); DiskFileItemFactory factory = new DiskFileItemFactory(sizeThreshold, repository); ServletFileUpload upload = new ServletFileUpload(factory); upload.setHeaderEncoding("UTF-8" ); if (ServletFileUpload.isMultipartContent(request)) { List<FileItem> list = upload.parseRequest(request); if (list != null ) { for (FileItem item : list) { if (item.isFormField()) { String fieldName = item.getFieldName(); String fieldValue = item.getString("UTF-8" ); System.out.println("FormField:k=" + fieldName + ",v=" + fieldValue); } else { String fileName = item.getName(); String path = "/" + fileName; FileUtils.uploadFile(item,path); } } } } return "返回给前台的消息" ; } } public static void uploadFile (FileItem item, String targetFilePath) throws IOException { InputStream in = item.getInputStream(); OutputStream out = new FileOutputStream(targetFilePath); IOUtils.copy(in, out); in.close(); out.close(); item.delete(); }
当我项目环境是 Spring MVC
时这样用没有问题,当我更换为 Spring Boot
后在 List<FileItem> list = upload.parseRequest(request);
这个地方的值始终为 null。最后我参考 http://blog.csdn.net/u013248535/article/details/55823364 这篇文章找到了解决方法。
二、StandardMultipartHttpServletRequest
直接将 HttpServletRequest 强转为 StandardMultipartHttpServletRequest
,然后通过 getFileNames()
方法进行迭代,用这种方法不用使用 common-fileupload
包了,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 package jit.wxs.web;import org.apache.commons.io.FileUtils;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;import javax.servlet.http.HttpServletRequest;import java.io.File;import java.util.Iterator;@RestController public class FileController { @PostMapping("/uploadFile") public String uploadFile (HttpServletRequest request) throws Exception { StandardMultipartHttpServletRequest req = (StandardMultipartHttpServletRequest) request; Enumeration<String> names = req.getParameterNames(); while (names.hasMoreElements()) { String key = names.nextElement(); String val = req.getParameter(key); System.out.println("FormField:k=" + key + "v=" + val); } Iterator<String> iterator = req.getFileNames(); while (iterator.hasNext()) { MultipartFile file = req.getFile(iterator.next()); String fileNames = file.getOriginalFilename(); fileNames = new String(fileNames.getBytes("UTF-8" )); byte [] content = file.getBytes(); FileUtils.writeByteArrayToFile(new File(fileNames), content); } return "返回给前台的消息" ; } }
这样就能够实现文件上传,如果出现大小超出限制的错误,记得在 springboot
的配置文件中配置下:
1 2 3 4 spring.servlet.multipart.max-file-size =10 MBspring.servlet.multipart.max-request-size =100 MB
三、文件上传控件
在条件允许的情况下,可以使用一些第三方的文件上传控件。推荐下我使用过的控件:
BootstrapFileInput
WebUploader
Ajax 实现文件上传(解决upload.parseRequest为空问题)