Spring MVC:即使存在必需参数,文件上载也会出现错误请求(参数丢失) [英] Spring MVC: Bad request (parameter missing) on file upload even when required parameters are present

查看:152
本文介绍了Spring MVC:即使存在必需参数,文件上载也会出现错误请求(参数丢失)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个文件上传控制器,其方法如下所示:

I have a file-upload controller with a method that looks like this:

@RequestMapping(value = "/upload", method = RequestMethod.POST, produces = {"*/*", "application/json"})
public @ResponseBody ScriptUploadResponse upload(@RequestParam("userId") Long userId, @RequestParam("script") MultipartFile file) {
    return scriptService.upload(userId, file);
}

这曾经在Spring 3中使用基于XML的配置正常工作。我最近转移到使用Spring 4的基于Java的配置。当我上传文件时,我收到 400:错误请求,抱怨 userId 尚未提供。但是当我在浏览器中查看请求时,这就是我所看到的:

This used to work fine in Spring 3 with an XML-based config. I recently moved over to a Java-based config with Spring 4. When I upload a file, I get a 400: Bad request with the complaint that userId has not been provided. But when I look at the request in the browser, this is what I see:

------WebKitFormBoundaryoJhTJ817NockqUSY
Content-Disposition: form-data; name="userId"

1
------WebKitFormBoundaryoJhTJ817NockqUSY
Content-Disposition: form-data; name="script"; filename="script.js"
Content-Type: application/javascript


------WebKitFormBoundaryoJhTJ817NockqUSY--

Spring声明:


HTTP状态400 - 必需的长参数'userId'不存在

HTTP Status 400 - Required Long parameter 'userId' is not present

为什么Spring说我没有提供 userId 当有效负载显示它存在时?

Why is Spring saying that I haven't provided userId when the payload shows that it is present?

更新

我把断点放在 RequestParamMethodArgumentResolver.java (一个内部的Spring类)中,我可以看到 getParts() on HttpServletRequest 对象返回 no 部分。我不确定为什么会这样,但它似乎是问题的根源。从浏览器我可以看到正在发出的请求,但无论出于何种原因,多部分数据都没有通过。

I've put breakpoints inside RequestParamMethodArgumentResolver.java (an internal Spring class) and I can see that getParts() on the HttpServletRequest object returns no parts at all. I'm not sure why this is happening, but it seems to be the root of the issue. From the browser I can see the request being made, but for whatever reason, the multipart data isn't making it through.

推荐答案

我能够弄清楚这一点。要启用对多部分文件的支持,您必须以某种方式配置事物。这方面的文档令人沮丧地难以找到,Spring的文档似乎不完整或仅与基于XML的配置相关。我不确定我是在寻找错误的地方或者是什么,但即使是Google,我也无法找到一个解释如何设置它的地方。无论如何,这里是。

I was able to figure this out. To enable support for multipart files, you have to configure things in a certain way. The documentation for this was frustratingly hard to find and Spring's documentation regarding this seems to be incomplete or only related to XML-based config as well. I am not sure if I'm simply looking in the wrong place or what, but even with Google I was unable to find a single place that explains how to set this up. Anyway, here goes.

您首先必须在您的网络配置中包含一个bean。我只是将以下内容添加到我的配置类(扩展 WebMvcConfigurerAdapter ):

You first have to include a bean in your web configuration. I simply added the following to my configuration class (that extends WebMvcConfigurerAdapter):

@Bean
public MultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}

但这还不够。如果您正在使用Servlet 3.0并且还使用基于Java的配置,则必须配置调度程序servlet以支持多部分文件:

But this is not enough. If you are using Servlet 3.0 and also using a Java-based config for that, you have to configure the dispatcher servlet to support multipart files:

我将以下类添加到我的初始值设定项(扩展 WebApplicationInitializer ):

I added the following class to my initializer (that extends WebApplicationInitializer):

dispatcher.setMultipartConfig(
        new MultipartConfigElement("/tmp", 25 * 1024 * 1024, 125 * 1024 * 1024, 1 * 1024 * 1024)
);

整个方法最终看起来像这样:

The entire method ends up looking like this:

@Override
public void onStartup(ServletContext servletContext) {
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
    rootContext.register(ApplicationConfig.class, WebConfig.class);

    servletContext.addListener(new ContextLoaderListener(rootContext));

    //Spring security
    servletContext.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain")).addMappingForUrlPatterns(null, false, "/*");

    //Enable multipart support
    ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(rootContext));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");

    dispatcher.setMultipartConfig(
            new MultipartConfigElement("/tmp", 25 * 1024 * 1024, 125 * 1024 * 1024, 1 * 1024 * 1024)
    );
}

这篇关于Spring MVC:即使存在必需参数,文件上载也会出现错误请求(参数丢失)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆