Question(s):
- How can I define Jersey resources and
ExceptionMapper
s in such a way that they only respond to requests for a certain subset of paths? - How can I do this without having to decide ahead of time under what base path I would like to host them later?
- How can do this such that I can create a single
war
from composing libraries that each define resources for a particular base path of the web app?
Background:
I have a Guice + Jersey v1 webapp, that loads two ServletModule
s from two different dependencies (jar
s).
One of them defines resources for rest API endpoints (e.g. @Path("/purchases")
, @Path("/payment-methods")
), the other defines resources for a web UI (e.g. @Path("/")
, @Path("/products")
).
The ServletModule
for the former attempts to tie its Jersey resources to the "/api/"
base path (serve("/api/*").with(GuiceContainer.class, conf);
), while the latter does the equivalent for the "/"
basepath (serve("/*").with(GuiceContainer.class, conf);
)
Both dependencies also define their own Jersey ExceptionMapper
s; The API's ExceptionMapper
s respond with a JSON error object, while the web UI's ExceptionMapper
s generate a HTML response with the help of Freemarker.
However, the result of this combination - where both the API and web UI jars are on the classpath - is that Jersey resources from both dependencies respond to requests that have a path beginning with "/api/" and "/".
E.g. the API resource for /purchases
responds to requests for http://example.com/api/purchases
and http://example.com/purchases
. Similarly, the web UI resource for /products
responds to requests for http://example.com/products
and http://example.com/api/products
.
The fact that Jersey sees two ExceptionMapper
s for the same exception type (e.g. NotFoundException
) makes it pick only one, regardless of what the requested path starts with. In my case, the ExceptionMapper<NotFoundException>
responds to unknown resource requests under both /api/
and /
, which is bad for either part of the app.