users@jax-rs-spec.java.net

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

From: Santiago Pericas-Geertsen <Santiago.PericasGeertsen_at_oracle.com>
Date: Thu, 11 Oct 2012 09:37:12 -0400

Markus,

 So the transformation in this use case operates on the entity representation rather than the entity itself?

 We've had a lot of discussions (see archives) about filters reading and writing entities (thus, triggering interceptors and MBR/MBW multiple times) and that creates all sorts of issues. Hence the reason why the current proposal separates filtering from serialization. I.e., the current separation is by design.

-- Santiago

On Oct 10, 2012, at 4:14 PM, Markus KARG wrote:

> Hello Experts,
>
> to check how well we designed the Filters API in JAX-RS 2.0 we tried to rewrite some former Servlet Filters into JAX-RS 2.0 filters. It all looks good so far, but with one filter we have a severe problem that seems to proof that our API has a severe problem. Maybe we misunderstood something in the JavaDocs, but currently it looks as the following is impossible in JAX-RS (what would render the Filter API useless for us):
>
> Scenario: We need to write one PreMatchingFilter that rewrites EVERTHING, i. e. in a request it replaces the method, the URL, the headers, and wraps the entity content, and for the same request it must rewrite the response in a way that the status code, status info, headers are replaced and the entity content is wrapped. Should be possible, but actually is NOT (or at least looks like it is not):
>
> In filter(ContainerRequestContext, ContainerResponseContext) we can invoke setStatusCode, setStatusInfo, etc., but how do we wrap the original response entity? We see there is a responseContext.getEntityStream method, but that returns an OutputStream -- which we cannot read! So how to get the original content to analyze and wrap it? See, the entity shall not be replaced by "anything", but by a variant of the original response entity, so we need to get that in the filter method!
>
> And, no, we do not want to provide a separate entity interceptor as this would induce the need to split the replacement code into two different methods -- one to replace status and headers, one to replace the method, which is everything but smart.
>
> We think that to implement such a complex filter, the responseContext.getEntityStream() method must return a InputStream instead of OutputStream, and the setEntityStream() must accept an InputStream instead of an OutputStream.
>
> So did we a fault in our sample code, or is there a fault in the Filter API?
>
> Thanks!
> Markus