【问题标题】:Unable to process parts as no multi-part configuration has been provided无法处理零件,因为没有提供多零件配置
【发布时间】:2014-08-07 13:40:30
【问题描述】:

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

@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注解为:

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

我的 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;
    }
...
}

--- 已更新 ---

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>

---- 已更新----

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();

    }


}

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

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

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

春季版本为:4.0.4

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

谢谢

【问题讨论】:

  • 请向我们展示您的 web.xml 或等效的 java 配置。
  • @SotiriosDelimanolis 更新了问题。谢谢!
  • 我也想看看你的WebAppInitializer
  • @SotiriosDelimanolis 使用引导代码更新。再次感谢
  • 请求是否正确发送到了其余调度程序?

标签: java spring spring-mvc multipartform-data


【解决方案1】:

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

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

或者明确地给它命名

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

【讨论】:

    【解决方案2】:
    allowCasualMultipartParsing="true"
    

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

    【讨论】:

    • 不,这是 Tomcat Servlet 容器特定的配置。 OP 所说的错误是缺少 MultipartResolver bean 的 Spring MVC 错误。
    【解决方案3】:

    没有找到多部分配置的例外情况很简单。虽然您提供了 multipartResolver bean。

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

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

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

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

    【讨论】:

    • 上面接受的答案实际上为我做了。可能您的答案适合另一种情况。
    • 我认为这是因为版本。接受的答案对我不起作用。我研究了更多,发现更改 bean name 解决了这个问题。
    【解决方案4】:

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

    以下是我正在从事的项目的 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>
    

    由于我有一个带有持久身份验证设置的自定义登录页面,我还需要具备以下条件:

    public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
    
            @Override
            protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
                insertFilters(servletContext, new MultipartFilter());
            }
        }
    

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

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

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

    相关文字如下:

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

    【讨论】:

      猜你喜欢
      • 2017-04-17
      • 2017-02-08
      • 2020-10-22
      • 2014-08-26
      • 2016-08-16
      • 2014-06-29
      • 2023-04-01
      • 2018-10-23
      • 1970-01-01
      相关资源
      最近更新 更多