users@jersey.java.net

RE: [Jersey] File uploads through Jesery

From: Ashish Raniwala <araniwala_at_gmail.com>
Date: Sat, 23 Aug 2008 01:45:44 +0530

Hi Paul,

 

In below code you have specified @InputStream. Is this some annotation? I am
working with 0.9-EA but do not see this annotation and Google also did not
help.

 

Thanks,

Ashish

 

From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
Sent: Friday, August 22, 2008 12:36 PM
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] File uploads through Jesery

 

Hi Ashish,

 

There are a bunch of examples supplied with Jersey. Probably the closest is
the storage service example that provides a similar Web interface to that of
Amazon S3. But this example does not really deal with large files.

 

You can do streaming upload using a method as follows:

 

  @PUT

  public void upload(@InputStream in) {

     ...

  }

 

 

If you want to do partial uploads then i think you need to define what is
partial (partial GETs are specified by HTTP).

 

One could use the POST method and reuse the Range header that is normally
used as a request header for partial GETs:

 

  @PUT

  public void patialUpload(

     @InputStream in, @HeaderParam("Range") String range ) {

     ...

  }

 

You would need to parse the range header yourself, if you have a class to do
that that has a contructor with a single String argument you can do:

 

  @PUT

  public void patialUpload(

     @InputStream in, @HeaderParam("Range") Range range ) {

     ...

  }

 

 

Another approach could be to specify the range via a URI:

 

  @PUT

  public void upload(@InputStream in) {

     ...

  }

 

  @Path({start}-{end})

  @PUT

  public void partialUpload(@InputStream in,

          @PathParam("start") int start, @PathParam("end") int end) {

     ...

  }

 

The second method is a sub-resource method. So if your URI to upload the
file was:

 

  http://host/myfile

 

then the partial upload could be done at a following URI for 100 bytes
starting at the 10th byte:

 

  http://host/myfile/10-100

 

The fact that the above resources manipulate the same underlying data is not
an issue.

 

Paul.

 

On Aug 22, 2008, at 1:28 AM, Ashish Raniwala wrote:





Hi Paul,

 

I am new user of JERSEY. What you explained here is exactly what I am
looking for. I need to support very large file uploads. Is there any
code/example you can refer me to?

 

My requirement is to support concurrent partial file uploads and file size
can be as large as 10 GB.

 

Thanks,

Ashish

 

From: Paul Sandoz [mailto:Paul.Sandoz_at_Sun.COM]
Sent: Thursday, August 21, 2008 1:03 PM
To: users_at_jersey.dev.java.net
Subject: Re: [Jersey] File uploads through Jesery

 

Hi Kevin,

 

I would avoid embedding large binary files in XML as it either requires them
to be base 64 encoded or using some like MTOM which IMHO is not really
designed to be consumed directly (because to do so breaks the layering of
the XML infoset).

 

One solution is to explicitly use MIME multipart (using say
multipart/form-data or multipart/mixed). The first body part can be the XML
data and the second body part can be the binary file. This is much more
explicit that in the MTOM case and i think is much easier for clients to
produce/consume. You can use the JavaMail API for this, although there is
experimental support for "multipart/form-data" when using @FormParam. We
need to improve this area to make it easier and also improve the streaming
for certain cases.

 

Another solution is to make the resources for the binary file separate from
the meta-data. I think this is especially useful for large files and if you
want to manipulate the meta-data separate from the file itself. It also
means it is possible to support ETag/Last-Modified on the XML and binary
data separately and enable partial GETs of large files.

 

Combining the above it is possible to POST a MIME multipart message to a
resource from which it creates two separate resources, one for the XML and
one for the binary file. This makes it easier to get the XML data separately
from the binary file. A slightly different variant (one that AtomPub
specifies) is to POST the binary file from which some default XML for the
XML resource is created and then can be modified (in AtomPub this is how you
can create media-based Atom entries).

 

Another variant is to POST some XML data from which a ticket URI is created
from which to upload the binary file. if the client does not upload the file
within a certain period the ticket expires and the "transaction" does not
complete.

 

 

There are many ways :-) all much better IMHO than embedding binary data in
XML documents.

 

You can use InputStream as a type for parameters or a return type of a
resource method. You can also use the File type (when used for consuming a
temporary file will be created, when used for producing this is efficient as
it streams the contents of the file).

 

Hope this helps,

Paul.

 

On Aug 21, 2008, at 5:20 AM, Kevin Duffey wrote:






I am curious if there is anyone on the list who has dealt with file uploads
via a REST call. My project will have this need sooner than later and rather
than try to reinvent the wheel, if anyone has already done this, and
wouldn't mind posting there code/thoughts on this subject, I'd appreciate it
very much. Primarily how do we attach a binary/text file to an xml body as
part of a request, then parse it on the other side.

Thanks.