You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Jeff Wang <je...@plutom.com> on 2011/12/05 11:55:28 UTC
JAX-RS Annotations and path resolution
1) I have 2 service classes with the following annotations:
@Path("/user/{userId}")
public class Foo {
@GET
@Path("/fooResourceA")
public FooResourceA fooResourceA();
@GET
@Path("/fooResourceB")
public FooResourceB fooResourceB();
}
@Path("/user/{userId}")
public class Bar {
@GET
@Path("/barResourceA")
public BarResourceA barResourceA();
@GET
@Path("/barResourceB")
public BarResourceB barResourceB();
}
When a request comes in the form of /user/1/barResourceA, the Bar
service class never gets checked for pattern match, and the client
gets a 404. Is this working as intended? I'm assuming I should stop
being lazy and create separate service classes for fooResourceA, etc.
with a class level @Path of "/user/{userId}/fooResourceA", etc.?
2) In the examples at
http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Subresourcelocators,
what is the order of methods called on the deepest call?
(http://localhost:9000/customerservice/orders/223/products/323/items)
If, like the document implies, the call is a)
customerService.getOrder(orderId) and then b)
order.getItems(productId), then that's not a good thing, right?
because getItems(productId) returns "this", which is an object of type
Order, while presumably we're trying to get items?
Does the example actually want to remove the 2 getItems methods from
the Order object, have a Product object, and have items be a
sub-resource of Product? Or is this example trying to illustrate an
example that I have not yet understood?
3) While sub-resources are easy/good for GETs, what about
POST/PUT/DELETE? the usual getters and setters don't take care of
that very well, so we're going to have 4 methods per sub-resourced
field? Is that the usual usage, to put some object lifecycle
management methods into your POJO?
4) In a recent answer, you had the following code:
@Path("/fleets")
@Component
public class FleetResource {
@Autowired
BusResource busResource
@Path("/{fleet_id}/busses")
public BusResource getBusses() {
return busResource;
}
}
Is there somewhere that this functionality is documented (or where I
can look at the code?) The only way that I saw to do sub-resources
were to annotate in the POJO, but it looks like you can use a returned
@Component to have CXF continue resolving? For example, assuming like
you previous answer, that BusResource is annotated with a class level
@Path("/busses"). would a method level annotation of
@Path("{bus_Id)") be able to match /fleets/5/busses/1?
thanks!
Jeff Wang
Re: JAX-RS Annotations and path resolution
Posted by Sergey Beryozkin <sb...@gmail.com>.
On 06/12/11 10:11, Jeff Wang wrote:
> Ok, I think I'm getting away from what I'm trying to accomplish, which
> is to figure out the best way to annotate sub-resources. Currently, I
> have foo, which is a sub-resource of bar. so I'd like to GET
> /bar/1/foo for the list of Foos that bar 1 has. or POST /bar/1/foo to
> create a new foo. or GET /bar/1/foo/3, to get foo 3.
>
> Currently, I have created two separate service beans, have with a
> class level @PATH annotation of "/bar" and "/bar/{barId}/foo"
> respectively, and individual @PATH additions as required (for fooId
> and barId as appropriate.
>
> Right now, Bar, the POJO has a very simple JPA and XML mapping.
> @XMLRootElement
> @Entity
> public class Bar {
> @Column(name="fooId")
> public Foo;
> }
>
> (getters, setters, and other fields removed.) How would a equivalent
> mapping be expressed in a sub-resource locator? Would it be actually
> easier to read?
>
Not sure if it answers your question, here is one example:
@Path("bar/{id}/foo")
public class BarResource {
@GET
public Foos getFoos(@PathParam("id") int id) {}
@POST
public void addFoo(Foo foo) {}
// optional: @GET
@Path("{fooid}")
public Foo getFoo (@PathParam("id") int id, @PathParam("fooid") int
foo_id) {}
}
Additionally you can have a "/bar" path on a Bar itself and register it
as another root resource, or push the above "{id}/foo" to the 3 existing
methods and a GET which will return Bar - that would cover /bar only
Cheers, Sergey
> thanks
> Jeff Wang
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com
Re: JAX-RS Annotations and path resolution
Posted by Jeff Wang <je...@plutom.com>.
Ok, I think I'm getting away from what I'm trying to accomplish, which
is to figure out the best way to annotate sub-resources. Currently, I
have foo, which is a sub-resource of bar. so I'd like to GET
/bar/1/foo for the list of Foos that bar 1 has. or POST /bar/1/foo to
create a new foo. or GET /bar/1/foo/3, to get foo 3.
Currently, I have created two separate service beans, have with a
class level @PATH annotation of "/bar" and "/bar/{barId}/foo"
respectively, and individual @PATH additions as required (for fooId
and barId as appropriate.
Right now, Bar, the POJO has a very simple JPA and XML mapping.
@XMLRootElement
@Entity
public class Bar {
@Column(name="fooId")
public Foo;
}
(getters, setters, and other fields removed.) How would a equivalent
mapping be expressed in a sub-resource locator? Would it be actually
easier to read?
thanks
Jeff Wang
Re: JAX-RS Annotations and path resolution
Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi
On 05/12/11 10:55, Jeff Wang wrote:
> 1) I have 2 service classes with the following annotations:
> @Path("/user/{userId}")
> public class Foo {
> @GET
> @Path("/fooResourceA")
> public FooResourceA fooResourceA();
>
> @GET
> @Path("/fooResourceB")
> public FooResourceB fooResourceB();
> }
>
> @Path("/user/{userId}")
> public class Bar {
> @GET
> @Path("/barResourceA")
> public BarResourceA barResourceA();
>
> @GET
> @Path("/barResourceB")
> public BarResourceB barResourceB();
> }
>
> When a request comes in the form of /user/1/barResourceA, the Bar
> service class never gets checked for pattern match, and the client
> gets a 404. Is this working as intended? I'm assuming I should stop
> being lazy and create separate service classes for fooResourceA, etc.
> with a class level @Path of "/user/{userId}/fooResourceA", etc.?
>
It is working as expected given that both resource classes are equal
candidates and no another resource class is selected after the check on
the initially selected resource has been completed,
you can customize it by registering a custom comparator:
http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Customselectionbetweenmultipleresources
or experiment with @Path annotations such that both resources have
non-matching path values. Or may be update Foo to delegate to Bar via
a subresource locator mechanism
> public class Foo {
> @GET
> @Path("/fooResourceA")
> public FooResourceA fooResourceA();
>
> @GET
> @Path("/fooResourceB")
> public FooResourceB fooResourceB();
@Path("/")
public Bar getBar() {
}
> }
> 2) In the examples at
> http://cxf.apache.org/docs/jax-rs-basics.html#JAX-RSBasics-Subresourcelocators,
> what is the order of methods called on the deepest call?
> (http://localhost:9000/customerservice/orders/223/products/323/items)
> If, like the document implies, the call is a)
> customerService.getOrder(orderId) and then b)
> order.getItems(productId), then that's not a good thing, right?
> because getItems(productId) returns "this", which is an object of type
> Order, while presumably we're trying to get items?
>
I guess that example is too complex but when I typed it awhile back I
did not think about it :-)
> Does the example actually want to remove the 2 getItems methods from
> the Order object, have a Product object, and have items be a
> sub-resource of Product? Or is this example trying to illustrate an
> example that I have not yet understood?
>
when we have
http://localhost:9000/customerservice/orders/223/products/323/items
http://localhost:9000/customerservice/orders/223 will return an Order
which links to a Product this Order relates somehow to
and also it keeps list of presumably Product Items, so after we've got
an Order, products/323/items will lead to
a subresource locator which happens to be this very Order which will
have a @GET for Items,
it's a bit over-complex :-), but I guess that some realistic data
services/structures can be complex as well
> 3) While sub-resources are easy/good for GETs, what about
> POST/PUT/DELETE? the usual getters and setters don't take care of
> that very well, so we're going to have 4 methods per sub-resourced
> field? Is that the usual usage, to put some object lifecycle
> management methods into your POJO?
>
Subresource is simply a utility class whose job is to offload some of
the processing from the root resource.
It's really depends on the application, whether a single subresource
instance is reused or a new one is created per every request
> 4) In a recent answer, you had the following code:
> @Path("/fleets")
> @Component
> public class FleetResource {
>
> @Autowired
> BusResource busResource
>
> @Path("/{fleet_id}/busses")
> public BusResource getBusses() {
> return busResource;
> }
> }
>
> Is there somewhere that this functionality is documented (or where I
> can look at the code?) The only way that I saw to do sub-resources
> were to annotate in the POJO, but it looks like you can use a returned
> @Component to have CXF continue resolving? For example, assuming like
> you previous answer, that BusResource is annotated with a class level
> @Path("/busses"). would a method level annotation of
> @Path("{bus_Id)") be able to match /fleets/5/busses/1?
>
CXF does not work with @Component annotation, it is Jersey which relies on it
Cheers, Sergey
> thanks!
> Jeff Wang
--
Sergey Beryozkin
Talend Community Coders
http://coders.talend.com/
Blog: http://sberyozkin.blogspot.com