Will JAX-RS / Jersey inheritance inherit honor?

Say I want the following URLs to be represented by my JAX-RS / Jersey app:

http://myapp.example.com/app/fizz http://myapp.example.com/app/buzz http://myapp.example.com/app/foo http://myapp.example.com/app/bar 

Say I want /app be the parent base resource, and /app/* be the "child" resources. Will the following URL strategy I'm looking for (?):

 @Path('/app') @Produces(MediaType.APPLICATION_JSON) public abstract class AppResource { // Whatever... } @Path('/fizz') // <--- right here, will FizzResource live at /app/fizz? @Produces(MediaType.APPLICATION_JSON) public class FizzResource extends AppResource { // Whatever... } 

Will FizzResource display in /app/fizz or just /fizz ?

+7
source share
3 answers

Will FizzResource exposed on /app/fizz or just /fizz ?

Short answer

FizzResource will be exposed on /fizz .

Long answer

To quote JSR 339 (section 3.6 on annotation inheritance):

If the subclass or implementation method has any JAX-RS annotations, then all annotations for the superclass or interface method are ignored.

The specification also reads:

To meet other Java EE specifications, it is recommended that you always repeat annotations, rather than relying on inheritance of annotations .

Subresource Creation

The JAX-RS / Jersey documentation explains how to create subresources:

@Path can be used in classes, and such classes are called root resource classes.

@Path can also be used in resource root class methods. This allows you to combine common functions for a number of resources and potentially reuse them.

The first @Path method can be used for resource methods, and such methods are called subresource methods .

To create subresources do the following:

 @Path("/app") public class YourHandler { @Produces(MediaType.APPLICATION_JSON) public String yourHandlerForApp() { // This method is be exposed at /app } @Path("/fizz") @Produces(MediaType.APPLICATION_JSON) public String yourHandlerForAppSlashFizz() { // This method is be exposed at /app/fizz } } 
+16
source

I do not think that the answers given are the best for the initial statement of the problem.

He wants to have his sub-resources in separate classes. This is understandable and admirable, because not doing it would mean putting all its endpoints in one class, which would be huge.

If all the endpoints on this port start with /app , then I think the best way to do this is to configure your filter to fit in your @ApplicationPath .

If this is not the case when all endpoints start with the same prefix, you will have to use this JAX-RS subresource style, where you specify @Path but not the HTTP method annotation ( @GET , etc.) And return instance of the resource you want to delegate:

 @Path("/app") public class AppResource { @Context UriInfo uriInfo; @Path("fizz") public FizzResource getItemContentResource() { return new FizzResource (); } } @Produces(MediaType.APPLICATION_JSON) public class FizzResource extends AppResource { // Whatever... } 

This use of resources is provided in the JAX-RS documentation .

You can also have all your subresources declare their paths as

  @Path(BASE_URL + "/fizz") 

Where BASE_URL is a static string, but I would try to avoid this, because using a not-so-constant parameter for @Path seems to cause problems for every JAX-RS IDE plugin I came across. They cannot figure out the actual path, so they give up. Thus, you may lose the ability to have a “JAX-RS view” that allows you to visualize / move JAX-RS resources along paths.

+1
source

Do you want to

 @Path("/app") public class YourHandler { @Path('/') @Produces(MediaType.APPLICATION_JSON) public String yourHandlerForApp() { // Whatever... } @Path('/fizz') // <--- right here, will FizzResource live at /app/fizz? @Produces(MediaType.APPLICATION_JSON) public String yourHandlerForAppSlashFizz() { // Whatever... } } 
0
source

All Articles