【问题标题】:How to implement multiple files upload with extra fields per each file in Spring Boot如何在 Spring Boot 中实现每个文件都有额外字段的多个文件上传
【发布时间】:2026-01-31 02:35:01
【问题描述】:

Spring Boot中如何实现多文件上传功能,每个文件都有自己的额外字段(例如comment、documentType)?

这个答案可能是相关的,但它仅适用于单个文件: Spring boot controller - Upload Multipart and JSON to DTO

【问题讨论】:

  • 点击此链接callicoder.com/… 帮助包括完整的前端、后端和来自邮递员的测试响应
  • @DHARMENDRASINGH 谢谢!但在示例中,每个文件没有额外字段的多文件上传。
  • 你有没有检查邮递员命中(屏幕截图)在那个 json 中的多次命中,他正在发送许多东西,比如类型、名称和大小
  • @DHARMENDRASINGH 不,它们是来自服务器(上传后)的响应,而不是请求,:)
  • 多文件上传和单文件上传没有区别,只需在spring中添加一个名为file2的表单文件输入,以@RequestParam("file2")接收即可。并且没有现成的方法可以在春季解决“DTO 列表”

标签: java spring spring-boot


【解决方案1】:

您可以在 POST 有效负载中编码多个请求部分,并使用 Spring Boot 进行处理。

假设您需要为每个文件传入两件事:

  • Blob 与文件内容
  • metadata - 一个可以容纳任何东西的对象 - 标题/cmets - 你可以命名它。

前端

您可以使用任何东西来模拟FormData 参数,这是在 TypeScript 中的:

假设一个文档如下所示:

export interface NewDocument {
  title: string,
  comment: string,
  author: string,
  file: File
}

所以 FormData 的生成可能是这样的:

private getFormData(doc: NewDocument): FormData {
  let formData: FormData = new FormData();
  const json: Blob = new Blob([JSON.stringify(doc)], {type: 'application/json'});
  formData.append('metadata', json); //adding the metadata
  const blob: Blob = new Blob([doc.file[0]], {type: doc.file[0].type});
  formData.append('file', blob); //adding the file contents
  return formData;
}

然后您可以POST 将表单数据发送到给定的端点。

后端

您可以在请求中指定不同的RequestParts

@PostMapping
public ResponseEntity<Void> uploadFile(@RequestPart("metadata") FileMetadata metadata,
@RequestPart("file") MultipartFile file) {
   //process
}

FileMetadata 这是一个自定义 Java POJO,您可以将前端的 NewDocument 的 JSON 表示反序列化到其中

你应该可以把它变成一个倍数的版本。

@PostMapping
public ResponseEntity<Void> uploadFile(@RequestPart("metadata") FileMetadata[] metadatas,
@RequestPart("file") MultipartFile[] files) {
   //process
}

现在的问题是如何识别哪个元数据是针对哪个文件的。

一种简单的方法是在元数据对象中编码文件名并将其用于映射。

【讨论】:

  • 不错的理论.. !!
【解决方案2】:

HTML端

<input id="files" type="file" name="files[]"  multiple />

上传

<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
<script type="text/javascript">
function uploadFiles(){
    var form = new FormData();
    var i=0;
    $.each($("input[type='file']")[0].files, function(i, file) {
        form.append('file', file);
        form.append('extradata','ola'+i);
        i++;
    });

    // send form data with ajax
    $.ajax({
        type: 'POST',
        url: '/uploadFiles',
        cache: false,
        contentType: false,
        processData: false,
        data : form,
        success: function(result){
            console.log(result);
            alert('upload success');
        },
        error: function(err){
            console.log(err);
        }
    })
}
</script>

和服务器端

@PostMapping("/uploadFiles")
public String uploadFiles(@RequestParam("file") MultipartFile[] files,
                          @RequestParam("extradata") String[] extras) throws Exception {
    int i = 0;
    Files.createDirectories(Paths.get("./uploaded/"));
    for (MultipartFile f : files) {
        Files.copy(f.getInputStream(), Paths.get("./uploaded/" + extras[i] + f.getOriginalFilename()));
        i++;
    }
    return "success";
}

你可以在这里找到运行示例https://github.com/ozkanpakdil/spring-examples/tree/master/demoMultiFileUpload

【讨论】: