users@jersey.java.net

Re: [Jersey] Filters

From: Keith R. Davis <keith.davis_at_zunisoft.com>
Date: Thu, 12 Jun 2008 08:45:44 -0600

Stupid question: will this require my existing application to re-factor
existing servlet filters that I am using with 0.7ea?

On Thu, 12 Jun 2008 16:30:43 +0200, Paul Sandoz <Paul.Sandoz_at_Sun.COM>
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
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net