MultipartResolver和AbstractAnnotationConfigDispatcherServletInitializer
问题内容:
我在将CommonsMultipartResolver
bean与Extendeds结合使用时遇到麻烦AbstractAnnotationConfigDispatcherServletInitializer
。
我已经在先前的项目中成功使用CommonsMultipartResolver,但是初始化器实现了WebApplicationInitializer
。
凭直觉,我是在Initializing扩展中完成的AbstractAnnotationConfigDispatcherServletInitializer
。
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{
MultipartUploadConfig.class
};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{
WebMvcConfig.class
};
}
我认为这将与WebApplicationInitializer
(这是工作配置)中的代码具有相同的效果。
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
dispatcherServlet.register(WebMvcConfig.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(MultipartUploadConfig.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
}
使用AbstractAnnotationConfigDispatcherServletInitializer
,出现以下错误:
Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided
因此,任何人都知道如何使multipartResolver
bean与之配合使用AbstractAnnotationConfigDispatcherServletInitializer
?
其他相关信息:
WebMvcConfig.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = ...)
public class WebMvcConfig extends WebMvcConfigurerAdapter {
...
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
MultipartUploadConfig.java
@Configuration
public class MultipartUploadConfig {
@Bean
public CommonsMultipartResolver multipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(8192);
multipartResolver.setDefaultEncoding("utf-8");
return multipartResolver;
}
}
堆栈跟踪:
[http-nio-8080-exec-4] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [] threw exception
org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:100)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.<init>(StandardMultipartHttpServletRequest.java:78)
at org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:76)
at org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:108)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided
at org.apache.catalina.connector.Request.parseParts(Request.java:2669)
at org.apache.catalina.connector.Request.getParts(Request.java:2636)
at org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1083)
at org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:85)
... 23 more
问题答案:
得到它了。该AbstractAnnotationConfigDispatcherServletInitializer
和WebApplicationInitializer
版本确实做到相互对应。没问题。问题在于,在使用的项目中AbstractAnnotationConfigDispatcherServletInitializer
,还存在Spring
Security,这使事情搞砸了。
使用Spring Security时,多部分解析器的Bean名称应为@Bean(name = "filterMultipartResolver")
。当然,这意味着MultipartFilter
应该这样设置AbstractSecurityWebApplicationInitializer
。
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
}