springMVC:为MultipartFilte配置了上传文件解析器,报错或不能使用
一、问题描述
为支持restful风格请求,并且应对可能上传文件的情况,需要在配置hiddenHttpMethodFilter过滤器之前配置MultipartFilter。目的是让MultipartFilter过滤器先将带文件上传的请求,进行解析。以便hiddenHttpMethodFilter可以取到”_method”参数,转化为相应的http动作。
既然multipartFilter要进行上传文件的解析,那么必然需要MutipartResolver,那么问题发生了!
二、报错:Unable to process parts as no multi-part configuration has been provided
配置如下
web.xml
<filter>
<filter-name>MultipartFilter</filter-name>
<filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
<init-param>
<param-name>multipartResolverBeanName</param-name>
<param-value>multipartResolver</param-value>
</init-param>
</filter>
springmvc.xml DispatcherServlert的上下文文件
我们使用了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>
另外,还有一个multipartResolver需要介绍:
org.springframework.web.multipart.support.StandardServletMultipartResolver
CommonsMultipartResolver:使用commons Fileupload来处理multipart请求,使用时需导入jar包。
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.xml
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-web.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup> <!-- StandardServletMultipartResolvershu属性配置 -->
<multipart-config>
<max-file-size>20848820</max-file-size>
<max-request-size>418018841</max-request-size>
<file-size-threshold>1048576</file-size-threshold>
</multipart-config>
</servlet>
至此、报错的问题已经解决。但是为什么我们配置的上传文件的解析器没有用到呢?说来话长,我们源码中见。
2,解决未使用我们自己配置的上传文件的解析器(CommonsMultipartResolver)
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;
}
}
有点抽象,说的再多不如去做下。在前端页面发送了一个带文件上传控件的表单,看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的
问题解决
1.新建一个applicationContext.xml(名字任意取),
2.将multipartResovler配置在其中。
3.重要的是要通过ContextLoaderListener来加载此文件,这样这个bean就在spring的容器里了,然后WebApplicationContext.containsBean()为true,就会使用你配置的解析器,而不是使用默认的了。
最后放张图

spring和spirngmvc父子容器介绍
(转发自https://blog.csdn.net/jml1437710575/article/details/52020936)
在百度中别人的帖子中看到一段应该是官方的原文解释,我摘抄过来并粗糙的直译一下:
Spring lets you define multiple contexts in a parent-child hierarchy.
spring允许你定义多个上下文在父子继承关系中
The applicationContext.xml defines the beans for the “root webapp context”, i.e. the context associated with the webapp.
applicationContext.xml文件是为了”根webapp应用上下文”定义bean, 也就是说它的上下文是和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,
spring-servlet.xml文件(或是其他的你习惯的称呼)是为了一个servlet应用上下文呢定义bean. 在一个webapp中可以有多个此配置文件,
one per Spring servlet (e.g. spring1-servlet.xml for servlet spring1, spring2-servlet.xml for servlet spring2).
每一个spring的servlelt(例如: 名为spring1的servlet拥有配置文件spring1-servlet.xml, 名为spring2的servlet拥有配置文件spring2-servlet.xml).
Beans in spring-servlet.xml can reference beans in applicationContext.xml, but not vice versa.
在spring-servlet.xml中定义的bean可以直接引用在applicationContext.xml中定义的bean, 但是反过来不可以.
All Spring MVC controllers must go in the spring-servlet.xml context.
所有springmvc的Controller必须在spring-servlet.xml对应的上下文中运行.
In most simple cases, the applicationContext.xml context is unnecessary. It is generally used to contain beans that are shared between all servlets
在大多数简单的情况下, applicationContext.xml对应的上下文并不必须. 它通常用来包含那些bean用来在webapp中所有servlet之间共享.
in a webapp. If you only have one servlet, then there’s not really much point, unless you have a specific use for it.
如果你只有一个servlet, 那么实际没有什么必要定义applicationContext.xml, 除非你有特别应用.
本文转自:https://blog.csdn.net/gao_zhennan/article/details/81331218
springMVC:为MultipartFilte配置了上传文件解析器,报错或不能使用的更多相关文章
- ASP.NET Uploadify 上传文件过大 报错(http error)借鉴,以防忘记
Uploadify上传文件原来很早之前用过,没发现什么问题.今天再使用过程中,当文件大于30M的时候就会报错404.查看错误消息提示配置最大上传太小了.需要修改. 记得原来配置上传文件大小在这里:&l ...
- VFS 上传文件到sftp 报错 包含中文路径 或者中文文件名称
之前用Apache commons-vfs工具进行ftp操作(FTP服务器是 FileZilla Server) 上传本地文件 到 ftp服务器上,如果文件名称 包含 中文 报错 org.apache ...
- jetty上传文件的时候报错显示文件过大
这个时候我们需要修改jetty的参数文件 cd /data/java_web_app/news23456/etc vim jetty.xml 找到这一行 <Configure id=" ...
- springBoot上传文件时MultipartFile报空问题解决方法
springBoot上传文件时MultipartFile报空问题解决方法 1.问题描述: 之前用spring MVC,转成spring boot之后发现上传不能用.网上参考说是spring boot已 ...
- windows中修改catalina.sh上传到linux执行报错This file is needed to run this program解决
windows中修改catalina.sh上传到linux执行报错This file is needed to run this program解决 一.发现问题 由于tomcat内存溢出,在wind ...
- Git上传代码遇到的报错
Git上传代码遇到的报错 1.git上传代码卡住(Total 7072 (delta 2508), reused 6844 (delta 2376), pack-reused 0) git confi ...
- Web Server 配置及上传文件
第一种方案:从github上面克隆到服务器 1.git上传文件 ( git bash ) ①切换至所要上传的文件夹 cd 文件夹homepage ②告诉系统当前文件夹要进行git管理 git init ...
- 3、配置XShell上传文件
1.yum -y install lrzsz(安装 lrzsz) 2.rz -y(会弹出选择文件框,选择上传文件)
- ftp配置 Laravel上传文件到ftp服务器
listen=YES anonymous_enable=NO local_enable=YES write_enable=YES local_umask= dirmessage_enable=YES ...
随机推荐
- 【Docker】Docker容器中安装netstat命令
1)先执行 apt-get update 2) 再执行 apt-get install net-tools
- 用Photoshop软件实现批量压缩照片
前提:手头有 "大" 照片,出于某种原因想把它变成 "小" 照片:电脑刚好安装有PS软件. 需知:如果您的压缩需求仅限于降低图片品质,降低图片像素,那么建议您采 ...
- Explorer(2019年牛客多校第八场E题+线段树+可撤销并查集)
题目链接 传送门 题意 给你一张无向图,每条边\(u_i,v_i\)的权值范围为\([L_i,R_i]\),要经过这条边的条件是你的容量要在\([L_i,R_i]\),现在问你你有多少种容量使得你可以 ...
- 项目Beta冲刺--3/7
项目Beta冲刺--3/7 作业要求 这个作业属于哪个课程 软件工程1916-W(福州大学) 这个作业要求在哪里 项目Beta冲刺 团队名称 基于云的胜利冲锋队 项目名称 云评:高校学生成绩综合评估及 ...
- 男上加男 BETA冲刺博客汇总
项目BETA冲刺(团队) --总结 1.团队信息 团队名 :男上加男 成员信息 : 队员学号 队员姓名 个人博客地址 备注 221600427 Alicesft https://www.cnblogs ...
- JSR303/JSR-349,hibernate validation,spring validation 之间的关系
JSR303是一项标准,JSR-349是其的升级版本,添加了一些新特性,他们规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,他们位于javax.validation.co ...
- git 学习笔记 —— 获取远端分支并修改后提交至远端仓库
笔者最近进行开发过程中,所有参与者的代码需要通过 git 上传到远端仓库中,不同的模块对应不同的 git 分支,不同模块的数据需要从远端仓库中获取.这里记录下笔者从远端仓库中获取分支数据,进行修改,最 ...
- wordpress导航当前页面菜单高亮显示如何操作
我们在制作wordpress主题时有些客户要求导航在访问某个菜单时,这个菜单项会高亮显示,让用户知道自己正在访问的是哪个菜单下的内容,这个要如何实现呢?wordpress早就为你想好了,.curren ...
- haproxy 2.0 dataplaneapi docker 镜像
为了方便测试dataplaneapi 基于官方的docker镜像,制作了一个简单的包含dataplaneapi 的镜像 下载dataplaneapi https://github.com/haprox ...
- REdis一致性方案探讨
REdis功能强大众所周知,能够大幅简化开发和提供大并发高性能,但截止到REdis-5.0.5仍然存在如下几大问题: 一致性问题 这是由于REdis的主从复制采用的是异步复制,异常时可能发生主节点的数 ...