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

时间:2014-06-17 13:47:37

标签: java spring spring-mvc multipartform-data

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

@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查看了一些类似的问题,但没有一个答案有帮助 我

Spring版本是:4.0.4

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

由于

4 个答案:

答案 0 :(得分:12)

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

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

或明确指定名称

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

答案 1 :(得分:5)

allowCasualMultipartParsing="true"

在context.xml中的context标签上,它对我起作用

答案 2 :(得分:2)

除了没有找到多部件配置之外,它是直接的。虽然您提供了 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;
}

答案 3 :(得分:0)

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