一、问题描述
为支持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配置了上传文件解析器,报错或不能使用的更多相关文章

  1. ASP.NET Uploadify 上传文件过大 报错(http error)借鉴,以防忘记

    Uploadify上传文件原来很早之前用过,没发现什么问题.今天再使用过程中,当文件大于30M的时候就会报错404.查看错误消息提示配置最大上传太小了.需要修改. 记得原来配置上传文件大小在这里:&l ...

  2. VFS 上传文件到sftp 报错 包含中文路径 或者中文文件名称

    之前用Apache commons-vfs工具进行ftp操作(FTP服务器是 FileZilla Server) 上传本地文件 到 ftp服务器上,如果文件名称 包含 中文 报错 org.apache ...

  3. jetty上传文件的时候报错显示文件过大

    这个时候我们需要修改jetty的参数文件 cd /data/java_web_app/news23456/etc vim jetty.xml 找到这一行 <Configure id=" ...

  4. springBoot上传文件时MultipartFile报空问题解决方法

    springBoot上传文件时MultipartFile报空问题解决方法 1.问题描述: 之前用spring MVC,转成spring boot之后发现上传不能用.网上参考说是spring boot已 ...

  5. 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 ...

  6. Git上传代码遇到的报错

    Git上传代码遇到的报错 1.git上传代码卡住(Total 7072 (delta 2508), reused 6844 (delta 2376), pack-reused 0) git confi ...

  7. Web Server 配置及上传文件

    第一种方案:从github上面克隆到服务器 1.git上传文件 ( git bash ) ①切换至所要上传的文件夹 cd 文件夹homepage ②告诉系统当前文件夹要进行git管理 git init ...

  8. 3、配置XShell上传文件

    1.yum   -y  install  lrzsz(安装 lrzsz) 2.rz -y(会弹出选择文件框,选择上传文件)

  9. ftp配置 Laravel上传文件到ftp服务器

    listen=YES anonymous_enable=NO local_enable=YES write_enable=YES local_umask= dirmessage_enable=YES ...

随机推荐

  1. 转摘jemeter学习-连接数据库之jdbc请求

    JMETER连接数据库 mysql下载地址:https://dev.mysql.com/downloads/connector/j/ mysql连接器根据语言选择/J,用的是Mac,选择下载.tar. ...

  2. java比较两个小数的大小

    BigDecimal data1 = new BigDecimal("1");BigDecimal data2 = new BigDecimal("1.0"); ...

  3. mysql分析sql语句基础工具 -- explain

    分析sql语句 explain explain (sql语句) G; 分析结果: id sql语句编号如果是连接查询,表之间是平等关系,编号相同:如果有子查询,编号递增. select——type 查 ...

  4. thinkphp5 数据库查询之paginate: 同时获取记录总数和分页数据

    thinkphp5中要想同时获得查询记录的总数量以及分页的数据, 可以用paginate(), 真的非常方便! 表结构: CREATE TABLE `t_users` ( `id` int(11) u ...

  5. Ofbiz项目学习——阶段性小结——服务返回结果

    一.返回成功 1.在.DispatcherReturnDemoService类中编写服务[returnSuccess],内容如下: /** * 返回成功结果 * @param dctx * @para ...

  6. luogu_4287:双倍回文

    洛谷4287:双倍回文 前言: 参考博文: https://www.cnblogs.com/Vscoder/p/10498625.html 题目描述: 记字符串\(w\)的倒置为\(w^R\).例如\ ...

  7. .net core 从 ActionFilterAttribute 获取Request.Body 的正确方式

    由于 ModelBinding在动作过滤器之前运行,直接使用 context.ActionArguments["parameter"]  获取模型对象 This article s ...

  8. ubuntu 安装任何版本的Firefox

    https://ftp.mozilla.org/pub/firefox/releases/ 1.sudo gedit /usr/share/applications/firefox.desktop 2 ...

  9. CCF 201812-3 CIDR合并

    CCF 201812-3 CIDR合并 //100分 93ms #include<stdio.h>//CCF上stdio.h比cstdio快!!! #include<string.h ...

  10. 使用charles对jmeter进行抓包