Java 使用Jersey在REST服务中上载多个文件

Java 使用Jersey在REST服务中上载多个文件,java,curl,jersey,jax-rs,multipartform-data,Java,Curl,Jersey,Jax Rs,Multipartform Data,这里有很多链接建议使用多部分/表单数据,以及如何在这里上传文件。对于通过CURL命令上载到REST服务并接受FormDataMultiPart的多个文件的组合,无法真正找到一个 当前正在使用的代码如下所示: @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.

这里有很多链接建议使用
多部分/表单数据
,以及如何在这里上传文件。对于通过CURL命令上载到REST服务并接受
FormDataMultiPart
的多个文件的组合,无法真正找到一个

当前正在使用的代码如下所示:

@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柱 "" -H“accept:application/json”-H“Content Type:multipart/form data”-F“file=@/Users/naman/Desktop/Media/video.mp4;Type=video/mp4”

但是它会导致
multiPart
在服务和NPE中成为
null


我在这里遗漏了什么愚蠢的东西吗?

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

curl-X柱 "" -H“accept:application/json”-H“Content Type:multipart/form data”-F“file=@/Users/naman/Desktop/Media/video.mp4”-F“Type=video/mp4”


问题在于方法参数(存在
@FormDataParam

@FormDataParam
用于以声明方式从多部分请求中提取单个部分,而
FormDataMultiPart
用于获取整个多部分正文并以编程方式提取每个部分。有一个嵌套的多部分,其中完整的多部分是一个单独的部分(在这种情况下,您所拥有的将起作用),但这里的情况并非如此

如果删除
@FormDataParam(“文件”)
,则它将按预期工作。您可以使用使用
getField(fieldName)
的方法开始从多部分中提取部分。这将为您提取的每个部分提供一个
FormDataBodyPart
。如果希望该部分作为
InputStream
,则可以使用
FormDataBodyPart#getValueAs(InputStream.class)
获取数据,也可以使用
File.class
byte[].class
,无论您的偏好如何。这是如何从
FormDataMultiPart
中提取数据

每个零件都有自己的名称,您可以使用该名称提取零件。对于cURL请求,您发送了一个部件,部件名称为
file
。i、 e.
“文件=@/Users/…”
。因此,如果要发送另一个部件,只需添加另一个名称不同的参数1:

curl-X POST”http://localhost:37200/api/sample-“散装”\
-H“接受:应用程序/json”\
-H“内容类型:多部分/表单数据”\
-F“file1=@/Users/naman/Desktop/Media/video.mp4”\
-F“file2=@/Users/naman/Desktop/Media/other_video.mp4”
如前所述,
@FormDataParam
用于以声明方式提取部分。使用零件的名称作为注释值。因此,使用前面的cURL命令,您可以执行以下操作

public Response bulkUpload(
        @FormDataParam("file1") InputStream file1,
        @FormDaraParam("file1") FormDataContentDisposition file1Fdcd,
        @FormDataParam("file2") InputStream file2,
        @FormDaraParam("file2") FormDataContentDisposition file2Fdcd) {
}
您可以从
FormDataContentDisposition
获取有关该部件的信息,例如文件名

另见

脚注
  • 零件也可以有相同的名称,例如

    -F file=@path_to_file1
    -F file=@path_to_file2
    
    这就是为什么当您试图以编程方式获取零件时,会得到一个FormDataCodeParts列表,而不是一个对象,即

    FormDataMultiPart multiPart = ...
    List<FormDataBodyPart> files = multiPart.getField("file");
    
  • 使用此参数
    公共响应上载文件(@FormDataParam(“文件”)列表文件)
    用于循环
    对于(int j=0;j
    A使用
    FormDataMultiPart
    ,我开始怀疑这是否得到了某种支持。当使用
    FormDataMultiPart
    时,您不使用
    @FormDataParam
    FormDataMultiPart
    是整个请求正文(所有部分)。当您想要获取单个零件时,可以使用
    @FormDataParam
    ,其中可以使用零件的名称作为注释值。也许可以提供一些澄清。另外请看@PaulSamsotha,非常感谢您的回复。我将在一段时间内查看文档,尽管我可以通过最简单的示例验证删除
    @FormDataParam
    是否可以为
    多部分
    增加价值。我使用您希望处理多部分的方式。我做了formData.append('file',file.name,file.data);service.ts文件中的formData.append('testObj',JSON.stringyfy(testObj))。在REST上使用multipart获取“testObj”和“file”,但获取NPE
    FormDataMultiPart multiPart = ...
    List<FormDataBodyPart> files = multiPart.getField("file");
    
    public Response upload(@FormDataParam("file") List<InputStream> files) { ... }
    
    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   }