Spring mvc的文件上传是通过commons-fileupload来完成的,首先我们需要添加jar包,我的是maven项目添加依赖:
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3</version> </dependency>
spring mvc默认的解析器没有加入对文件上传的解析,我们要在mvc的配置文件中添加MultipartResolver的申明,因为CommonsMultipartResolver实现了MultipartResolver接口,所以我们可以这样配置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="defaultEncoding" value="utf-8" /> <property name="maxUploadSize" value="10485760000" /> <property name="maxInMemorySize" value="40960" /> </bean>
注意这里我们允许上传文件的最大大小由spring来控制,需要注意这里指定的不是单个文件大小,而是所有文件的总和。当超出上传文件限制时,在进controller之前,会直接抛出org.springframework.web.multipart.MaxUploadSizeExceededException异常,可以配置一个异常拦截器来专门处理这个异常:
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"> <property name="exceptionMappings"> <props> <!-- 遇到MaxUploadSizeExceededException异常时,自动跳转到/WEB-INF/jsp/error_fileupload.jsp页面 --> <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">error_fileupload</prop> </props> </property> </bean>
在页面上添加文件上传的form表单,别忘了form的enctype="multipart/form-data"> :
<form action="user/fileUpload" method="post" enctype="multipart/form-data"> <input type="file" name="files" /> <input type="submit" value="上传" /> </form>
controller中接收文件,如果只是上传一个文件,只需要声明MultipartFile类型即可,而且无需显式指定@RequestParam注解,如果上传的是多个文件,那么这里就要用MultipartFile[]数组来接收文件,并且还要指定@RequestParam注解,不然会抛出java.lang.NoSuchMethodException: [Lorg.springframework.web.multipart.MultipartFile;.<init>()异常。上传多个文件时,前台表单中的所有<input type="file" name=”files”/>的name都应该是files,否则参数里的files无法获取到所有上传的文件,这里只列出示范代码,具体的判空及文件处理等操作略:
@RequestMapping(value="/fileUpload", method=RequestMethod.POST) public String addUser(User user, @RequestParam MultipartFile[] files, HttpServletRequest request) throws IOException{ for(MultipartFile myfile : files){ System.out.println("文件长度: " + myfile.getSize()); System.out.println("文件类型: " + myfile.getContentType()); System.out.println("文件名称: " + myfile.getName()); System.out.println("文件原名: " + myfile.getOriginalFilename()); System.out.println("========================================"); //可以使用FileUtils来保存文件,这里不再列出代码 //FileUtils.copyInputStreamToFile()方法会自动关闭IO流 //FileUtils.copyInputStreamToFile(myfile.getInputStream(), new File(realPath, myfile.getOriginalFilename())); } } return "success"; }
还有一种方式,处理起来可能相对麻烦一些:
@RequestMapping(value = "fileUpload2", method = RequestMethod.POST) public String fileUpload2(HttpServletRequest request) throws IllegalStateException, IOException { // 设置上下方文 CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver( request.getSession().getServletContext()); // 检查form是否有enctype="multipart/form-data" if (multipartResolver.isMultipart(request)) { MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request; Iterator<String> iter = multiRequest.getFileNames(); while (iter.hasNext()) { // 由CommonsMultipartFile继承而来,拥有上面的方法. MultipartFile file = multiRequest.getFile(iter.next()); if (file != null) { String path = "D:/" + file.getOriginalFilename(); File localFile = new File(path); file.transferTo(localFile); } } } return "success"; }