The problem is with the method parameter (the presence of the @FormDataParam
)
public Response bulkUpload(@FormDataParam("file") FormDataMultiPart multiPart) {}
@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.
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
.
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 name1, 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"
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) {
}
You can get information about the part, such as the file name from the FormDataContentDisposition
.
See also
Footnotes
Parts can have the same name also, e.g.
-F file=@path_to_file1
-F file=@path_to_file2
This is the reason when you try to get a part programmatically, you get a list of FormDataBodyParts instead of a single object i.e
FormDataMultiPart multiPart = ...
List<FormDataBodyPart> files = multiPart.getField("file");
And if you wanted to get them declaratively, you would use a List
instead of a single object type
public Response upload(@FormDataParam("file") List<InputStream> files) { ... }