tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
Subject Re: setHeader after DoFilter delegation in filter?
Date Sat, 11 Oct 2008 10:44:54 GMT
André Warnier wrote:
> Hi.
> 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
> getWriter.

I suspect it will rather depend on the type of processing the OP is
trying to do on the output, maybe he can enlighten us?

> 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.

Andre is making the point that the processing could be done inside the
wrapper, rather than in the filter - which is only there to allow you to
wrap the response.

> Not very easy, and over my current capacities.

As above, depends on the type of processing required...  the use of a
ByteArrayOutputStream may be a simple way of buffering the response for


> 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:

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

View raw message