15

I am using jboss's rest-easy multipart provider for importing a file. I read here http://docs.jboss.org/resteasy/docs/1.0.0.GA/userguide/html/Content_Marshalling_Providers.html#multipartform_annotation regarding @MultipartForm because I can exactly map it with my POJO.

Below is my POJO

public class SoftwarePackageForm {

    @FormParam("softwarePackage")
    private File file;

    private String contentDisposition;

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public String getContentDisposition() {
        return contentDisposition;
    }

    public void setContentDisposition(String contentDisposition) {
        this.contentDisposition = contentDisposition;
    }
}

Then I got the file object and printed its absolute path and it returned a file name of type file. The extension and uploaded file name are lost. My client is trying to upload a archive file(zip,tar,z)

I need this information at the server side so that I can apply the un-archive program properly.

The original file name is sent to the server in content-disposition header.

How can I get this information? Or atleast how can I say jboss to save the file with the uploaded file name and extension? Is it configurable from my application?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Krishna Chaitanya
  • 2,533
  • 4
  • 40
  • 74
  • Can you try adding `@PartType("application/zip")` to your `file` and see if it works? The full package is `org.jboss.resteasy.annotations.providers.multipart.PartType`. – ivan.sim Oct 13 '14 at 06:09
  • @isim Yeah I will try. What will be the value for tar and Z files? – Krishna Chaitanya Oct 13 '14 at 06:47
  • @isim No use :( It did not work. I don't understand why people wrap apis when they don't provide all functionality which the original apis provide. They say something can be done better, they provide apis, they introduce more problems and by the time we come to know this, we are locked. I am working on this from almost 3 days and fed up. – Krishna Chaitanya Oct 13 '14 at 06:54

4 Answers4

23

After looking around a bit for Resteasy examples including this one, it seems like there is no way to retrieve the original filename and extension information when using a POJO class with the @MultipartForm annotation.

The examples I have seen so far retrieve the filename from the Content-Disposition header from the "file" part of the submitted multiparts form data via HTTP POST, which essentially, looks something like:

Content-Disposition: form-data; name="file"; filename="your_file.zip"
Content-Type: application/zip

You will have to update your file upload REST service class to extract this header like this:

@POST
@Path("/upload")
@Consumes("multipart/form-data")
public Response uploadFile(MultipartFormDataInput input) {

  String fileName = "";
  Map<String, List<InputPart>> formParts = input.getFormDataMap();

  List<InputPart> inPart = formParts.get("file"); // "file" should match the name attribute of your HTML file input 
  for (InputPart inputPart : inPart) {
    try {
      // Retrieve headers, read the Content-Disposition header to obtain the original name of the file
      MultivaluedMap<String, String> headers = inputPart.getHeaders();
      String[] contentDispositionHeader = headers.getFirst("Content-Disposition").split(";");
      for (String name : contentDispositionHeader) {
        if ((name.trim().startsWith("filename"))) {
          String[] tmp = name.split("=");
          fileName = tmp[1].trim().replaceAll("\"","");          
        }
      }

      // Handle the body of that part with an InputStream
      InputStream istream = inputPart.getBody(InputStream.class,null);
    
      /* ..etc.. */
      } 
    catch (IOException e) {
      e.printStackTrace();
    }
  }

  String msgOutput = "Successfully uploaded file " + fileName;
  return Response.status(200).entity(msgOutput).build();
}

Hope this helps.

Gerald Mücke
  • 10,724
  • 2
  • 50
  • 67
ivan.sim
  • 8,972
  • 8
  • 47
  • 63
  • Yeah, I have fall back to this approach. I raised a issue in their forum as well here https://issues.jboss.org/browse/RESTEASY-1115. Thanks for your efforts. – Krishna Chaitanya Oct 14 '14 at 05:44
5

You could use @PartFilename but unfortunately this is currently only used for writing forms, not reading forms: RESTEASY-1069.

Till this issue is fixed you could use MultipartFormDataInput as parameter for your resource method.

lefloh
  • 10,653
  • 3
  • 28
  • 50
-1

If you user MultipartFile class, than you can do something like:

MultipartFile multipartFile;
multipartFile.getOriginalFilename();
-2

It seems that Isim is right, but there is a workaround.

Create a hidden field in your form and update its value with the selected file's name. When the form is submitted, the filename will be submitted as a @FormParam.

Here is some code you could need (jquery required).

<input id="the-file" type="file" name="file">
<input id="the-filename" type="hidden" name="filename">

<script>
$('#the-file').on('change', function(e) {
    var filename = $(this).val();
    var lastIndex = filename.lastIndexOf('\\');
    if (lastIndex < 0) {
        lastIndex = filename.lastIndexOf('/');
    }
    if (lastIndex >= 0) {
        filename = filename.substring(lastIndex + 1);
    }
    $('#the-filename').val(filename);
});
</script>
agelbess
  • 4,249
  • 3
  • 20
  • 21