Servlet 3.0 的 MultipartResolver 的 Spring 4 Java 配置

Posted

技术标签:

【中文标题】Servlet 3.0 的 MultipartResolver 的 Spring 4 Java 配置【英文标题】:Spring 4 Java Config for MultipartResolver for Servlet 3.0 【发布时间】:2014-06-27 12:17:59 【问题描述】:

我对 Spring MVC 配置采用全 Java 方法,但无法弄清楚如何以编程方式将 MultipartConfigElement 与我的 DispatcherServlet 关联。

Spring 文档说明:

为了使用基于 Servlet 3.0 的多部分解析,您需要标记 在 web.xml 中带有“multipart-config”部分的 DispatcherServlet,或者 在编程 Servlet 中使用 javax.servlet.MultipartConfigElement 注册...

http://docs.spring.io/spring/docs/4.0.4.RELEASE/spring-framework-reference/htmlsingle/#mvc-multipart

这是我的WebApplicationInitializer 代码:

public class DispatcherServletInitializer implements WebApplicationInitializer 

    private static final Logger logger = LoggerFactory.getLogger(DispatcherServletInitializer.class);

    @Override
    public void onStartup(ServletContext container) 

        // Create the 'root' Spring application context
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(AppConfig.class);

        // Manage the lifecycle of the root application context
        container.addListener(new ContextLoaderListener(rootContext));

        // Create the dispatcher servlet's Spring application context
        AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext();
        dispatcherContext.register(WebConfig.class);

        //HOW CAN I ASSOCIATE THIS CONFIG WITH MY DISPATCHER SERVLET?
        MultipartConfigElement config = new MultipartConfigElement("C:\\Temp", 20848820, 418018841, 1048576);
        DispatcherServlet dispatcherServlet = new DispatcherServlet(dispatcherContext);

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher = 
            container.addServlet("dispatcher", dispatcherServlet);
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/*");
    


如何将MultipartConfigElement 与我的DispatcherServlet 关联?我没有看到任何像 setMultipartConfiguration 这样的方法或任何接受它的构造函数。

另请注意,我的 WebConfig 声明了 MultipartResolver

@Bean
public StandardServletMultipartResolver multipartResolver()
    return new StandardServletMultipartResolver();

但 Spring 文档指出:

Configuration settings such as maximum sizes or storage locations need to be applied at that Servlet registration level as Servlet 3.0 does not allow for those settings to be done from the MultipartResolver.

任何指导将不胜感激。

【问题讨论】:

【参考方案1】:

这是与AbstractAnnotationConfigDispatcherServletInitializer 配置servlet 方式兼容的解决方案。这比WebApplicationInitializer 的侵入性要小一些。

它使用 AbstractAnnotationConfigDispatcherServletInitializer.customizeRegistration 的覆盖。

public class MySpringWebSetup extends AbstractAnnotationConfigDispatcherServletInitializer

  // Your usual obligatory configuration overrides:
  @Override protected Class<?>[] getRootConfigClasses()  ... 
  @Override protected Class<?>[] getServletConfigClasses()  ... 
  @Override protected String[] getServletMappings()  ... 

  // Optional configuration:
  @Override
  protected void customizeRegistration(Dynamic registration) 
    registration.setMultipartConfig(
      // Maybe use more sophisticated configuration than this:
      new MultipartConfigElement("")
    );
  

我发现它捕获了getServletMappings 的堆栈跟踪,从而进入了org\springframework\web\servlet\support\AbstractDispatcherServletInitializer.java 的代码:

protected void registerDispatcherServlet(ServletContext servletContext) 

    [more registration stuff was here]

    registration.setLoadOnStartup(1);
    registration.addMapping(getServletMappings());
    registration.setAsyncSupported(isAsyncSupported());

    Filter[] filters = getServletFilters();
    if (!ObjectUtils.isEmpty(filters)) 
        for (Filter filter : filters) 
            registerServletFilter(servletContext, filter);
        
    


    customizeRegistration(registration);

【讨论】:

【参考方案2】:

看起来你需要这个:

ServletRegistration.Dynamic dispatcher = 
            container.addServlet("dispatcher", dispatcherServlet);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");

dispatcher.setMultipartConfig(new MultipartConfigElement("/tmp", 1024*1024*5, 1024*1024*5*5, 1024*1024));

【讨论】:

成功了!谢谢阿尔乔姆!

以上是关于Servlet 3.0 的 MultipartResolver 的 Spring 4 Java 配置的主要内容,如果未能解决你的问题,请参考以下文章

Servlet 3.0 新特性详解

Java 之 Servlet 3.0

Servlet 3.0 异步处理详解

Servlet 3.0 规范注解规范

Servlet 3.0 特性

Servlet 3.0版本初次使用小结