Search code examples
jersey-client

Java Jersey Client upload multiple files associated with named control


I am having trouble trying to figure out how to get Java Jersey Client (https://jersey.java.net/documentation/latest/client.html) code to do something. I have an application that has the capability of uploading multiple files. See the following HTML.

<form action="http://localhost:8080/app/rest/files/uploadMultipleFiles" method="post"
                                               enctype="multipart/form-data">  
 <p>  
   Select a file to Upload to server: 
   <input type="file" name="files" size="60" multiple=“multiple”/>  
 </p>  
 <input type="submit" value="Upload File" />  
</form>  

NOTE: Any uploaded files would be associated with the input control name "files".

The SERVER CODE does the following:

@Path("/uploadMultipleFiles")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFiles(final FormDataMultiPart multiPart)
{ 
  //Get contents of control named “files”
    List<FormDataBodyPart> bodyParts = multiPart.getFields("files");
    /* Save multiple files */
    if (bodyParts != null)
    {

        for (int i = 0; i < bodyParts.size(); i++)
        {

            BodyPartEntity bodyPartEntity = (BodyPartEntity) bodyParts.get(i).getEntity();
            String fileName = bodyParts.get(i).getContentDisposition().getFileName();
            try
            {
                String path = temporaryUploadDirectory + File.separator + fileName;
                long size = saveFile(bodyPartEntity.getInputStream(), path);

…. It uses the HTML input control name “files” to obtain the list List of uploaded files. It can then access each file as a BodyPartEntity.

I’m having great difficulty figuring out how to get a Jersey client to upload the code so that the files are associated with a control names “files”. I want to write client code to upload to the server this way (the HTML fragment before the server code works fine. I want the Jersey client code to send data for upload in the exact same way, but cant figure out how).

I can throw together code to create FileDataBodyPart for each file to upload. But I don't know how to associate them with a control named "files":

List<FileDataBodyPart> bodyParts = new ArrayList<FileDataBodyPart>();
//get files to upload from file system
File dir = new File(classLoader.getResource("uploadTestDirectory").getFile());
if (dir.exists())
{
    File[] files = dir.listFiles();
    int count = 0;
    forFile f : files)
    {
       //Create a FileDataBodyPart for each file from uploadTestDirectory. Add to a list 
       bodyParts.add(new FileDataBodyPart("file" 
                       + count, new File(f.getAbsolutePath()),
                        MediaType.APPLICATION_OCTET_STREAM_TYPE));
       count++;        
    }

    WebTarget webTarget = client.target("http://localhost:8080/app/rest").path("files")
                                     .path("uploadMultipleFiles");

    //FOLLOWING IS THE FormDataMultiPart to upload
    FormDataMultiPart multiPart = new FormDataMultiPart();
    multiPart.setMediaType(MediaType.MULTIPART_FORM_DATA_TYPE);

    //add the file body parts
    for (FileDataBodyPart bp : bodyParts)
    {
        multiPart.bodyPart(bp);
    }

    Response clientResponse =
            webTarget.request(MediaType.APPLICATION_JSON).post(
                 Entity.entity(multiPart, multiPart.getMediaType()));
}

My question: How can I modify the above code so that the files( the FileDataBodyPart objects) are included under a control named “files” (like my server code expects, like the HTML at the top would produce).

I can upload files with client code like the above but can’t figure out a way to associate them with a “files” control. Does this make sense?

Any help would be appreciated. -Andrew


Solution

  • It doesn't appear that there is support for this:

    https://jersey.java.net/apidocs/2.6/jersey/org/glassfish/jersey/media/multipart/FormDataMultiPart.html

    See "TODO Consider supporting the use case of a nested multipart/mixed body part to contain multiple uploaded files."