users@jersey.java.net

Re: UriBuilder

From: Richard Wallace <rwallace_at_thewallacepack.net>
Date: Mon, 10 Dec 2007 11:47:47 -0800

I actually solved this problem by turning it on its head. My resource
classes now return either Response or Representation objects. A
representation has a single method,

void write(OutputStream out) throws IOException

and I have a RepresentationMessageBodyWriter that calls it. The
Representation object is a specific instance for that resource, so for
the CategoriesResource I have a corresponding CategoriesRepresentation.
The actual representation is build using a call like

CategoriesRepresentation.generate(categories, uriInfo);

In the generate() method, I use an HTML markup builder inspired by this
blog entry,
http://stephan.reposita.org/archives/2007/11/30/the-best-markup-builder-i-could-build-in-java.

This gives me the power of the Java language, but is still pretty easy
to work with and I don't have to worry about lame little typos or
anything like I would with a template system. I've also got it fairly
strongly typed, so, as an example, I can <li> elements can only be
children of <ul> elements and <ul> elements can only have <li> elements
as children.

I probably wouldn't use this for very large documents as it would
require the whole thing to be in memory, much like DOM. But for short
things, like RESTful representations of resources, this is absolutely
perfect.

Rich

Paul Sandoz wrote:
> Marc Hadley wrote:
>> On Dec 7, 2007, at 4:35 PM, Richard Wallace wrote:
>>> Thanks for the info. That's definitely what I'm looking for. Now
>>> the question is, how can I get the UriInfo object in a
>>> MessageBodyWriter?
>>> I've come up with about half a dozen ways that I can do it by using
>>> an interceptor and putting the UriInfo object in a thread local, or
>>> overriding ServletContainer and wrapping the WebApplicationImpl
>>> object to catch the handleRequest() method and stuff the
>>> ContainerRequest in a thread local. Or I could have my objects that
>>> I return from my resource methods be something like a Result object
>>> that wraps the actual response data and the UriInfo object.
>>>
>>> Of those, the last is probably the one that I would be most likely
>>> to pick, but it still seems a bit ugly to me. But if that's what I
>>> gotta do, I guess that's what I gotta do.
>>>
>>> Any other suggestions?
>>>
>> Hmm, I think for now the last of your suggestions is the way to go. I
>> think we may need to revisit MessageBodyWriter in JSR 311 so such
>> things can be accessed.
>>
>
> As part of Jersey 0.6 the instances of MessageBodyWriter/Reader will
> be part of the WebApplication and then we can enable life-cycle of
> and injection onto those instances (perhaps by modifying the existing
> resource SPI so that it works well with Spring, Guice et. al.).
>
>
> IMHO until then i think probably the cleanest way you can do this
> without modifying the application code is to:
>
> 1) Add a method on WebApplication to inject web application specific
> stuff on an object (it is already in the implementation)
>
> 2) Have a property on resource config that specifies a factory to get a
> singleton object with fields to inject thread local guarded stuff to
> (just like on a resource class);
>
> 3) Extend ServletContainer to override initiate (but calling
> super.initiate first) and then call WebApplicationInject on the
> factory singleton obtained from the resource config property.
>
> then the instances of the MessageBodyWriter can get access to the
> factory singleton and the injected fields.
>
> I am happy to make any such modifications if they can make it easier
> for you in the interim period of now and the 0.5 release, before we
> resolve this properly.
>
> Paul.
>
>> Marc.
>>
>> ---
>> Marc Hadley <marc.hadley at sun.com>
>> CTO Office, Sun Microsystems.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>