users@jersey.java.net

Re: [Jersey] Working with binary files (images/files, etc) via REST

From: Kevin Duffey <andjarnic_at_yahoo.com>
Date: Tue, 7 Sep 2010 18:24:51 -0700 (PDT)

Ya, I was afraid that that would probably be the way to go. It shouldn't be a problem requiring the client side to submit the info separately for binary data. I'll have to look up multi-part.. haven't used it in such a way short of the old file upload servlet back in the day and setting a <form element to multipart. I need to find your add-on.. maybe they'll fix the download link soon so I can get to the latest to download it.


--- On Tue, 9/7/10, Craig McClanahan <craigmcc_at_gmail.com> wrote:

From: Craig McClanahan <craigmcc_at_gmail.com>
Subject: Re: [Jersey] Working with binary files (images/files, etc) via REST
To: users_at_jersey.dev.java.net
Date: Tuesday, September 7, 2010, 6:15 PM



On Tue, Sep 7, 2010 at 5:18 PM, Kevin Duffey <andjarnic_at_yahoo.com> wrote:


I like what you say, although I thought you built the add-on that I was looking for on handling file upload/download.. which the link seems to be broken right now on the jersey site to get to downloads.

Anyway, the issue I have is that the XML sent in may include several values at once, not just an image (or file). I thought that I could get away with wrapping it in a CDATA block... I've not personally experienced on how to turn a chunk of perhaps base64 encoded (or binhex) binary data from a CDATA chunk, especially via a Jersey call. But it would allow me to accept a chunk of XML that contains multiple values. It doesn't have to be this way, it would just make it more in line with the rest of how my XSD works. For that matter, can you even specify an XSD element that pertains to binary data and have it work with the Jersey/JAXB, so that I can accept it via a method in that manner?

If you're trying to include the binary data inside your XML document itself, AFAIK you'll need to base64 encode it or something (which means that, from the Jersey perspective, it's just a string field).  That's an XML thing, not really a Jersey or JAX-RS thing.

However, you're not going to be happy with the implications of this on message size.  If you have the ability to control the message format, I'd *really* suggest using multipart (or multipart/form-data) so that you can send the XML part in XML and the binary part in binary.  In other words, the XSD would only define the metadata about the image (or whatever the binary file is), and would not include the data itself.

Craig
 

--- On Tue, 9/7/10, Craig McClanahan <craigmcc_at_gmail.com> wrote:

From: Craig McClanahan <craigmcc_at_gmail.com>
Subject: Re: [Jersey] Working with binary files (images/files, etc) via REST
To: users_at_jersey.dev.java.net




On Tue, Sep 7, 2010 at 2:54 PM, Kevin Duffey <andjarnic_at_yahoo.com> wrote:


I went to the site today to try to find the addons to jersey.. want to look at working with sending binary data like files/images via a REST call. The downloads links all seem to go to Chapter 7 Dependencies now.

Anyway, despite that being broken, has anyone worked with sending files, images, large binary data, up via REST? I know Craig wrote an addon a while ago, just curious with all the changes lately if anyone has an elegant solution to sending files to REST and vice versa, getting files back from REST.

Thanks.


For upload and download of binary data by itself, the simplest thing to do is accept an InputStream argument (for upload), or produce an entity that is an InputStream (for download):

    @Path("/foo")


        @GET
        @Produces("image/png")
        public Response download(...) {
            InputStream stream = ... InputStream pointing at my image data ...

        }

        @POST
        @Consumes("image/png")
        public void upload(InputStream stream) {
            ... read from stream and store the image somewhere ...


This works because JAX-RS includes MessageBodyReader and MessageBodyWriter implementations that know what to do with an InputStream.

If you want to send metadata about the image along with the image itself, you can use the multipart extension stuff, but the same principle applies ... you'll use an InputStream to deal with the multipart body part that contains the binary data.

Craig