users@jersey.java.net

Re: [Jersey] Jersey 1.0.1: getMatchedResources and actual resources

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 05 Feb 2009 16:53:31 +0100

On Feb 5, 2009, at 4:08 PM, Wilhelmsen Tor Iver wrote:

>
>> What "fields" are you referring to? fields on VacationDays or fields
>> on Employee? or do you mean method parameters?
>
> Fields of the Employee object, yes.
>
>> What "get()" method are you referring to? Employee.get() or
>> VacationDays.get()?
>
> The Employee get method.
>
>> I presume your URI path is something like "/employee/1/vacationdays"
>> thus the Employee.get() will never be called because the URI
>> does not
>> point to the correct resource it points to the vacation days
>> resource.
>
> getMatchedResource() returns a list of resource objects with the
> correct
> types involved in the resource path, but not "resolved"; perhaps my
> mistake was not invoking get) manually on the Employee object in order
> to get the data object the resource represents... My confusion ws
> probably triggered by the mistake of having the resource classes
> extend
> the bean classes, which I have dropped now.
>
>> In the method Employee.getVacationDays() do you want to pass
>> the value
>> of the "id" path param to VacationDays?
>
> Well, I was expecting to find it in the list from
> getMatchedResources(),
> but perhaps I misread the following javadocs:
>

No, the path id will be accessible from the method:

   UriInfo.getPathParameters()

and the matched paths are accessible from the method:

   UriInfo.getMatchedURIs()

It will only be accessible if you do the following:


@Path("/employee/{id}")
@Produces("application/xml")
public class Employee extends EmployeeBean {

         public String id;

         public Employee(@PathParam("id") String id) {

             this.id = id;

         }

         @GET
         public Response get(@PathParam("id") String id, @Context
UriInfo info) { ... }

         @Path("vacationdays")

         public VacationDays getVacationDays() {

                 return new VacationDays();
         }

}

public class VacationDays extends VacationDaysBean {

         @GET
         public Response get(@Context UriInfo info) {
                 List<Object> res = info.getMatchedResources();
                 VacationDaysBean ret = null;
                 if (res != null && res.size() > 0) {
                         Object obj = res.get(res.size() - 1);
*** if (obj instanceof Employee) {

                               String id = ((Employee)obj).id

                           }


The declaration of "@PathParam("id") String id" on a resource method
will result in that somehow being automatically associated with a
field of the class.


> http://www.jboss.org/file-access/default/members/resteasy/freezone/docs/
> 1.0.0.GA/javadocs/javax/ws/rs/core/UriInfo.html#getMatchedResources()
>
> The following also seems to indicate that the actual Employee object
> is
> supposed to be resolved first
>
> http://www.jboss.org/file-access/default/members/resteasy/freezone/docs/
> 1.0.0.GA/userguide/html/JAX-
> RS_Resource_Locators_and_Sub_Resources.html
>
> Or is this a difference between how Sun and JBoss interpret the spec?

No, the fact that your:

   Employee.getVacationDays()

was called means Jersey instantiated the Employee class (and then put
it in the matched list).


>
> Note: I have not yet tried to plug in RestEasy or CXF instead.
>
>
>> 2) by reusing @PathParam in the VacationDays.get method:
>>
>> @GET
>> public Response get(@PathParam("id") String id, @Context
>> UriInfo info) {
>
> Probably the best approach, yes (though I used constructors) if we
> later
> decide current sub-resources should move elsewhere in the resource
> hierarchies.
>
>> In sub-resource locators it is the responsibility of the application
>> to instantiate a resource class. Jersey will not inject onto
>> constructors or fields of the instance returned.
>
> I was instantiating it, but when it is later used then the resource
> path
> seems absent...
>
> I solved the problem by passing the id down the "pipe" and returning
> (thus configured) resource objects in the @Path-annotated methods. So
> now I have:
>
> Employees.java: Root resource for /employees, handles queries and {id}
> resources
> Employee.java: Is the type used for /employees/{id}, id passed in
> constructor, handles vacationdays sub-resource, get method returns
> EmployeeBean
> VacationDays: Type used for Employee's vacationdays, id passed in
> constructor, get method returns VacationDaysBean
>
> Thanks for the help! I am getting somewhere now... :)
>

OK, Great!

Paul.