users@jersey.java.net

Re: [Jersey] Hello World! and Welcome to jersey-multipart

From: Jeff Schmidt <jas_at_535consulting.com>
Date: Thu, 23 Oct 2008 21:15:45 -0600

Thanks for your thoughts on that Craig. I feel better about going
this route. :)

Cheers,

Jeff

On Oct 23, 2008, at 5:51 PM, Craig McClanahan wrote:

> Jeff Schmidt wrote:
>> Thanks Craig! This all sounds good.
>>
>> I guess my client side question was more generic. Potential clients
>> may be using Java, Python, Ruby etc. and whatever related
>> libraries. I don't know if issuing multi-part requests is unusual
>> or difficult in general for such clients. I don't want to put up
>> anymore barriers to entry to use the API then I have to. :)
> Agreed -- this is one of the nicest things about REST.
>> What has been your experience in this regard? Any complaints from
>> clients?
>>
> Constructing a multipart request is actually very easy, with pretty
> much any client language and HTTP framework. From the point of view
> of such a framework, it's a single request of type "multipart/
> mixed" (or whatever), and the interesting part of the problem is
> constructing the message body. For that, it's mostly a matter of
> alternating between a bunch of headers and content for each body
> part, with a little extra glue for the "boundary" string. In jersey-
> client, the code that does this is in MultiPartWriter.java, and as
> you can see it is pretty straightforward (assuming your library
> already has a way to format the request body for your data entity --
> which is the same code you'd need to send that body part by itself).
>
> Parsing a multipart response, on the other hand, is somewhat more
> complicated. In the case of jersey-multipart I punted :-) and used
> JavaMail APIs, because systems that understand mail streams already
> have to know how to do this. If you use a different Java HTTP
> library you can still use JavaMail for this part; in other
> languages, I'd start by looking for parsing libraries that already
> exist, and then just glue them in to the client.
>
> One of my upcoming tasks will be to create a Ruby client library for
> some of the services I'm working on, and that will ultimately
> include some multipart processing -- so I'll soon get to practice
> what I preach above :-).
>
> Craig
>> Cheers,
>>
>> Jeff
>>
>> On Oct 23, 2008, at 1:10 PM, Craig McClanahan wrote:
>>
>>> Jeff Schmidt wrote:
>>>> Hi Craig:
>>>>
>>>> Thanks for your work on jersey-multipart. I have some SOAP based
>>>> endpoints where a request can consist of various XML meta data,
>>>> and then there is an element of type base64Binary where an
>>>> arbitrary file can be 'attached' to the request. I would like to
>>>> do something equivalent in a RESTful manner. It seems like a
>>>> request comprised of an XML entity and a binary entity would be
>>>> the way to go. The JAX-RS resource does not need to understand
>>>> the binary entity, just make it available to some server-side code.
>>> Yep, that is exactly the sort of thing I use it for.
>>>>
>>>> Looking at some of the jersey-multipart code, it looks like I can
>>>> use BodyPart.getEntityAs(MyMetaData.class) to access the XML meta
>>>> data, and BodyPart.getEntity().getInputStream() to access the
>>>> binary data. When I'm done, MultiPart.cleanup() will delete the
>>>> temporary binary file (if > threshold bytes). Am I reading that
>>>> right?
>>>>
>>> That's exactly right.
>>>> Also, I don't know if doing this on the server side will make it
>>>> difficult for clients. You said the jersey-client can easily work
>>>> with jersey-multipart. I've not yet looked into the Commons
>>>> HttpClient or other client libraries to see if they have issues
>>>> with making multipart requests.
>>>>
>>> You can also look at the Jersey client code itself. One of the
>>> really cool things about jersey-client is you can use the same
>>> providers (including the jersey-multipart stuff) on the client
>>> just like you can use it on the server. There's some small
>>> samples of this in the jersey-multipart unit tests.
>>>
>>>> Thanks,
>>>>
>>>> Jeff
>>>>
>>> Craig
>>>
>>>> On Oct 17, 2008, at 12:58 AM, Paul Sandoz wrote:
>>>>
>>>>> Hi Craig,
>>>>>
>>>>> Welcome to the list of Jersey committers :-)
>>>>>
>>>>> Thanks very much for the multipart MIME contribution, it looks
>>>>> really good. I would like to leverage this to improve the
>>>>> support for multipart/form-data and also consider support for
>>>>> Multipart Java Beans.
>>>>>
>>>>> Classes supporting AtomPub support would be great!
>>>>>
>>>>> Re: the cleanup aspect. I think we need to review Jersey's IoC
>>>>> support and integration capabilities with the likes of Spring/
>>>>> Guice. It is really hard to be abstract from an IoC framework :-
>>>>> ( If the returned MultiPart was instantiated in the life-cycle
>>>>> of the request then when the response is about to the sent a pre
>>>>> destroy method could be called to do the clean up. That would
>>>>> not work for the conditions of the client working standalone
>>>>> (perhaps cleanup could also be called before being GC'ed
>>>>> although that cannot be relied upon).
>>>>>
>>>>> Paul.
>>>>>
>>>>>
>>>>> On Oct 17, 2008, at 1:00 AM, Craig McClanahan wrote:
>>>>>
>>>>>> For those who don't know me, I have been around the Java web
>>>>>> tier for quite a while, being the original author of the Struts
>>>>>> framework (<http://struts.apache.org>), as well as co-spec-lead
>>>>>> for JavaServer Faces 1.0 and 1.1. My more recent interests
>>>>>> have focused on RESTful web services, which led me naturally
>>>>>> towards JAX-RS and the Jersey implementation.
>>>>>>
>>>>>> I've been one of the folks inside Sun who has been leveraging
>>>>>> Jersey for some internal projects over the last few months. We
>>>>>> had a particular need to support MIME multipart/* media types,
>>>>>> and it made sense to generalize this into a reusable module --
>>>>>> hence, I've just uploaded the "jersey-multipart" module to the
>>>>>> "contribs" directory. It relies on 1.0 or later Jersey code,
>>>>>> and provides what I hope are found to be elegant solutions to
>>>>>> the problems of multipart handling, while leveraging all the
>>>>>> nice JAX-RS providers support for dealing with the entity
>>>>>> content of body parts, just like we've grown spoiled by on
>>>>>> complete message bodies. And, it works both on the server side
>>>>>> and the client side, when you use jersey-client.
>>>>>>
>>>>>> Example server code to build a multipart response might look
>>>>>> like this:
>>>>>>
>>>>>> // I have also provided an appropriate MessageBodyWriter for
>>>>>> the MyBean class
>>>>>> MyBean bean = ...;
>>>>>> return Response.ok(new MultiPart().
>>>>>> type(new MediaType("multipart", "mixed").
>>>>>> bodyPart("This is the first body part in plain text", new
>>>>>> MediaType("text", "plain")).
>>>>>> bodyPart(bean, new MediaType("x-application", "x-
>>>>>> format"))).build();
>>>>>>
>>>>>> (Of course, you can do things in a more fine-grained fashion,
>>>>>> but the builder pattern utilized all over the JAX-RS and Jersey
>>>>>> APIs was so cool that Paul suggested I use it here too, so I
>>>>>> did :-).
>>>>>>
>>>>>> To read a MultiPart entity (produced by code like the previous
>>>>>> example) that was uploaded to the server you might do something
>>>>>> like this:
>>>>>>
>>>>>> // I have also provided an appropriate MessageBodyReader for
>>>>>> the MyBean class
>>>>>> @Path("...")
>>>>>> @PUT
>>>>>> @Consumes("multipart/mixed")
>>>>>> @Produces(...)
>>>>>> public Response handler(MultiPart multiPart) {
>>>>>> BodyPart part0 = multiPart.getBodyParts().get(0);
>>>>>> String text = part0.getEntityAs(String.class);
>>>>>> BodyPart part1 = multiPart.getBodyParts().get(1);
>>>>>> MyBean bean = part1.getEntityAs(MyBean.class);
>>>>>> ...
>>>>>> multiPart.cleanup();
>>>>>> }
>>>>>>
>>>>>> The need for cleanup() is because the implementation knows how
>>>>>> to buffer "large" body parts to temporary files on disk, so you
>>>>>> don't blow away your JVM heap on a multi-gigabyte upload or
>>>>>> download. I'm looking for a way to avoid the need for the
>>>>>> application to call this, but haven't found one yet -- in the
>>>>>> mean time, everything else about dealing with multipart files
>>>>>> has seemed pretty easy to deal with.
>>>>>>
>>>>>> As mentioned above, this module works on the client side as
>>>>>> well, if you're using jersey-client. The unit tests have some
>>>>>> more worked-out examples of the lower level details.
>>>>>>
>>>>>> Give it a try and see what you think! And, for sure, if you
>>>>>> see anything that needs to be improved, please ask here and/or
>>>>>> file an issue in the issue tracking system.
>>>>>>
>>>>>> Craig McClanahan
>>>>>>
>>>>>> PS: Among my other interests will be working with the Atom
>>>>>> Publishing Protocol support, again with the idea of leveraging
>>>>>> JAX-RS providers to do format translations for custom <content>
>>>>>> payloads.
>>>>>>
>>>>>>
>>>>>>
>>>>>> ---------------------------------------------------------------------
>>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net <mailto:users-unsubscribe_at_jersey.dev.java.net
>>>>>> >
>>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>> <mailto:users-help_at_jersey.dev.java.net>
>>>>>>
>>>>>
>>>>>
>>>>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net <mailto:users-unsubscribe_at_jersey.dev.java.net
>>>>> >
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net <mailto:users-help_at_jersey.dev.java.net
>>>>> >
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Jeff Schmidt
>>>>
>>>>
>> --
>>
>> Jeff Schmidt
>>
>>
>>
>>
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net


--
Jeff Schmidt