一、问题描述
为支持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. struts2启动报错:ERROR com.opensymphony.xwork2.conversion.impl.DefaultConversionPropertiesProcessor - Conversion registration error

    [framework] 2019-12-05 11:34:05,441 - org.springframework.web.context.ContextLoader -5352 [RMI TCP C ...

  2. 号称全站最直观解释-smv核函数-是干啥

    认识 svm 在求解时, 通过某非线性变换 φ( x) ,将输入空间映射到高维特征空间.特征空间的维数可能非常高.如果支持向量机的求解只用到内积运算,而在低维输入空间又存在某个函数 K(x, x′) ...

  3. prometheus学习系列十一: Prometheus和AlertManager的高可用

    前面的系列中, prometheus和alertmanager都是单机部署的,会有单机宕机导致系统不可用情况发生.本文主要介绍下prometheus和alertmanager的高可用方案. 服务的高可 ...

  4. Odoo中的五种Action详解

    转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10826232.html Odoo中的五种action都是继承自ir.actions.actions模型实现的 ...

  5. Python socket基本写法

    TCP:长连接,安全可靠,不会丢包,但是会发生黏包,面向流的传输,超长的数据包会被拆包发送 多条send的小数据会连在一起发送,造成黏包现象,是tcp协议内部的优化算法造成的 如果要发送特别大的数据时 ...

  6. FRP 中文文档

    https://github.com/fatedier/frp/blob/master/README_zh.md README | 中文文档 frp 是一个可用于内网穿透的高性能的反向代理应用,支持 ...

  7. python基础语法10 函数递归,模块,软件开发目录规范

    函数递归: 函数递归指的是重复 “直接调用或间接调用” 函数本身, 这是一种函数嵌套调用的表现形式. 直接调用: 指的是在函数内置,直接调用函数本身. 间接调用: 两个函数之间相互调用间接造成递归. ...

  8. wordpress文章显示同一分类下的上一篇下一篇

    我们在用wordpress开发网站的时候会在文章页中引入上一篇下一篇,但是发现新闻页的上下文章有可能是产品分类的post,这个就不太合理,如何显示同一分类下的上一篇下一篇文章呢?随ytkah一起来看看 ...

  9. 学习:窗口创建以及消息处理basic.c

    WNDCLASS结构: Windows 的窗口总是基于窗口类来创建的,窗口类同时确定了处理窗口消息的窗口过程(回调函数). 在创建应用程序窗口之前,必须调用 RegisterClass 函数来注册窗口 ...

  10. 小功能 清单模板导入 根据Excel生成树

    把代码备份一下,免得硬盘又坏了,看来已经造成心理阴影了啊. 方式一: //清单范本 public void test1() { //生成说明 var ds = ExcelHelper.ExcelToD ...