问题描述
这里有一些链接建议使用multipart/form-data
,以及如何在此处上传文件.对于通过CURL命令上传到多个接受FormDataMultiPart
的REST服务的多个文件的组合,找不到真正的文件.
Quite a few links here that suggest using multipart/form-data
and how to get the file upload here. Couldn't really find one for a combination of multiple files uploaded via CURL command and to a REST service accepting FormDataMultiPart
.
当前服务中的代码如下:
The code in service currently looks like :
@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为:
and the CURL I am trying to call the service is as :
但是它会导致服务处的multiPart
是null
,当然还会导致NPE.
But it results in multiPart
being null
at the service and of course NPE.
我在这里错过了任何愚蠢的事情吗?
Anything silly that I've missed here?
推荐答案
问题出在方法参数上(@FormDataParam
的存在)
The problem is with the method parameter (the presence of the @FormDataParam
)
public Response bulkUpload(@FormDataParam("file") FormDataMultiPart multiPart) {}
@FormDataParam
用于要从多部分请求中声明性地提取单个部分,而FormDataMultiPart
用于获取整个多部分主体并以编程方式 提取每个部分. 有可能具有嵌套的多部分,其中完整的多部分是单个部分(在这种情况下,您可以使用的部分),但这不是事实.
@FormDataParam
is used when you want to declaratively extract individual parts from the multipart request, whereas FormDataMultiPart
is used to get an entire multipart body and programmatically extract each part. It's possible to have a nested multipart where a complete multipart is an individual part (in which case what you have would work), but this is not the case here.
如果删除@FormDataParam("file")
,则它将按预期工作.您可以使用getField(fieldName)
的方法开始从多部分中提取部分.这将为您提取的每个部分提供一个FormDataBodyPart
.如果希望将该零件用作InputStream
,则可以使用FormDataBodyPart#getValueAs(InputStream.class)
获取数据,也可以使用File.class
或byte[].class
(无论您的偏好如何).这是从FormDataMultiPart
提取数据的方法.
If you remove the @FormDataParam("file")
, then it will work as expected. You can start extracting parts out of the multipart using the method you are using getField(fieldName)
. This will give you a FormDataBodyPart
for each part you extract. You can get the data with FormDataBodyPart#getValueAs(InputStream.class)
if you want that part as an InputStream
, or you can use File.class
or byte[].class
, whatever your preference. This is how to extract data from the FormDataMultiPart
.
每个部分都有其自己的名称,然后使用该名称提取该部分.对于您的cURL请求,您发送了一部分,该部分的名称为file
.即"file=@/Users/..."
.因此,如果要发送另一部分,只需添加另一个名称,如弗拉基米尔(Vladimir)提到的 :
Each part has it's own name and you extract the part using that name. In the case of your cURL request, you sent one part, and the part's name is file
. i.e. "file=@/Users/..."
. So if you want to send another part, just add another parameter with a different name, as 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命令,您可以做到.
As I mentioned earlier, @FormDataParam
is used to extract parts declaratively. You use the part's name as the annotation value. So with the previous cURL command, you could do.
public Response bulkUpload(
@FormDataParam("file1") InputStream file1,
@FormDaraParam("file1") FormDataContentDisposition file1Fdcd,
@FormDataParam("file2") InputStream file2,
@FormDaraParam("file2") FormDataContentDisposition file2Fdcd) {
}
您可以获取有关零件的信息,例如FormDataContentDisposition
中的文件名.
You can get information about the part, such as the file name from the FormDataContentDisposition
.
- Why "FormDataMultiPart" type parameter is treated differently
- Jersey documentation for its multipart support (on the server side)
- File upload along with other object in Jersey restful web service
这篇关于使用Jersey在REST服务中上传多个文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!