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
?
Will the
FizzResource
be exposed at/app/fizz
or just/fizz
?
FizzResource
will be exposed at /fizz
.
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.
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
}
}
I don't think the answers given are the best for the original problem statement.
He wants to have his subresources in separate classes. That's understandable and admirable because to not do that would mean putting all his endpoints in the same class, which would be huge.
If all endpoints on this port start with /app
then I think the best way to do that is to configure your filter to put it in your @ApplicationPath
.
If it's not the case that all endpoints start with the same prefix, then you will have to use this style of JAX-RS subresources where you specify a @Path
but not an HTTP method annotation (@GET
, etc.) and return an instance of the resource you want to delegate to:
@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 method of doing 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 that because the use of a not-exactly constant parameter to @Path
seems to cause every JAX-RS IDE plugin I've seen problems. They aren't able to compute the actual path, so they give up. So you might lose the ability to have a "JAX-RS View" that allows you to visualize/navigate your JAX-RS resources by the Paths.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With