SpringMVC 的文件上传

来源:互联网 发布:windows ce系统升级 编辑:程序博客网 时间:2024/04/19 05:13

springmvc 为文件上传提供了两种形式,一种是基于Commons FilesUpload,另外一种是基于Servlet 3.0对 multipart 请求解析的支持。springmv下org.springframework.web.multipart包提供了对文件上传的支持。默认情况下,spring是不提供对文件上传的支持的,开发者需要在应用上下文中加入MultipartResolver的声明才可使用。

这篇文章主要是针对Commons FilesUpload这种形式。

    测试的Demo使用Maven构建构建,需要注意的是,使用 commons filesUpload 这种形式的,需要加入commons-fileupload以及commons-io这两个依赖包。

    项目目录如下:

上传文件保存在upload/temp文件夹下,spring的配置文件放在了conf/spring 文件夹下

     项目的pom.xml如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.lee</groupId>  <artifactId>spring-mvc-demo</artifactId>  <packaging>war</packaging>  <version>0.0.1-SNAPSHOT</version>  <name>spring-mvc-demo Maven Webapp</name>  <url>http://maven.apache.org</url>    <properties>  <project.build.sourceEncoding>utf-8</project.build.sourceEncoding>  </properties>   <dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>3.2.0.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>3.2.0.RELEASE</version></dependency>    <dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.0.1</version><scope>provided</scope></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.2</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>1.3</version></dependency><dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>  </dependencies>   <build>    <finalName>spring-mvc-demo</finalName>    <plugins>    <plugin>  <groupId>org.eclipse.jetty</groupId>  <artifactId>jetty-maven-plugin</artifactId>  <version>9.2.11.v20150529</version></plugin>    <plugin>     <groupId>org.apache.maven.plugins</groupId>         <artifactId>maven-compiler-plugin</artifactId>         <version>3.3</version>     <configuration>    <source>1.7</source>    <target>1.7</target>    <encoding>utf-8</encoding>     </configuration>    </plugin>     </plugins>  </build>  </project>
注:使用jetty,所以需要加入javax.servlet-api的依赖

有关于web.xml文件配置就不再赘述了。

在dispatcher-servlet.xml,需要加入MultipartResolver,如下

  <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="3000000"/>
<property name="defaultEncoding" value="utf-8"/>
</bean>

有个问题必须注意,在上面的配置中,bean的id必须是multipartResolver,否则会在做上传的时候抛出异常。

java.lang.IllegalArgumentException: Expected MultipartHttpServletRequest: 

is a MultipartResolver configured?。

这是为什么呢?原因很简单。

打开DispatcherServlet这个类的源码,查看关于MultipartResolver初始化方法initMultipartResolver(ApplicationContext context) 的声明,源码如下


private void initMultipartResolver(ApplicationContext context) {try {this.multipartResolver = context.getBean(MULTIPART_RESOLVER_BEAN_NAME, MultipartResolver.class);if (logger.isDebugEnabled()) {logger.debug("Using MultipartResolver [" + this.multipartResolver + "]");}}catch (NoSuchBeanDefinitionException ex) {// Default is no multipart resolver.this.multipartResolver = null;if (logger.isDebugEnabled()) {logger.debug("Unable to locate MultipartResolver with name '" + MULTIPART_RESOLVER_BEAN_NAME +"': no multipart request handling provided");}}}

我们发现,DispatcherServlet在做MultipartResolver初始化时,是通过getBean(String name, Class<T> requiredType)方法来获取对应的MultiartResolver,而在做初始化时调用这个方出入的参数 name 是在DispatcherServlet定义的一个静态变量,如下

public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";

所以,在dispatcher-servlet.xml 声明MultipartResolver时,bean的id或是name 必须是multipartResolver,否者的话它就找不到对应的MultipartResolver,最终导致抛出上面的异常
到此为止,项目配置完毕。
     文件上传页面如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!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=UTF-8"><title>文件上传</title><style type="text/css">input{display:block;margin:10px;}</style></head><body><div style="border:1px solid #3300FF;width:400px;margin:20px auto;"><p>单文件上传</p><form action="/upload/singleUpload" enctype="multipart/form-data" method="post"><input type="file" name=singleFile><input type="submit" value="submit"/></form></div><div style="border:1px solid #FF0000;width:400px;margin:20px auto;"><p>多文件上传</p><form action="/upload/multiUpload" enctype="multipart/form-data" method="post"><input type="file" name="multiFiles"/><input type="file" name="multiFiles"/><input type="file" name="multiFiles"/><input type="file" name="multiFiles"/><input type="submit" value="submit"/></form></div></body></html>
需要注意的是,form的enctype 必须设置为multipart/form-data。
然后就是编写对应的Controller,代码如下,

package com.lee.springmvc.controller;import java.io.File;import java.io.IOException;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.multipart.MultipartFile;/**  *  * 文件上传controller * @author  Lee E-mail: mingl2012@126.com * @date 创建时间:2015年11月29日 上午2:21:52  * @version 1.0   */@Controllerpublic class FileController {/** * 文件上传页面跳转 */@RequestMapping(value="/upload")public String uploadForward(){return "upload";}/** *   单文件上传*  @param singleFile 上传的单个文件*  @param request */@RequestMapping(value = "/upload/singleUpload", method=RequestMethod.POST)public String singleUpload(@RequestParam("singleFile")  MultipartFile singleFile, HttpServletRequest request) throws IOException{String savePath = request.getSession().getServletContext().getRealPath("upload/temp");if(singleFile != null && !singleFile.isEmpty()){String fileName = singleFile.getOriginalFilename();//采用UUID生成随机文件名fileName = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));File targetFile = new File(savePath, fileName);if(!targetFile.exists()){targetFile.mkdir();}singleFile.transferTo(targetFile);}return "success";}/** *  多文件上传*  @param multiFiles MultipartFile 数组,对应上传的多个文件 */@RequestMapping(value = "/upload/multiUpload", method=RequestMethod.POST)public String multiUpload(@RequestParam("multiFiles")  MultipartFile[] multiFiles, HttpServletRequest request) throws IOException{String savePath = request.getSession().getServletContext().getRealPath("upload/temp");if(multiFiles != null && multiFiles.length > 0){for(MultipartFile file: multiFiles){if(file != null && !file.isEmpty()){String fileName = file.getOriginalFilename();//采用UUID生成随机文件名fileName = UUID.randomUUID().toString().replace("-", "") + fileName.substring(fileName.lastIndexOf("."));File targetFile = new File(savePath, fileName);if(!targetFile.exists()){targetFile.mkdir();}file.transferTo(targetFile);}}}return "success";}}
注:为了简便,并未做异常处理,实际项目中须有对应的异常处理。

到此为止,代码部分也书写完毕。
测试
多文件上传:
点击提交按钮,上传成功,跳转到success页面,此时,在upload/temp文件夹下就可以找到上传的图片了


到此为止,关于springmvc的文件上传就完毕了。有不足的地方请多指教。


0 0
原创粉丝点击