【问题标题】:Spring MVC 4 AJAX upload MultipartFile with extra parametersSpring MVC 4 AJAX 上传带有额外参数的 MultipartFile
【发布时间】:2025-12-05 23:45:02
【问题描述】:

我目前正在开发使用 AJAX (jQuery) 和 Spring MVC 4 上传文件。除了文件本身,我还必须发送一些额外的参数,例如正在上传的文件的描述。我正在使用一个$.ajax() 调用,它发送一个FormData 对象以及我的CSRF 令牌,如下所述:

var formdata = new FormData();
    formdata.append("description", $('#description').val());
    formdata.append("file", $("#file")[0].files[0]);

$.ajax({
    url: '/upload',
    type: 'POST',
    headers : {"X-CSRF-TOKEN" : $('#myToken').val()}
    data: formdata,
    enctype: 'multipart/form-data',
    processData: false,
    contentType: false,
    success: function (data) {
        alert("Data Uploaded: "+data);
    }
});

我找到了多个如何使用 javascript 的 FormData 对象以及接收 MultipartFile 对象的 Spring 控制器上传文件的示例,但是当我尝试使用 @RequestParam 检索其他参数时,我最终得到了错误。以下是我正在尝试的示例(不起作用):

@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public boolean uploadFile(
        @RequestParam(value = "file") MultipartFile file, 
        @RequestParam(value = "description") String description) {

    //Do stuff...

}

经过大量研究并尝试不同的方法后,我发现我可以将HttpServletRequest 声明为参数,它可以让我检索每个参数(但不能检索文件本身)。 下面是一个工作示例

@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseBody
public boolean uploadFile(
        @RequestParam(value = "file") MultipartFile file, 
        final HttpServletRequest request) {

    String description = request.getParameter("description");

    //Do some other stuff...

}

尽管上面的示例有效,但我不能使用注释并且在方法的签名中明确显示我的参数这一事实让我很烦恼。所以我尝试了一种不同的方法,将@PRequestParam 注释更改为@ModelAttribute 注释,效果出奇的好。

我的问题是:

  1. 如果参数可在HttpServletRequest 对象中检索,为什么@RequestParam 不起作用?

  2. 为什么@ModelAttribute 有效?我应该使用它而不是从 HttpServletRequest 显式检索内容吗?

【问题讨论】:

    标签: java jquery ajax spring-mvc spring-annotations


    【解决方案1】:

    这可能来得太晚了,但您可以将描述作为参数传递到 url:

    url: '/upload?' + $.param({description: $('#description').val()});
    

    别忘了问号!

    对于数据,您只需传递实际文件:

    data: $("#file")[0].files[0]
    

    你的控制器看起来像这样:

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ResponseBody
    public boolean uploadFile(
        @RequestParam(value = "file") MultipartFile file, 
        @RequestParam(value = "description") String description) {
    
    //Do stuff...
    

    }

    希望有帮助!

    【讨论】: