users@jersey.java.net

Re: [Jersey] Filters

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 02 Jul 2008 15:45:21 +0200

Hi,

This is completed in the latest build.

See JavaDoc of:

   com.sun.jersey.spi.container.ContainerRequestFilter
   com.sun.jersey.spi.container.ContainerResponseFilter
   ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS
   ResourceConfig.PROPERTY_CONTAINER_RESPONSE_FILTERS

Filters are components so if you provide reference to classes then they
will get instantiated/injected by the component provider, otherwise if
you provide instances injection will occur.

I have provided a partial implementation for HTTP POST method replacing.
It currently works with the request header "X-HTTP-Method-Override". We
also need to support a query parameter but i need to refactor the
Uri-based support so that it is easy to get access to query parameters
and replace the request URI.

When using servlet you can configure the list of filters in the web.xml
as follows:

<init-param>
<param-name>com.sun.jersey.spi.container.ContainerRequestFilters</param-name>

<param-value>com.sun.jersey.api.container.filter.PostReplaceFilter</param-value>
</init-param>

If you use the same class for a request and response filter then only
one instance will be created thus you can use a thread local field to
store some state from the request filtering to the response filtering.

Paul.

Paul Sandoz wrote:
> Hi,
>
> Now that the container SPI is refactored we can move on to specifying
> filters.
>
> Any filter SPI cannot be stack based (like the Russian doll filter API
> on Jersey client-side) because Jersey server-side needs to be in control
> of the stack (e.g. writing out multiple responses for comet).
>
> The disadvantage of a non-stack-based approach is it means state cannot
> be as easily shared between inbound and outbound filtering. But how
> common is that on the server side?
>
> So i propose the following provider interfaces:
>
> public interface ContainerRequestFilter {
> ContainerRequest filter(ContainerRequest request);
> }
>
> public interface ContainerResponseFilter {
> ContainerResponse filter(ContainerResponse response);
> }
>
> An implementation can throw a WebApplicationException to terminate the
> filter chain prematurely with it's own response.
>
> A provider implementation could consist of:
>
> @Provider
> public class MyFilter
> implements ContainerRequestFilter, ContainerRequestFilter {
> ...
> }
>
> and thus only one instance would be created for both in-bound and
> out-bound filtering, which means thread-local state could be shared.
>
> The next question is how to order/prioritize filters.
>
> I think the application should declare two lists of filter classes, for
> inbound and outbound. This makes it easy to specify using ResourceConfig
> or in the web.xml.
>
> Here is an example of what a transport-based GZIP filter might look like:
>
> @Provider
> public class GZIPFilter
> implements ContainerRequestFilter, ContainerRequestFilter {
>
> ContainerRequest filter(ContainerRequest request) {
> if (transport encoding is GZIP) {
> request.setEntity(new GZIPInputStream(request.getEntity());
> }
> return request;
> }
>
> private static class GZIPWriter
> implements ContainerResponseWriter {
> ContainerResponseWriter crw;
>
> GZIPWriter(ContainerResponseWriter crw) { this.crw = crw; }
>
> OutputStream writeStatusAndHeaders(
> long contentLength,
> ContainerResponse response) throws IOException {
> OutputStream o = crw.writeStatusAndHeaders(contentLength,
> response);
> return new GZIPOutputStream(o);
> }
> }
>
> ContainerResponse filter(ContainerResponse response) {
> if (transport encoding is GZIP) {
> response.setContainerResponseWriter(
> new GZIPWriter(response.getContainerResponseWriter()));
> }
> return response;
> }
> }
>
> We need the above as well as logging, fake PUT/DELETE, URI-based conneg,
> URI C14N with redirection filters.
>
> This is a long shot but it may even be possible to reuse such filters
> specifically targeted at resources.
>
> Paul.
>

-- 
| ? + ? = To question
----------------\
    Paul Sandoz
         x38109
+33-4-76188109