Discussion:
Equivalent of a Servlet Filter for Jersey / JAX-RS / REST resources?
a***@public.gmane.org
2012-01-05 06:11:46 UTC
Permalink
In a regular Web Application, I can assign a chain of Filters to
various paths for aspects such as Authentication, Authorization,
Errors, Logging and more.

The advantage is that I write servlets to focus on core functionality
without worrying about infrastructure aspects. I can write orthogonal,
cross-cutting Filters to authenticate, authorize, etc. Then I can weave
them in web.xml. Looking at web.xml is enough to assure me that there
are no holes in my application.

Is this possible in JAX-RS or Jersey? If not, what is my best bet?
Marshall Pierce
2012-01-05 07:36:32 UTC
Permalink
Post by a***@public.gmane.org
In a regular Web Application, I can assign a chain of Filters to
various paths for aspects such as Authentication, Authorization,
Errors, Logging and more.
The advantage is that I write servlets to focus on core functionality
without worrying about infrastructure aspects. I can write orthogonal,
cross-cutting Filters to authenticate, authorize, etc. Then I can weave
them in web.xml. Looking at web.xml is enough to assure me that there
are no holes in my application.
Is this possible in JAX-RS or Jersey? If not, what is my best bet?
There are a few different ways that I know of to do filtering in Jersey
(not part of the JAX-RS standard). The way you register your filter
implementations varies depending on how you're hosting Jersey (as a
regular servlet configured in web.xml, inside Guice Servlet, etc).

1. You can register implementations ContainerRequestFilter and
ContainerResponseFilter. This is suitable for filtering tasks that
aren't specific to an individual JAX-RS resource. You do not get access
to information about which specific AbstractResourceMethod is invoked.
This class of filter is useful for app-wide tasks like inspecting
authentication credentials.

2. ResourceFilterFactory is a mechanism by which filtering can be
customized for each resource method. Your implementation can create
Container[Request|Response]Filter instances (via ResourceFilter) that
are specific to each AbstractMethod. AbstractMethod (and its various
subclasses) provide easy access to the java.lang.Class of the resource,
etc. This is used by
com.sun.jersey.api.container.filter.RolesAllowedResourceFilterFactory to
look for JSR-250 annotations on classes or methods and to permit or
allow requests as appropriate.

3. ResourceMethodDispatchAdapter lets you wrap
ResourceMethodDispatchProvider implementations. This gives you the
opportunity to wrap the actual invocation of the resource method the way
javax.servlet.Filter lets you. It's a little more awkward to use than
servlet filters out of the box, but I didn't have any trouble building
up a little infrastructure to allow easy registration of generic servlet
filter-style classes.

InstrumentedResourceMethodDispatchAdapter in
https://github.com/codahale/metrics/tree/master/metrics-jersey/src/main/java/com/yammer/metrics/jersey
uses this approach to get timing information.


Check out the implementations of those various interfaces that come
bundled with Jersey for more ideas on how to use them.

-Marshall
Tatu Saloranta
2012-01-05 18:32:15 UTC
Permalink
Post by a***@public.gmane.org
In a regular Web Application, I can assign a chain of Filters to
various paths for aspects such as Authentication, Authorization,
Errors, Logging and more.
The advantage is that I write servlets to focus on core functionality
without worrying about infrastructure aspects. I can write orthogonal,
cross-cutting Filters to authenticate, authorize, etc. Then I can weave
them in web.xml. Looking at web.xml is enough to assure me that there
are no holes in my application.
Is this possible in JAX-RS or Jersey? If not, what is my best bet?
Aside from JAX-RS hooks, perhaps you should do this at "plain old
Servlet" level -- JAX-RS is hooked via Servlet API, and many of
cross-cutting concerns may be easier to tackle at that level.

-+ Tatu +-
a***@public.gmane.org
2012-01-05 23:13:22 UTC
Permalink
Thank you Marshall and Tatu for your excellent responses! :-)

I had an additional idea last night, which seems to have the benefit of
being JAX-RS standard:

The constructor for a Resource is ordinarily invoked on a per-request
basis prior to any method that handles a request for it, yielding way
to hook in-bound filter logic at a coarser granularity than a method
(but finer than a urlPatterns specification).

When a Resource constructor is not invoked on a per-request basis, it
is because a method of another Resource is responsible for its
lifecycle, and the constructor for that Resource is invoked on a
per-request basis. Also, in this case the method itself which is
managing the lifecycle for the Resource is itself another hook for
filter logic (both in-bound and out-bound) at a granularity coarser
than a method but finer than a urlPatterns specification.

Any opinion on this approach?
Marshall Pierce
2012-01-06 10:07:53 UTC
Permalink
Post by a***@public.gmane.org
Thank you Marshall and Tatu for your excellent responses! :-)
I had an additional idea last night, which seems to have the benefit of
The constructor for a Resource is ordinarily invoked on a per-request
basis prior to any method that handles a request for it, yielding way
to hook in-bound filter logic at a coarser granularity than a method
(but finer than a urlPatterns specification).
When a Resource constructor is not invoked on a per-request basis, it
is because a method of another Resource is responsible for its
lifecycle, and the constructor for that Resource is invoked on a
per-request basis. Also, in this case the method itself which is
managing the lifecycle for the Resource is itself another hook for
filter logic (both in-bound and out-bound) at a granularity coarser
than a method but finer than a urlPatterns specification.
Any opinion on this approach?
It's not necessarily the case that a resource constructor not being
invoked on a per-request basis is a sign of a subresource locator or
other atypical lifecycle. You may wish for performance reasons to have a
singleton instance of a resource that is re-used for every request.

Using the constructor as a means of applying filtering logic seems
somewhat awkward, and it's not where I would expect to find filters.
Also, it looks like you can't throw WebApplicationException from a
resource class constructor as a way to reject a request; it just ends up
as a 500. (This is using Guice; not sure about what happens when using
Jersey's IoC.)

Seems to me that your options for class-wide filtering are either to
have some boilerplate at the top of every resource method or to annotate
the class and use a ResourceFilterFactory that looks for classes with
that annotation.

a***@public.gmane.org
2012-01-06 09:07:26 UTC
Permalink
I'm not sure my thanks in my earlier post made it to the list. I
really appreciate the thorough answer Marshall, and thanks Tatu for the
icing on the cake :-)
Loading...