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

 ̄綄美尐妖づ 提交于 2019-12-04 03:09:48

问题


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";
    }

} 

@RestEndpoint annotation is:

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

My ContextCOnfiguration class is:

@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.xml file:

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

Spring version is: 4.0.4

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

Thanks


回答1:


I don't know why they did this, but the MultipartResolver bean in the context needs to be named multipartResolver. Rename your @Bean method to

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

Or give it the name explicitly

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



回答2:


allowCasualMultipartParsing="true"

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




回答3:


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

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

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

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

or

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



回答4:


The answer by R. Ali Ashik worked for me.

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

  <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:

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

The relevant reference material in the context is this: 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).


来源:https://stackoverflow.com/questions/24265573/unable-to-process-parts-as-no-multi-part-configuration-has-been-provided

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!