users@jax-rs-spec.java.net

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

From: Markus KARG <markus_at_headcrashing.eu>
Date: Wed, 10 Oct 2012 22:14:44 +0200

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