一、如果使用Servlet3.0对multipart进行支持配置,则需要使用 DispatcherServlet 的 registration 来启用multpart 请求。可以在 自己实现的 AbstractAnnotationConfigDispatcherServletInitializer 类中重载 customizeRegistration 方法。AbstractAnnotationConfigDispatcherServletInitializer 将 DispatcherServlet 注册到 Servlet 容器中就会调用 customizeRegistration 方法。
/* 通过这个ServletRegistration.Dynamic 可以设置很多 如
* 1.调用 setLoadOnStartup()设置 load-on-startup 优先级
* (load-on-startup元素标记容器是否在启动的时候就加载这个 servlet(实例化并调用其init()方法),它的值必须是一个整数,表示servlet应该被载入的顺序,
* 当值为0或者大于0时,表示容器在应用启动时就加载并初始化这个servlet,当值小于0或者没有指定时,则表示容器在该servlet被选择时才会去加载,正数的值越小,该servlet的优先级越高,
* 应用启动时就越先加载当值相同时,容器就会自己选择顺序来加载)
*
* 2.调用 setInitParameter 设置初始化参数
*
* 3.调用 setMultipartConfig 配置对 multipart 的支持
*/
@Override
protected void customizeRegistration(Dynamic registration) {
//设置对 multipart 的支持,临时存储目录为 E:\\javaUploads
registration.setMultipartConfig(new MultipartConfigElement("E:\\javaUploads"));
//限制文件大小不超过2MB,整个请求不超过4MB
//registration.setMultipartConfig(new MultipartConfigElement("E:\\javaUploads", 2097152, 4194304, 0));
}
添加其他的 Servlet 和 Filter
如果想往Web 容器中注册其他组件,可以创建一个新的初始化器。最简单的方式就是实现spring 的 WebApplicationInitializer 接口。
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import filter.MyFilter;
import servlet.MyServlet;
public class MyServletInitializer implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
System.out.println("----注册myServlet-----");
//注册一个 Servlet
Dynamic myServlet = servletContext.addServlet("myServlet", MyServlet.class);
//映射到 /testServlet/** 路径上
myServlet.addMapping("/testServlet");
//注册Filter
javax.servlet.FilterRegistration.Dynamic filter = servletContext.addFilter("myFilter", MyFilter.class);
filter.addMappingForUrlPatterns(null, false, "/testServlet");
}
}
如果要注册Filter并将其映射到DispatcherServlet 上,只需要重载 AbstractAnnotationConfigDispatcherServletInitializer 的 getServletFilters 方法即可。
//注册 Filter,该 Filter 只会映射到 DispatcherServlet
@Override
protected Filter[] getServletFilters() {
return new Filter[] {new DispatcherServletFilter()};
}
二、在web.xml中声明 DispatcherServlet
<!-- ContextLoaderListener 和 DispatcherServlet 各自都会加载一个Spring 应用上下文 -->
<!-- contextConfigLocation 该上下文参数指定了 ContextLoaderListener 从路径为/WEB-INF/spring/root-context.xml 文件中加载bean定义 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml</param-value><!-- 设置根上下文配置文件位置 -->
</context-param>
<!-- 注册 ContextLoaderListener -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 注册 DispatcherServlet -->
<!-- DispatcherServlet 默认会根据 Servlet 名字找到一个文件来加载应用上下文。如在此处它会加载 /WEB-INF/dispatcherServlet-context.xml 这个文件,也可以指定一个路径来加载,如下-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 将 DispatcherServlet 映射到 "/" -->
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
三、配置 multipart 解析器
DispatcherServlet 没有实现解析 multipart 请求数据的功能。它将该任务委托给了Spring 中的 MultipartResolver 接口的实现。spring 中内置了两个实现供我们选择。CommonMultipartResolver 和 standeadServletMultipartResolver。
其中 standeadServletMultipartResolver 是以来与 Servlet3.0 中对 multipart 请求的支持,所以我们优先使用 standeadServletMultipartResolver
将 standeadServletMultipartResolver 声明为 bean。
//multipart 解析器
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
@Override
protected void customizeRegistration(Dynamic registration) {
//设置对 multipart 的支持,临时存储目录为 E:\\javaUploads
registration.setMultipartConfig(new MultipartConfigElement("E:\\javaUploads"));
//限制文件大小不超过2MB,整个请求不超过4MB
//registration.setMultipartConfig(new MultipartConfigElement("E:\\javaUploads", 2097152, 4194304, 0));
}
四、处理 multipart 请求
方式一
//接收文件方式1 传入一个 byte 数组,数组中包含了请求中对应 part 数据(通过@RequestPart指定),该方式会将 file 部分参数变为必传项
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String processUploadFile(@RequestPart("file") byte[] file, String userName, String password) {
System.out.println(userName);
System.out.println(password);
if (file.length > 0) {
System.out.println("]]]]]]]]]]]]]]]]");
}
return "uploadFile";
}
方式二
//接收文件方式2 接收 MultipartFile
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String processUploadFile(HttpServletRequest req, HttpServletResponse response,
@RequestParam(value="file", required=true) MultipartFile file) throws IllegalStateException, IOException {
System.out.println(req.getParameter("userName"));
if (file.isEmpty()) {
System.out.println("---kong----");
} else {
System.out.println("-----not null----");
file.transferTo(new File("E:/javaUploads/" + file.getOriginalFilename()));
}
return "uploadFile";
}
方式三
//接收文件方式3 以 part 形式接收上传的文件
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String processUploadFile(HttpServletRequest req, HttpServletResponse response,
@RequestPart("file") Part file) throws IllegalStateException, IOException {
System.out.println(req.getParameter("userName"));
if (file == null) {
System.out.println("---kong----");
} else {
System.out.println("-----not null----");
file.write("E:/javaUploads/" + file.getName());
}
return "uploadFile";
}