springMVC:为MultipartFilte配置了上传文件解析器,报错或不能使用
2020-12-13 02:19
标签:现在 自己 应该 请求 转化 解决 文件上传 并且 utils 一、问题描述 二、报错:Unable to process parts as no multi-part configuration has been provided web.xml springmvc.xml DispatcherServlert的上下文文件 另外,还有一个multipartResolver需要介绍: CommonsMultipartResolver:使用commons Fileupload来处理multipart请求,使用时需导入jar包。 原因: 三、解决问题 至此、报错的问题已经解决。但是为什么我们配置的上传文件的解析器没有用到呢?说来话长,我们源码中见。 2,解决未使用我们自己配置的上传文件的解析器(CommonsMultipartResolver) 有点抽象,说的再多不如去做下。在前端页面发送了一个带文件上传控件的表单,看MutilFilter是否使用我配置的文件上传的解析器(CommonsMultipartResolver)。 wac.containsBean(beanName) beanName=”multipartResolver” 为false。说明你在spring的上下文中没有配置id=”multipartResolver”。奇怪了,我明明在springmvc.xml中配置了id=”multipartResolver”.为什么在spring对应的上下文对象中找不到呢?这里就要牵扯到新的概念了。 springmvc.xml是由DispatcherServlet加载的,然后生成了springmvc的上下文对象,称为子容器。 ContextLoaderListener加载的配置文件,生成的spring的上下文对象,称为父容器。 子容器可以使用父容器中定义的bean,反之则不行。 如上multipartResovler配置在springmvc.xnl中,即对应的bean在子容器中,而WebApplicationContext.containsBean()在父容器中是查找不到这个bean的 spring和spirngmvc父子容器介绍 Spring lets you define multiple contexts in a parent-child hierarchy. The applicationContext.xml defines the beans for the “root webapp context”, i.e. the context associated with the webapp. The spring-servlet.xml (or whatever else you call it) defines the beans for one servlet’s app context. There can be many of these in a webapp, one per Spring servlet (e.g. spring1-servlet.xml for servlet spring1, spring2-servlet.xml for servlet spring2). Beans in spring-servlet.xml can reference beans in applicationContext.xml, but not vice versa. All Spring MVC controllers must go in the spring-servlet.xml context. In most simple cases, the applicationContext.xml context is unnecessary. It is generally used to contain beans that are shared between all servlets in a webapp. If you only have one servlet, then there’s not really much point, unless you have a specific use for it. 本文转自:https://blog.csdn.net/gao_zhennan/article/details/81331218 springMVC:为MultipartFilte配置了上传文件解析器,报错或不能使用 标签:现在 自己 应该 请求 转化 解决 文件上传 并且 utils 原文地址:https://www.cnblogs.com/nizuimeiabc1/p/11031381.html
为支持restful风格请求,并且应对可能上传文件的情况,需要在配置hiddenHttpMethodFilter过滤器之前配置MultipartFilter。目的是让MultipartFilter过滤器先将带文件上传的请求,进行解析。以便hiddenHttpMethodFilter可以取到”_method”参数,转化为相应的http动作。
既然multipartFilter要进行上传文件的解析,那么必然需要MutipartResolver,那么问题发生了!
配置如下filter>
filter-name>MultipartFilterfilter-name>
filter-class>org.springframework.web.multipart.support.MultipartFilterfilter-class>
init-param>
param-name>multipartResolverBeanNameparam-name>
param-value>multipartResolverparam-value>
init-param>
filter>
我们使用了commons-fileupload-1.3.1.jar提供的CommonsMultipartResolver解析器bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
property name="maxUploadSize" value="20000000"/>
property name="defaultEncoding" value="utf-8">property>
bean>
org.springframework.web.multipart.support.StandardServletMultipartResolver
StandardServletMultipartResolver:是基于Servlet3.0来处理multipart请求的,所以不需要引用其他jar包,但是必须使用支持Servlet3.0的容器才可以.
如果你配置的multipartFilter的multipartResolver是CommonsMultipartResolver,即如上面springmvc.xml,
web.xml的配置,报这个错误的话,说明你配置的上传文件的解析器(CommonsMultipartResolver)根本,没有用到,而是使用这个上传文件的解析器(StandardServletMultipartResolver),而你又没有对这个解析器提供必要的配置信息,所以报错。
1、解决报错
给StandardServletMultipartResolver提供配置信息即可,(注:为何这样配置,原因见https://blog.csdn.net/gao_zhennan/article/details/81327268)
web.xmlservlet>
servlet-name>springmvcservlet-name>
servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
init-param>
param-name>contextConfigLocationparam-name>
param-value>classpath:spring/applicationContext-web.xmlparam-value>
init-param>
load-on-startup>1load-on-startup>
multipart-config>
max-file-size>20848820max-file-size>
max-request-size>418018841max-request-size>
file-size-threshold>1048576file-size-threshold>
multipart-config>
servlet>
MultipartFilter关键源码public class MultipartFilter extends OncePerRequestFilter {
public static final String DEFAULT_MULTIPART_RESOLVER_BEAN_NAME = "filterMultipartResolver";
private String multipartResolverBeanName = DEFAULT_MULTIPART_RESOLVER_BEAN_NAME;
private final MultipartResolver defaultMultipartResolver = new
StandardServletMultipartResolver();
//将web.xml文件中为multipartFilter设置的参数(init-param)的属性值(param-value),
//通过调用set方法设置进来,此时multipartResolverBeanName=multipartResolver
public void setMultipartResolverBeanName(String multipartResolverBeanName) {
this.multipartResolverBeanName = multipartResolverBeanName;
}
protected String getMultipartResolverBeanName() {
return this.multipartResolverBeanName;
}
protected MultipartResolver lookupMultipartResolver() {//关键方法:用来查找上传文件的解析器
WebApplicationContext wac = WebApplicationContextUtils.
getWebApplicationContext(getServletContext());
// 1.WebApplicationContext 是spring的上下文对象,在ContextLoaderListener加载spring的配置文件后,将生成的对应的WebApplicationContext,先放在了web.xml的上下文对象中ServletContext
String beanName = getMultipartResolverBeanName();
// 2.上面有这个方法,返回值为this.multipartResolverBeanName,即"multipartResolver"
if (wac != null && wac.containsBean(beanName)) {
// 3.1只要监听器ContextLoaderListener,加载了spirng的配置文件wac 就不会是null,
// 现在关键的是:ContextLoaderListener加载的配置文件中是否配置了这个bean(id="multipartResolver")
return wac.getBean(beanName, MultipartResolver.class);
}
else {
//3.2如过ContextLoaderListener加载的配置文件中没有这个bean,则与之
//对应的WebApplicationContext对象中也不包含这个bean,
//于是wac.containsBean(beanName) 为false。
//返回默认的解析器"StandardServletMultipartResolver"
return this.defaultMultipartResolver;
}
}
问题解决
1.新建一个applicationContext.xml(名字任意取),
2.将multipartResovler配置在其中。
3.重要的是要通过ContextLoaderListener来加载此文件,这样这个bean就在spring的容器里了,然后WebApplicationContext.containsBean()为true,就会使用你配置的解析器,而不是使用默认的了。
最后放张图
(转发自https://blog.csdn.net/jml1437710575/article/details/52020936)
在百度中别人的帖子中看到一段应该是官方的原文解释,我摘抄过来并粗糙的直译一下:
spring允许你定义多个上下文在父子继承关系中
applicationContext.xml文件是为了”根webapp应用上下文”定义bean, 也就是说它的上下文是和webapp想关联的
spring-servlet.xml文件(或是其他的你习惯的称呼)是为了一个servlet应用上下文呢定义bean. 在一个webapp中可以有多个此配置文件,
每一个spring的servlelt(例如: 名为spring1的servlet拥有配置文件spring1-servlet.xml, 名为spring2的servlet拥有配置文件spring2-servlet.xml).
在spring-servlet.xml中定义的bean可以直接引用在applicationContext.xml中定义的bean, 但是反过来不可以.
所有springmvc的Controller必须在spring-servlet.xml对应的上下文中运行.
在大多数简单的情况下, applicationContext.xml对应的上下文并不必须. 它通常用来包含那些bean用来在webapp中所有servlet之间共享.
如果你只有一个servlet, 那么实际没有什么必要定义applicationContext.xml, 除非你有特别应用.
文章标题:springMVC:为MultipartFilte配置了上传文件解析器,报错或不能使用
文章链接:http://soscw.com/essay/25341.html