users@jersey.java.net

[Jersey] Re: Sub-resource addressed by only one path segment?

From: Jim Danz <jim_at_likeness.com>
Date: Wed, 12 Jun 2013 14:13:50 -0700

Hi Mira,

Thanks for your response, and for the workaround tip. We are still on
Jersey 1.16, so it looks like that's the explanation.

Cheers,
Jim

On Tue, Jun 11, 2013 at 1:08 AM, Miroslav Fuksa
<miroslav.fuksa_at_oracle.com>wrote:

> Just a note. I have not implemented and tested the proposed solution
> below. So, there might be any problems with this proposal which I currently
> don't see but it might be worth to try.
>
> Mira
>
>
>
> On 06/11/2013 09:56 AM, Miroslav Fuksa wrote:
>
>> Hi Jim,
>>
>> which Jersey version you are using?
>>
>> In Jersey 2 this should be possible, you can have sub resource locators
>> with empty path:
>>
>> @Path("/")
>> public EntityCollectionsListResource get() {
>> return listResourceFactory.**createForCommunityListContext(**);
>> }
>>
>> In Jersey 1.x this looks like such a construction does not work. Your sub
>> resource locator method is not even called when it has empty path.
>>
>> So, if you use Jersey 1, you might implement something like this:
>>
>> @Path("/community-list")
>> public static class CommunityListResource {
>> ....
>>
>> @GET
>> public String get() {
>> return ....
>> }
>>
>> @Path("{id}/list")
>> public CommunityListResource locator() {
>> // here check the UriInfo.getMatchedURIs() and if we are already
>> in /community-list/{id}/list throw
>> // WebApplicationException with 404 code.
>>
>>
>> return listResourceFactory.**createForCommunityListContext(**);
>> }
>>
>> }
>>
>> So, you would return the same class from the sub resource locator and if
>> you are already in "sub resource" then return 404 by
>> WebApplicationException. I am not saying this is nice solution but could
>> help.
>>
>> Mira
>>
>> On 06/11/2013 01:17 AM, Jim Danz wrote:
>>
>>> Hi folks,
>>>
>>> I am wondering if I can have a sub-resource with only one path segment.
>>>
>>> Specifically, I am trying to have a scheme where there is a
>>> subresource EntityCollectionsListResource that is listening on:
>>> /user/{id}/list
>>> and
>>> /community-list
>>>
>>> I was able to wire the /user/{id}/list portion of this without trouble.
>>> I'm having trouble with the community-list portion.
>>>
>>> My community list resource looks like:
>>> @Path("/community-list")
>>> public class CommunityListResource {
>>> private final EntityCollectionsListResourceF**actory
>>> listResourceFactory;
>>>
>>> @Inject
>>> CommunityListResource(**EntityCollectionsListResourceF**actory
>>> listResourceFactory) {
>>> this.listResourceFactory = listResourceFactory;
>>> }
>>>
>>> @Path("/")
>>> public EntityCollectionsListResource get() {
>>> return listResourceFactory.**createForCommunityListContext(**);
>>> }
>>> }
>>>
>>> Where EntityCollectionsListResource has, among other things:
>>> @PUT
>>> @GET
>>> @Path("/{listIdentifierParam}"**) @GET
>>>
>>> The subpaths in EntityCollectionsListResource work fine. For instance,
>>> GET /community-list/Foo
>>> ==> 200
>>>
>>> But a plain
>>> GET /community-list
>>> ==> 405
>>>
>>> And likewise:
>>> GET /community-list/
>>> ==> 405
>>>
>>> I've stepped through the debugger, and it looks like "/community-list"
>>> alone doesn't even get to the EntityCollectionsListResource. It gets
>>> stuck at the CommunityListResource, in that the after match
>>> "/community-list" it has only empty string remaining in path, and then
>>> it refuses to match on "/".
>>>
>>> So, I'd like to ask: is there any way to have a subresource with only
>>> a single path statement that addresses it? I can change
>>> CommunityListResource to the following:
>>> @Path("/community-list")
>>> public class CommunityListResource {
>>> private final EntityCollectionsListResourceF**actory
>>> listResourceFactory;
>>>
>>> @Inject
>>> CommunityListResource(**EntityCollectionsListResourceF**actory
>>> listResourceFactory) {
>>> this.listResourceFactory = listResourceFactory;
>>> }
>>>
>>> @Path("/community-list")
>>> public EntityCollectionsListResource get() {
>>> return listResourceFactory.**createForCommunityListContext(**);
>>> }
>>> }
>>>
>>> And everything works fine on /community-list/community-**list, but it's
>>> not the URL structure that I'd hoped for.
>>>
>>> Many thanks,
>>> Jim
>>>
>>
>>
>