jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: [jax-rs-spec users] Heads Up: Severe problem when rewriting responses! Is our Filter API suitable?

From: Jan Algermissen <jan.algermissen_at_nordsc.com>
Date: Thu, 11 Oct 2012 23:36:09 +0200

On Oct 11, 2012, at 11:25 PM, Markus KARG wrote:

> Bill,
>
> thanks for chiming in.
>
>> Markus, in a response filter you can:
>> * change the status
>> * change/add/remove headers
>> * change the Java Object entity (even set it to null)
>> So I don't understand your problem.
>
> the problem is that the response filter (or an interceptor, or a combination
> - I actually don't care as long as it works) must change the entity
> *representation* (the XML, not the Java Object).

Why don't you do everything in an interceptor?

Jan

>
> Example: A JAX-RS resource method produces an XML String (as the filter must
> work with any kind of resource method, let's assume that the filter just
> does not know whether the method returns the String directly, or whether a
> MBW is producing that XML by serializing any kind of Java Object). The
> response filter must modify that XML if the request was sent by a particular
> agent (in the real world use case: a particular Microsoft product that just
> expects a particular BUGGY XML syntax, which JAXB just doesn't like to
> produce for good reasons, as the filter solely exists to workaround a this
> Microsoft bug).
>
> (This filter actually exists and is working well, but so far it was a
> Servlet Filter. As JAX-RS does not enforce Servlet containers, we want to
> turn it into a JAX-RS filter and / or interceptor to make it run with any
> kind of JAX-RS container).
>
> So, how to capture that original XML production to transform it on demand?
>
> When you try it using a container response filter, you know whether the
> client was that Microsoft product, but you will notice that there is no way
> to get the original XML inside of a container response filter to transform
> it.
>
> When you try it using an entity interceptor, you will get that XML easily by
> capturing the subsequent chain element's production into a replacement
> buffer output stream and you can send a different representation to the
> client using the original output stream (just like the original Servlet
> filter works like), but you have no chance to know whether the client
> actually is that particular Microsoft product (and you don't want to
> transform always as this would break all non-Microsoft agents).
>
> So one must use both, a response filter plus an entity interceptor, write a
> property ("Interceptor: You are needed!") into the context, check that
> context in the interceptor, do the rewrite there. That's a rather hack, but
> it is actually working, but you will notice that the client will never
> receive the new XML completely if it is longer than the original XML. Why?
> Simply because the RI 2.0 M08-1 sets a "Content-Length" header using the
> original XML's length, and ignores the actual length produced by the
> interceptor, so the client stops to read (at least cURL does and complains
> about the rest of the bytes in the stream). A nice way to produce a buffer
> overrun in the agent. And as you don't know the length produced by the
> interceptor inside of the response filter, you cannot overwrite the header
> there...
>
> As you see, it is simply not working. That is my problem. :-(
>
> Maybe I oversee a really simple solution?
>
> Regards
> Markus
>