users@jersey.java.net

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

From: Miroslav Fuksa <miroslav.fuksa_at_oracle.com>
Date: Tue, 11 Jun 2013 10:08:38 +0200

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 EntityCollectionsListResourceFactory
>> listResourceFactory;
>>
>> @Inject
>> CommunityListResource(EntityCollectionsListResourceFactory
>> 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 EntityCollectionsListResourceFactory
>> listResourceFactory;
>>
>> @Inject
>> CommunityListResource(EntityCollectionsListResourceFactory
>> 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
>