[jax-rs-spec users] [jsr339-experts] Re: Example 3: Why current ReaderInterceptors are cool.

From: Sergey Beryozkin <>
Date: Fri, 27 Apr 2012 12:43:52 +0100

On 27/04/12 09:35, Sergey Beryozkin wrote:
> Hi Bill
> It's a good example,
> On 26/04/12 23:23, Bill Burke wrote:
>> Here's "Example 3" where a ClientResponseFilter and a ReaderInterceptor
>> work beautifully together. This also shows why you might want to allow a
>> ReaderInterceptor the ability to return a java.lang.Object.
>> -- Example 3: Client-side Caching --
>> Flow:
>> 0. Application code calls:
>> Response response = target.request().get();
>> 1. ClientRequestFilter find that the request URL is cached, but the
>> cache may have expired
>> 2. ClientRequestFilter adds If-None-Match, If-Modified-Since headers and
>> does a conditional GET
>> 3. ClientResponseFilter processes the response.
>> 4. ClientResponseFilter finds that cached entity is still valid.
>> 5. ClientResponseFilter updates cache entry with any new Cache-Control
>> metadata
>> 6. ClientResponseFilter sets the response InputStream to the raw
>> representation of the resource (a gzipped XML document in this case)
>> 6. ClientResponseFilter adds Content-Type header and changes Response
>> code to 200.
>> 7. ClientResponseFilter adds the cache entry to the its context's
>> property map so that the ReaderInterceptor can reference it.
>> 7. Application code calls:
>> Foo foo = response.getEntity(Foo.class);
>> 8. Caching ReaderInterceptor pulls the cache entry from context property
>> map
>> 9. Caching ReaderInterceptor asks the cache entry if it has ever
>> unmarshalled Foo.class. If it has, it returns it. Done. *THIS IS AN
>> totally bypasses the MBR.
>> 10. Caching ReaderInterceptor just proceeds to the next ReaderInterceptor
>> 11. GZIP ReaderInterceptor sees that the cached InputStream is gzip
>> encoded by seeing a Content-Encoding header. It wraps the InputStream.
>> 12. MBR unmarshalls the GZIPPED XML Document.
> Why steps 8-11 can not be made before response.getEntity() ?

I can see that MBR can be bypassed by the caching interceptor, however
the whole process requires the coordination between filters,
interceptors and finally MBRs and I wonder if it can be avoided.

I'd consider exploring the possibility of making all the post-processing
of the response completed before the Application calls
response.getEntity() and having a composite MBR (the one relying on
JAX-RS Providers) which would act as the cache and delegating to
providers for reading if the entity is not available.

Would that work ? MBRs can see the response headers which the filters
must've already updated. It may be limiting in that a number of other
properties may not be passed in a standard way between filters & MBRs
but here Response.getProperties() discussed in the other thread would be
very handy

> What if at step 7 (actually has to be 8), we have
> response.getEntity(InputStream.class) ?or

The other thing I've thought about, would the interceptors and I guess
response filters would need to be re-winded in this example if MBR
throws the exception, for them to clear the entries ?


> Cheers, Sergey

Sergey Beryozkin
Talend Community Coders