users@jersey.java.net

Re: [Jersey] Nested hierarchies of arbitrary depth

From: Craig McClanahan <Craig.McClanahan_at_Sun.COM>
Date: Thu, 25 Jun 2009 11:31:37 -0700

Marc Hadley wrote:
> On Jun 25, 2009, at 9:45 AM, Christopher Piggott wrote:
>
>> What is the best way in jersey to handle hierarchies of arbitrary
>> depth?
>
> Sounds like a "sub-resource locator" is what you are looking for, see:
>
> https://jsr311.dev.java.net/nonav/releases/1.0/spec/spec3.html#x3-310003.4.1
>
>
>> For example:
>>
>> I have a widget
>> a widget can have subwidgets
>> subwidgets can also have subwidgets
>> subwidgets can have components (but they are the bottom of the tree)
>>
>> So I might want to find:
>> /widget/1212/subwidget/17/component/3414
>>
>> or
>>
>>
>> /widget/12321/subwidget/235235/subwidget/234525/subwidget/234525/component/315
>>
>>
>> My intuition says that I would do this with a @Path that somehow
>> delegated to a new instance of the subresource (and so on) as it went
>> along, recursively. I just can't quite see how to put it together.
>>
> Something along these lines:
>
> @Path("widget/{widgetid}")
> public class WidgetResource {
>
> @GET
> ...
>
> @Path("subwidget/{subwidgetid}")
> SubWidgetResource getSubWidget(@PathParam("subwidgetid") String id)
> return new SubWidgetResource(id);
> }
> }
>
> public class SubWidgetResource {
>
> @GET
> ...
>
> @Path("subwidget/{subwidgetid}")
> SubWidgetResource getSubWidget(@PathParam("subwidgetid") String id)
> return new SubWidgetResource(id);
> }
> }
>
> Essentially getSubWidget returns a new instance of a resource class to
> handle the relative path "subwidget/{subwidgetid}" and that can
> recurse as deep as required.
>
I agree with Marc's suggested approach, but would just like to highlight
one issue that bites a lot of people the first time they use
sub-resource classes like this ... annotation-based injection into the
sub-resource class does *not* work on constructor parameters or instance
variables in the sub-resource class. The reason for this is that the
container didn't create the new sub-resource instance (the locator
method did), so it has no way to track it's lifecycle or perform the
injections.

The pattern I've followed on sub-resource classes is to do what Marc did
in his example here -- explicitly pass on anything you will need as
parameters to the sub-resource constructor. (In DI terms, you're
effectively using constructor injection). That applies not only to path
parameters (as was the case here), but other things that JAX-RS might
have injected into the root resource class, but needs to be passed on.

You don't have to worrry about injections to method parameters in the
sub-resource class ... those all work as expected. It's just the things
you might try to annotate on the constructor (or directly on instance
variables) that are at issue.
> HTH
> Marc.
>
Craig

>
>> --Chris
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>