【问题标题】:Multiple files upload in a REST service using Jersey使用 Jersey 在 REST 服务中上传多个文件
【发布时间】:2019-07-09 13:49:17
【问题描述】:

这里有很多链接建议使用multipart/form-data 以及如何在此处上传文件。无法真正找到通过 CURL 命令上传的多个文件的组合以及接受 FormDataMultiPart 的 REST 服务的组合。

目前服务中的代码如下:

@javax.ws.rs.POST
@javax.ws.rs.Path("/sample-bulk")
@javax.ws.rs.Consumes(javax.ws.rs.core.MediaType.MULTIPART_FORM_DATA)
public javax.ws.rs.core.Response bulkUpload(@FormDataParam("file") org.glassfish.jersey.media.multipart.FormDataMultiPart multiPart) {
    log.info("{} log", multiPart.getField("file"));
    return Response.ok().build();
}

我尝试调用该服务的 CURL 为:

curl -X POST "http://localhost:37200/api/sample-bulk" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "file=@/Users/naman/Desktop/Media/video.mp4;type=video/mp4"

但它导致multiPart 在服务中成为null,当然在 NPE 中。

我在这里错过了什么愚蠢的事情?

【问题讨论】:

  • A sample suggestion online 使用 FormDataMultiPart,因为我开始怀疑这是否受到某种方式的支持。
  • 当你使用FormDataMultiPart时,你不使用@FormDataParamFormDataMultiPart整个请求正文(所有部分)。当您想要获取 individual 零件时,您可以使用@FormDataParam,您可以使用零件的名称作为注释值。也许this 可能会提供一些澄清。另请查看Jersey docs for Multipart
  • @PaulSamsotha 非常感谢您的回复。我会在一段时间内查看文档,尽管我可以通过最小的示例验证删除 @FormDataParam 是否可以为 multiPart 添加价值。

标签: java curl jersey jax-rs multipartform-data


【解决方案1】:

问题出在方法参数上(@FormDataParam的存在)

public Response bulkUpload(@FormDataParam("file") FormDataMultiPart multiPart) {}

@FormDataParam 用于以声明方式从多部分请求中提取单个部分,而FormDataMultiPart 用于获取整个多部分主体并以编程方式提取每个部分。 It's possible 有一个嵌套的多部分,其中完整的多部分是一个单独的部分(在这种情况下,你所拥有的会起作用),但这里不是这种情况。

如果您删除 @FormDataParam("file"),它将按预期工作。您可以使用getField(fieldName) 的方法开始从多部分中提取部分。这将为您提取的每个部分提供FormDataBodyPart。如果您希望该部分作为InputStream,您可以使用FormDataBodyPart#getValueAs(InputStream.class) 获取数据,或者您可以使用File.classbyte[].class,无论您喜欢什么。这是从FormDataMultiPart中提取数据的方法。

每个部分都有自己的名称,您可以使用该名称提取部分。对于您的 cURL 请求,您发送了一个部分,该部分的名称是 file。即"file=@/Users/..."。所以如果要发送另一部分,只需添加另一个名称不同的参数1as mentioned by Vladimir:

curl -X POST "http://localhost:37200/api/sample-bulk"\
     -H "accept: application/json"\
     -H "Content-Type: multipart/form-data"\
     -F "file1=@/Users/naman/Desktop/Media/video.mp4"\
     -F "file2=@/Users/naman/Desktop/Media/another_video.mp4"

正如我之前提到的,@FormDataParam 用于以声明方式提取部分。您使用零件的名称作为注释值。所以使用前面的 cURL 命令,你可以做到。

public Response bulkUpload(
        @FormDataParam("file1") InputStream file1,
        @FormDaraParam("file1") FormDataContentDisposition file1Fdcd,
        @FormDataParam("file2") InputStream file2,
        @FormDaraParam("file2") FormDataContentDisposition file2Fdcd) {
}

您可以从FormDataContentDisposition获取有关零件的信息,例如文件名。

另见


脚注

  1. 部件也可以具有相同的名称,例如

    -F file=@path_to_file1
    -F file=@path_to_file2
    

    这就是当您尝试以编程方式获取零件时,您会得到一个 FormDataBodyParts 列表而不是单个对象的原因,即

    FormDataMultiPart multiPart = ...
    List<FormDataBodyPart> files = multiPart.getField("file");
    

    如果您想以声明方式获取它们,您可以使用 List 而不是单个对象类型

    public Response upload(@FormDataParam("file") List<InputStream> files) { ... }
    

【讨论】:

  • 我使用你想处理多部分的方式。我做了 formData.append('file', file.name, file.data); service.ts 文件中的 formData.append('testObj', JSON.stringyfy(testObj))。并在 REST 上使用 multipart 获取“testObj”和“file”但获取 NPE
【解决方案2】:
Use this parameter 

public Response uploadFile(@FormDataParam("files") List<FormDataBodyPart> file) 

Use for loop

 for (int j = 0; j < files.size(); j++) {
   FormDataBodyPart this_formDataBodyPartFile = files.get(j);
   ContentDisposition this_contentDispositionHeader = this_formDataBodyPartFile
                                                    .getContentDisposition();
   InputStream this_fileInputStream = this_formDataBodyPartFile.getValueAs(InputStream.class);
                                            FormDataContentDisposition fileDetail = (FormDataContentDisposition) this_contentDispositionHeader;

//Write the code upload code   }

【讨论】:

    【解决方案3】:

    尝试为每个多部分条目使用单独的 -F 标志,类似这样:

    curl -X POST "http://localhost:37200/api/sample-bulk" -H“接受:应用程序/json”-H“内容类型:multipart/form-data”-F“file=@/Users/naman/Desktop/Media/video.mp4”-F“type=video/mp4”

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-20
      • 2018-02-19
      • 2017-11-23
      • 1970-01-01
      • 1970-01-01
      • 2016-07-11
      • 2015-09-17
      • 1970-01-01
      相关资源
      最近更新 更多