tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From André Warnier>
Subject Re: setHeader after DoFilter delegation in filter?
Date Sat, 11 Oct 2008 09:47:04 GMT
I found an approximative example for you, here :
(searching Google for "HttpServletResponseWrapper example"

If I remember well, what you want to achieve is : depending on the 
response content that the webapp generates, you would like to set a 
response header.  This response header has to be set of course, before 
the first byte of output content is sent to the browser.

Before your webapp is going to send this first byte, it will need to get 
some form of output stream to write the byte to.
It will do that using one of the methods available to webapps to get 
such an output stream, which I identify as either getOutputStream or 
So what you probably need to do in your wrapper, is to override these 
two methods, so that when the servlet calls one of them, you can return 
your own version of it instead of the regular one.
In this way, later your wrapper can "sit in the middle" when the webapp 
starts writing to its output, and you can examine this output before 
forwarding it to the "real" servlet output stream.  Of course before you 
forward the output there, you will have determined which header you want 
to add and sent it out.

Not very easy, and over my current capacities.
Unfortunately the example I provided above is a bit of a cheat, because 
all it has to do is replace the original stream by a compressed one, for 
which there is apparently already a convenient class available.

One of the important elements maybe, is how much of the output you need 
to see in order to determine which header to add.
If it is just the first few bytes, then I suppose you could buffer this 
in memory until you have enough, send out your header, and then set a 
flag so that subsequent servlet writes happen as transparently as possible.
If it is the whole response and it can be big, then you might have to 
buffer the entire response to disk before setting your header, and then 
re-read the original response and sending it out yourself.

slioch wrote:
> Sorry all--I'm still stumped. Tried the suggestions and here's what I found. 
> I've subclass HttpServletResponseWrapper and overloaded the following
> methods:
>     public void flushBuffer();
>     public void sendRedirect(String str);
>     public void sendError(int sc);
>     public void sendError(int sc, String msg);
> in my new response wrapper. These methods have been disabled while
> processing is in the scope of my filter (I also record if these methods are
> called). I've replaced the response object with my new wrapper:
>     public void doFilter(ServletRequest req, ServletResponse res,
> FilterChain fc)
>     throws, javax.servlet.ServletException {
> 	ResponseWrapper resp = new ResponseWrapper((HttpServletResponse)(res));
> And I've found that sendError(), sendRedirect(), and flushBuffer() are not
> being called while in the processing is in the scope of my filter. In other
> words the filter looks something like:
> dofilter(ServletRequest req, ServletResponse res, FilterChain fc)
> {
>    ResponseWrapper resp = new ResponseWrapper((HttpServletResponse)(res));
>    //resp.isCommitted() returns false
>    //some processing work
>    //resp.isCommitted() returns false;
>    fc.doFilter(req,resp);
>    //resp.isCommitted() returns TRUE
>   //some more process work
>   return;
> }
> If I know that sendError(), sendRedirect(), and flushBuffer() are not being
> called how would response be sent (provided autoflush is false and the
> buffer size is large enough for the print writer). Thanks for the help (and
> patience)!
> mike
> Caldarale, Charles R wrote:
>>> From: André Warnier []
>>> Subject: Re: setHeader after DoFilter delegation in filter?
>>> To create output for the client, the application calls
>>> something, right? (I mean a method of HttpRequest).
>> Not quite - you're confusing request with response.  There are methods in
>> HttpServletResponse - an Interface, not a class - to obtain a PrintWriter
>> or ServletOutputStream that the webapp uses to generate data to be sent to
>> the client at some point in the future.  The data isn't sent until
>> flushBuffer(), sendError(), or sendRedirect() are called.  Since the
>> HttpServletResponseWrapper class implements the interface, those methods
>> are available via the wrapper.  The filter needs to subclass the wrapper
>> in order to subvert anything else in the filter/servlet chain.
>>  - Chuck
>> MATERIAL and is thus for use only by the intended recipient. If you
>> received this in error, please contact the sender and delete the e-mail
>> and its attachments from all computers.
>> ---------------------------------------------------------------------
>> To start a new topic, e-mail:
>> To unsubscribe, e-mail:
>> For additional commands, e-mail:

To start a new topic, e-mail:
To unsubscribe, e-mail:
For additional commands, e-mail:

View raw message