Search code examples
javaurljerseyjax-rs

Will JAX-RS/Jersey resource paths honor inheritance?


Say I want the following URLs exposed 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 to be a parent base resource, and /app/* to be "child" resources. Will the following accomplish the 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 the FizzResource be exposed at /app/fizz or just /fizz?


Solution

  • Will the FizzResource be exposed at /app/fizz or just /fizz?

    Short answer

    FizzResource will be exposed at /fizz.

    Long answer

    Quoting the JSR 339 (section 3.6 about Annotation Inheritance):

    If a subclass or implementation method has any JAX-RS annotations then all of the annotations on the superclass or interface method are ignored.

    The specification also says:

    For consistency with other Java EE specifications, it is recommended to always repeat annotations instead of relying on annotation inheritance.

    Creating sub-resources

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

    @Path may be used on classes and such classes are referred to as root resource classes.

    @Path may also be used on methods of root resource classes. This enables common functionality for a number of resources to be grouped together and potentially reused.

    The first way @Path may be used is on resource methods and such methods are referred to as sub-resource methods.

    So, do the following to create sub-resources:

    @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
        }
    }