Java 由于未提供多部件配置,因此无法处理部件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24265573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 11:11:53  来源:igfitidea点击:

Unable to process parts as no multi-part configuration has been provided

javaspringspring-mvcmultipartform-data

提问by royB

I wrote a simple controller for uploading files:

我写了一个简单的控制器来上传文件:

@RestEndpoint
public class ImageController {
    @Autowired
    GridFsTemplate mTemplate;

    @RequestMapping(value = "images", method = RequestMethod.POST)
    public @ResponseBody String testPhoto(@RequestParam String name, @RequestParam String directory, @RequestParam MultipartFile file) throws IOException {

        if(!file.isEmpty()){
            final byte[] bytes = file.getBytes();
            InputStream inputStream = new ByteArrayInputStream(bytes);
            mTemplate.store(inputStream, "name");

            return "uploaded photo";
        }

        return "failed";
    }

} 

@RestEndpointannotation is:

@RestEndpoint注释是:

@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
public @interface RestEndpoint
{
    String value() default "";
}

My ContextCOnfiguration class is:

我的 ContextCONfiguration 类是:

@Configuration
@EnableWebMvc
@ComponentScan(
    basePackages = "com.questter.site",
    useDefaultFilters = false,
    includeFilters =
    @ComponentScan.Filter({RestEndpoint.class, RestEndpointAdvice.class})
)
public class RestServletContextConfiguration extends WebMvcConfigurerAdapter {
    @Bean
    public CommonsMultipartResolver multiPartResolver(){

        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        return resolver;
    }
...
}

--- UPDATED ---

- - 更新 - -

web.xmlfile:

web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
     version="3.1">

    <display-name>Spring Application</display-name>

    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <url-pattern>*.jspf</url-pattern>
            <page-encoding>UTF-8</page-encoding>
            <scripting-invalid>true</scripting-invalid>
            <include-prelude>/WEB-INF/jsp/base.jspf</include-prelude>
            <trim-directive-whitespaces>true</trim-directive-whitespaces>
            <default-content-type>text/html</default-content-type>
        </jsp-property-group>
    </jsp-config>

    <!--<context-param>-->
        <!--<param-name>spring.profiles.active</param-name>-->
        <!--<param-value>development</param-value>-->
    <!--</context-param>-->

    <session-config>
        <session-timeout>30</session-timeout>
        <cookie-config>
            <http-only>true</http-only>
        </cookie-config>
        <tracking-mode>COOKIE</tracking-mode>
    </session-config>

    <distributable />

</web-app>

---- UPDATED ----

- - 更新 - -

public class Bootstrap implements WebApplicationInitializer
{

    @Override
    public void onStartup(ServletContext container) throws ServletException
    {
        container.getServletRegistration("default").addMapping("/resource/*");

        AnnotationConfigWebApplicationContext rootContext =
            new AnnotationConfigWebApplicationContext();
        rootContext.register(RootContextConfiguration.class);
        container.addListener(new ContextLoaderListener(rootContext));

        AnnotationConfigWebApplicationContext webContext =
            new AnnotationConfigWebApplicationContext();
        webContext.register(WebServletContextConfiguration.class);
        ServletRegistration.Dynamic dispatcher = container.addServlet(
            "springWebDispatcher", new DispatcherServlet(webContext)
        );
        dispatcher.setLoadOnStartup(1);
        dispatcher.setMultipartConfig(new MultipartConfigElement(
            null, 20_971_520L, 41_943_040L, 512_000
        ));
        dispatcher.addMapping("/");

        AnnotationConfigWebApplicationContext restContext =
                new AnnotationConfigWebApplicationContext();
        restContext.register(RestServletContextConfiguration.class);
        DispatcherServlet servlet = new DispatcherServlet(restContext);
        servlet.setDispatchOptionsRequest(true);
        dispatcher = container.addServlet(
                "springRestDispatcher", servlet
        );
        dispatcher.setLoadOnStartup(2);
        dispatcher.addMapping("/rest/*");

        rootContext.refresh();
        DbBootstrap dbBootstrap = rootContext.getBean(DbBootstrap.class);
        dbBootstrap.init();

    }


}

When perfoming a post request (using postman) i'm getting:

在执行发布请求时(使用邮递员),我得到:

HTTP Status 500 - Request processing failed; nested exception is java.lang.IllegalArgumentException:Expected MultipartHttpServletRequest: is a MultipartResolver configured 

I've looked over some similar questions over stackoverflow but none of the answers helped me.

我在stackoverflow上查看了一些类似的问题,但没有一个答案对我有帮助。

Spring version is: 4.0.4

Spring 版本为:4.0.4

Any help will be greatly appreciated (with a thumbs up of course).

任何帮助将不胜感激(当然竖起大拇指)。

Thanks

谢谢

采纳答案by Sotirios Delimanolis

I don't know why they did this, but the MultipartResolverbean in the context needs to be named multipartResolver. Rename your @Beanmethod to

我不知道他们为什么这样做,但是MultipartResolver上下文中的bean 需要命名为multipartResolver. 将您的@Bean方法重命名为

public CommonsMultipartResolver multipartResolver(){ // lowercase 'P'

Or give it the name explicitly

或者明确地给它命名

@Bean(name = "multipartResolver")
public CommonsMultipartResolver canBeCalledAnything(){

回答by Sotirios Delimanolis

allowCasualMultipartParsing="true"

on context tag inside context.xml, it's work for me

在 context.xml 中的上下文标记上,它对我有用

回答by Ramjan Ali

It is straight forward from the exception that no multi-part configuration is found. Though you have provided multipartResolverbean.

从没有找到多部分配置的例外情况来看,这是直接的。尽管您提供了multipartResolverbean。

The problem is that while specifying the MultipartFilterbefore the Spring Security filter, It tries to get the multipartResolverbean but can't find it. Because it expect the bean name/id as filterMultipartResolverinstead of multipartResolver.

问题是在 Spring Security 过滤器之前指定MultipartFilter 时,它尝试获取multipartResolverbean 但找不到它。因为它期望 bean 名称/id 为filterMultipartResolver而不是multipartResolver

Do yourself a favor. Please change the bean configuration like following -

帮自己一个忙。请更改 bean 配置,如下所示 -

@Bean
public CommonsMultipartResolver filterMultipartResolver(){
    CommonsMultipartResolver resolver = new 
    CommonsMultipartResolver();
    return resolver;
}

or

或者

@Bean(name = "filterMultipartResolver")
public CommonsMultipartResolver multiPartResolver(){
    CommonsMultipartResolver resolver = new 
    CommonsMultipartResolver();
    return resolver;
}

回答by Fruitjam

The answer by R. Ali Ashik worked for me.

R. Ali Ashik 的回答对我有用。

Following is the relevant part of pom.xml of the project that I am working on:

以下是我正在处理的项目的 pom.xml 的相关部分:

  <properties>
  <springframework.version>5.0.2.RELEASE</springframework.version>
  <springsecurity.version>5.0.0.RELEASE</springsecurity.version>
  <hibernate.version>5.2.17.Final</hibernate.version>
  <mysql.connector.version>8.0.11</mysql.connector.version>

  <properties>
  <springframework.version>5.0.2.RELEASE</springframework.version>
  <springsecurity.version>5.0.0.RELEASE</springsecurity.version>
  <hibernate.version>5.2.17.Final</hibernate.version>
  <mysql.connector.version>8.0.11</mysql.connector.version>

Since, I have a custom login page with persistent authentication setup, I also needed to have the following:

因为我有一个带有持久身份验证设置的自定义登录页面,所以我还需要以下内容:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

        @Override
        protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
            insertFilters(servletContext, new MultipartFilter());
        }
    }

But the actual clincher was this as pointed out by R. Ali Ashik:

但正如 R. Ali Ashik 指出的那样,真正的关键在于:

@Bean(name = "filterMultipartResolver")
public CommonsMultipartResolver multiPartResolver(){
    CommonsMultipartResolver resolver = new 
    CommonsMultipartResolver();
    return resolver;
}

The relevant reference material in the context is this: Class MultipartFilter

上下文中的相关参考资料是这样的: Class MultipartFilter

And the relevant text is as follows:

相关文字如下:

Looks up the MultipartResolver in Spring's root web application context. Supports a "multipartResolverBeanName" filter init-param in web.xml; the default bean name is "filterMultipartResolver". Looks up the MultipartResolver on each request, to avoid initialization order issues (when using ContextLoaderServlet, the root application context will get initialized after this filter).