文件上传的要素:
- 前端html的form表单要定义属性
enctype="multipart/form-data"
- 后台解析mutipart请求(这一步骤通常是使用工具)
对于SpringMVC默认配置MultipartResolver,也就是无法处理文件上传。
因此我们的解决方案当然就是配置MultipartResolver,Spring 为我们提供了两种Resolver实现: - StandardServletMultipartResolver
- CommonsMultipartResolver
优选方案当然是StandardServletMultipartResolver,但是这个Resolver必须满足如下条件: - Servlet3.0+
- Spring 3.1
所以才会有了CommonsMultipartResolver的替代方案。
接下来就看看如何在SpringMVC中进行文件上传操作
前端html
<%@ 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>学习SpringMVC</title>
</head>
<body>
<form action="${pageContext.request.contextPath }/file/upload.action" enctype="multipart/form-data" method="post">
<label for="fileID">文件上传:</label>
<input id="fileID" type="file" name ="uploadFile"/><br/>
<input type="submit" value="确定"/>
</form>
</body>
</html>
StandardServletMultipartResolver
当然最简单的方式还是进行XML方式的配置喽
但是请注意:你会发现这个StandardServletMultipartResolver似乎并不能配置一些参数,那么我们怎么设置参数呢?如文件上传的地址、最大上传文件大小… …。我们可以在我们配置的DispatcherServlet中进行配置<multipart-config>
,这里面必须配置location参数,StandardServletMultipartResolver才能正常使用。
我这里贴出JavaConfig+web.xml版
JavaConfig配置StandardServletMultipartResolver
web.xml配置参数
WebApplicationJavaConfig .java
@Bean
public MultipartResolver multipartResolver(){
StandardServletMultipartResolver multipartResolver = new StandardServletMultipartResolver();
return multipartResolver;
web.xml
<!-- Spring MVC DispatcherServlet -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 类似于ContextLoaderListener的参数配置 -->
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.xbz.mvc.initializer.WebApplicationJavaConfig</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<!-- multipartResolver配置参数 -->
<multipart-config>
<location>C:\Users\Administrator\Desktop\upload_tmp</location>
</multipart-config>
</servlet>
文件上传的准备工作完成了,那么后台又要如何接收呢??
首先我们来了解两个接口:
- Part
- MultipartFile
我们只要将文件对应域声明为上述类型参数变量,就能够在后台得到文件的各种操作了。
但是由于本人技术太菜,目前认为Part不能直接得到文件原始名称。
FileUploadController.java
展示了两种不同接收方式
@Controller
@RequestMapping("file")
public class FileUploadController {
@RequestMapping("upload")
public String uploadFile(@RequestPart(required=false,name="uploadFile")Part file,HttpSession session){
return "success";
}
@RequestMapping("upload_1")
public String uploadFile_1(@RequestPart(required=false,name="uploadFile")MultipartFile file,HttpSession session){
return "success";
}
}
虽然上面提到了StandardServletMultipartResolver不能在new的时候设置参数,但是可以在web.xml中设置。同样的,在使用JavaConfig时也是可以的。
MyApplicationInitializer.java
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* 该类会在serlvet3.0环境中自动查找实现了 javax.servlet.ServletContainerInitializer接口的类来完成初始化(应该类似于替代web.xml)
* 然而我们的这个类与ServletContainerInitializer没有一毛钱关系
* 但是Spring的SpringServletContainerInitializer实现了这个接口
* 在SpringServletContainerInitializer中会查找实现类了WebApplicationInitializer接口的类并将配置任务交给他们完成
* 当然我们的MyApplicationInitializer也就是间接实现了这个接口
*
* @author xubaozhong
* 而且在继承这个抽象类时,必须实现如下的三个方法
*
*/
public class MyApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer{
/**
* 重点配置方法
* 设置multipart参数
*/
@Override
protected void customizeRegistration(Dynamic registration) {
registration.setMultipartConfig(new MultipartConfigElement("C:/Users/Administrator/Desktop/upload_tmp"));
}
/**
* 类似于web.xml中配置ContextLoaderListener的contextConfigLocation
* 只是这个返回的是一个JavaConfig的数组Class
*/
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
return new Class<?>[]{RootApplicationJavaConfig.class};
}
/**
* 类似于web.xml中配置DispatcherServlet的contextConfigLocation
* 只是这个返回的是一个JavaConfig的数组Class
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebApplicationJavaConfig.class};
}
/**
* 等同于<mapping-url/>
*/
@Override
protected String[] getServletMappings() {
return new String[]{"*.action"};
}
}
到此,StandardServletMultipartResolver的使用结束。
如果的Spring是3.1以下或者我的服务器不支持Servlet3.0呢?
所以还有CommonsMultipartResolver作为替代方案。
替代方案我们可以配置参数了哟!!!
由于已经详细介绍StandardServletMultipartResolver的使用,而CommonsMultipartResolver类似,所以这里只贴出配置方式,请自行补脑。
JavaConfig类
似乎CommonsMultipartResolver很好用啊!!!
@Bean
public MultipartResolver multipartResolver() throws IOException{
CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
commonsMultipartResolver.setUploadTempDir(new FileSystemResource(new File("C:/Users/Administrator/Desktop/upload_tmp")));
return commonsMultipartResolver;
}
注意:使用CommonsMultipartResolver 需要引用commons-fileupload相关jar
maven如下
<dependencies>
<!-- 文件上传不使用Spring 提供的StandardServletMultipartResolver时 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
</dependencies>