You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Brendan Miller <ca...@catphive.net> on 2014/03/14 01:51:59 UTC

filter question

I have a filter with doFilter method like this:

    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
        throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        resp.setHeader("Cache-Control",
                       "must-revalidate, max-age=0, post-check=0,
pre-check=0");

        chain.doFilter(request, response);
    }

This sets the header. However, if I set the header *after* chain.doFilter,
the header is not set. Why is this?

    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
        throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        chain.doFilter(request, response);

        resp.setHeader("Cache-Control",
                       "must-revalidate, max-age=0, post-check=0,
pre-check=0");
    }

Programmatically I can see the header is null.

Has the content already been sent to the web browser after chain.doFilter?
If so, is there a way to delay sending data to the browser? I need to
inspect the status code in the response before setting my header (to
prevent 404's from being cached).

Thanks,
Brendan Miller

Re: filter question

Posted by André Warnier <aw...@ice-sa.com>.
Christopher Schultz wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
> 
> Makilaj,
> 
> On 3/14/14, 8:32 AM, Mikolaj Rydzewski wrote:
>> On 14.03.2014 13:25, André Warnier wrote:
>>
>>> Not a direct answer to your question, but this subject comes up
>>> so often that maybe a generic explanation may help.
>> [...]
>>> So any attempt at that point by the webapp (filters, servlet, 
>>> whatever) to modify the status or the headers will be met by a
>>> refusal : "can't do that, the response is already committed".
>> +100
>>
>> Wow, great explanation!
> 
> Agreed.
> 
> André, would you care to turn that into an entry on the Tomcat Wiki
> FAQ page? The concept of a "committed" response is certainly one that
> could use some clarification for those who don't understand it.
> 
I would happily do so, except that I am just at the point of leaving for a week where I'll 
have little time for that kind of thing.  Let's do this : I donate the response and all 
concommittant rights to the Apache Foundation, and will happily let someone else create 
the FAQ article and do some cut-and-paste in my stead.

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: filter question

Posted by Christopher Schultz <ch...@christopherschultz.net>.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Makilaj,

On 3/14/14, 8:32 AM, Mikolaj Rydzewski wrote:
> On 14.03.2014 13:25, André Warnier wrote:
> 
>> Not a direct answer to your question, but this subject comes up
>> so often that maybe a generic explanation may help.
> [...]
>> So any attempt at that point by the webapp (filters, servlet, 
>> whatever) to modify the status or the headers will be met by a
>> refusal : "can't do that, the response is already committed".
> 
> +100
> 
> Wow, great explanation!

Agreed.

André, would you care to turn that into an entry on the Tomcat Wiki
FAQ page? The concept of a "committed" response is certainly one that
could use some clarification for those who don't understand it.

- -chris
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: GPGTools - http://gpgtools.org
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBCAAGBQJTIwBBAAoJEBzwKT+lPKRYdDgP/0KM0avcuK4OEpGkgovMVq8A
OZD1GazPTM/a62zzSfsjH1uPrNl4pOIRKpXAjS+lg8c8JH8UME4mj25aPD/mvw7O
t6RZxmCTr7ogDRPvRPyQd5bQQl/WYcfzKOnQXKfOyVTprbe/byDimjCJfE6mWknY
XFXJJdp2OjMx1ft1g8Ht94G9ZPZOH2RhXm1pKCaDypelmoXo0PSeaXkeeBBYzqIn
LHFSbpy7lZ+EFKred2GDVNCI1IC+a4KXKb7N2UrMm9n7zfgcXqWCwyuVqAh3Sixj
SKs5czeLtnGdXRcsspGB8gQHCMTh2Dc9PAukLSKZEiWyT063DQCSikcOj9u7P1kF
BrLwW8I8g8fmyfrY17aNAPemBFoKyeUijhHUzw64oMxlu+VtfOTM2pfzaklCD5f9
kRJ9CQ0WkODdMWgrhFD2dC5hbbpVbSi8c9OHFM8pqRwcMaQZtY0DxeOo6xZDBLUW
sYV10Hu0xeLpH/uKfh1hKBnR8oMiOoviOrJI+oUPirLMlRvM5xgB7XLE2zWDGjRV
LkrItJLX9HxT730Qk/ZqfTaJbt/KnGNjHcqIGOzUx+iOeHxfnR6ULeEt3vbYaYHX
41d9+Navk0c9z5VwDu548onA5vYAdZYnm48KNKWUktjXzV3bo69Xb0K3+JgPIbHe
1r9awD88NkDmuyZ/gF9B
=BkUs
-----END PGP SIGNATURE-----

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: filter question

Posted by Mikolaj Rydzewski <mi...@ceti.pl>.
On 14.03.2014 13:25, André Warnier wrote:

> Not a direct answer to your question, but this subject comes up so
> often that maybe a generic explanation may help.
[...]
> So any attempt at that point by the webapp (filters, servlet,
> whatever) to modify the status or the headers will be met by a refusal
> : "can't do that, the response is already committed".

+100

Wow, great explanation!

-- 
Mikolaj Rydzewski <mi...@ceti.pl>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: filter question

Posted by André Warnier <aw...@ice-sa.com>.
Brendan Miller wrote:
> I have a filter with doFilter method like this:
> 
>     public void doFilter(ServletRequest request,
>                          ServletResponse response,
>                          FilterChain chain)
>         throws IOException, ServletException {
>         HttpServletRequest req = (HttpServletRequest) request;
>         HttpServletResponse resp = (HttpServletResponse) response;
> 
>         resp.setHeader("Cache-Control",
>                        "must-revalidate, max-age=0, post-check=0,
> pre-check=0");
> 
>         chain.doFilter(request, response);
>     }
> 
> This sets the header. However, if I set the header *after* chain.doFilter,
> the header is not set. Why is this?
> 
>     public void doFilter(ServletRequest request,
>                          ServletResponse response,
>                          FilterChain chain)
>         throws IOException, ServletException {
>         HttpServletRequest req = (HttpServletRequest) request;
>         HttpServletResponse resp = (HttpServletResponse) response;
> 
>         chain.doFilter(request, response);
> 
>         resp.setHeader("Cache-Control",
>                        "must-revalidate, max-age=0, post-check=0,
> pre-check=0");
>     }
> 
> Programmatically I can see the header is null.
> 
> Has the content already been sent to the web browser after chain.doFilter?
> If so, is there a way to delay sending data to the browser? I need to
> inspect the status code in the response before setting my header (to
> prevent 404's from being cached).
> 

Not a direct answer to your question, but this subject comes up so often that maybe a 
generic explanation may help.

What is the meaning of "the response is already committed" ?

In the HTTP protocol, a HTTP Response consists of :

- a HTTP "status line"  (like : "200 OK")
- 0 or more "response headers" (like "Content-length: 1234)
- a blank line
- the response content (like : a html page, or a jpeg image)

(The last 2 elements are optional, as some responses do not have a content part, by 
definition)

The above is what a HTTP client (e.g. a browser) will be waiting for, after it has sent a 
request to a HTTP server (e.g., Tomcat). The client will expect the above "response lines" 
to arrive to it strictly in the order above.  It would not expect for example the HTTP 
status line to come after a HTTP response header or after the content of the response.
That means that the HTTP server will need to ensure that the above response lines are 
written to the client socket also in the order above.

In the course of processing a request, at some point Tomcat will be setting up a "Response 
object", which is an internal representation of (and a buffer for) the HTTP response that 
will at some point be sent to the client.

When a webapp is run, the main thing it will usually be doing is to prepare the response 
content.  In the Response object, the status code and the response headers are also being 
set gradually, as a kind of side-effect (or explicitly).  But for the moment, all of this 
happens in the Response object, in memory, and nothing has yet been sent to the client.

In other words, at this point the Response is still "uncommitted", and the webapp can 
still manipulate the response status code and the response headers in the Response object.

However, as soon as the webapp starts outputting the response *content* to the client, and 
before even the first byte of the response content is effectively sent over the client 
socket, the server has no choice : in order to preserve the expected order in the HTTP 
response, it must first send the HTTP status line, then the HTTP headers, then a blank 
line, then the first byte of the response.

That is when the response is "commmitted" (and the server will now set a flag to that 
effect in the Response object).

 From that point on, it is too late to still modify the HTTP status code or the HTTP 
response headers, because they are already on their way to the client, and the server 
cannot "grab them back".

So any attempt at that point by the webapp (filters, servlet, whatever) to modify the 
status or the headers will be met by a refusal : "can't do that, the response is already 
committed".




---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: filter question

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Brendan Miller [mailto:catphive@catphive.net] 
> Subject: Re: filter question

> On Thu, Mar 13, 2014 at 6:20 PM, Martin Gainty <mg...@hotmail.com> wrote:
> > you'll need to pass your modified response to service method of servlet
> > which is *in* the filterChain

> I'm confused by what you mean by that.

As is pretty much everyone with regard to every post from Martin G.  After you've been on the list a bit, you'll learn to simply drop his messages in the rubbish bin.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY 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 unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: filter question

Posted by Tim Watts <ti...@cliftonfarm.org>.
On Thu, 2014-03-13 at 23:16 -0400, Tim Watts wrote:
> On Thu, 2014-03-13 at 19:11 -0700, Brendan Miller wrote:
> > To be clear, I'm trying to modify the response that comes back from the
> > service. I have a header that I may or may not need to set based on the
> > response code. I believe the service sets the response code?
> 
> That's true.  
Actually, let me correct myself: that may not be strictly true.  I don't
think there's anything in the spec that says the response code will be
set when service() returns UNLESS the request results in an error.

-- Tim.

> Unfortunately, by the time your filter gets control again,
> the response will very likely be committed thus shutting out any
> possibility of setting any headers.
> 
> Doing this in a Filter, while intuitively sensible, will always be a
> highly fragile solution.  You would have to set a buffer large enough to
> accommodate the largest conceivable response size.  Once a response is
> committed you can't set the response code or headers -- they're already
> on their way to the client.  There's no getting around this.
> 
> I think the best approach is to conditionally set the header before any
> response is generated.  If your application has an MVC structure you
> could do this just before the Controller invokes the View.  You should
> know the response code by then.
> 
> HTH
> 
> -- Tim
> 
> > 
> > 
> > On Thu, Mar 13, 2014 at 6:20 PM, Martin Gainty <mg...@hotmail.com> wrote:
> > 
> > > you'll need to pass your modified response to service method of servlet
> > > which is *in* the filterChain
> > >
> > >
> > > ApplicationFilterChain::internalDoFilter(ServletRequest request,
> > > ServletResponse response)
> > >         throws IOException, ServletException
> > >
> > > {
> > > ............
> > > servlet.service(request, response);
> > >
> > > ...........
> > >
> > > }
> > >
> > > Martin
> > >
> > >
> > >
> > >
> > >
> > >
> > > > Date: Thu, 13 Mar 2014 17:51:59 -0700
> > > > Subject: filter question
> > > > From: catphive@catphive.net
> > > > To: users@tomcat.apache.org
> > > >
> > > > I have a filter with doFilter method like this:
> > > >
> > > > public void doFilter(ServletRequest request,
> > > > ServletResponse response,
> > > > FilterChain chain)
> > > > throws IOException, ServletException {
> > > > HttpServletRequest req = (HttpServletRequest) request;
> > > > HttpServletResponse resp = (HttpServletResponse) response;
> > > >
> > > > resp.setHeader("Cache-Control",
> > > > "must-revalidate, max-age=0, post-check=0,
> > > > pre-check=0");
> > > >
> > > > chain.doFilter(request, response);
> > > > }
> > > >
> > > > This sets the header. However, if I set the header *after*
> > > chain.doFilter,
> > > > the header is not set. Why is this?
> > > >
> > > > public void doFilter(ServletRequest request,
> > > > ServletResponse response,
> > > > FilterChain chain)
> > > > throws IOException, ServletException {
> > > > HttpServletRequest req = (HttpServletRequest) request;
> > > > HttpServletResponse resp = (HttpServletResponse) response;
> > > >
> > > > chain.doFilter(request, response);
> > > >
> > > > resp.setHeader("Cache-Control",
> > > > "must-revalidate, max-age=0, post-check=0,
> > > > pre-check=0");
> > > > }
> > > >
> > > > Programmatically I can see the header is null.
> > > >
> > > > Has the content already been sent to the web browser after
> > > chain.doFilter?
> > > > If so, is there a way to delay sending data to the browser? I need to
> > > > inspect the status code in the response before setting my header (to
> > > > prevent 404's from being cached).
> > > >
> > > > Thanks,
> > > > Brendan Miller
> > >
> > >
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
> 



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: filter question

Posted by "Caldarale, Charles R" <Ch...@unisys.com>.
> From: Tim Watts [mailto:tim@cliftonfarm.org] 
> Subject: Re: filter question

> Doing this in a Filter, while intuitively sensible, will always be a
> highly fragile solution.  You would have to set a buffer large enough to
> accommodate the largest conceivable response size.  Once a response is
> committed you can't set the response code or headers -- they're already
> on their way to the client.  There's no getting around this.

The filter could wrap the original response object with its own creation, and thereby control what gets written through it.  The wrapper object can determine when to add the header, based on whatever criteria you like, such as amount of data so far written, internal state of the webapp, etc.  Examples of such wrappering have been posted on this list a few times in the recent past.

 - Chuck


THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY 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 unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: filter question

Posted by Tim Watts <ti...@cliftonfarm.org>.
On Thu, 2014-03-13 at 19:11 -0700, Brendan Miller wrote:
> I'm confused by what you mean by that. Are you saying I need to somehow
> rewrite the class of the FilterChain object passed to my filter?
> 
I think you're somewhat new to the list.  Mr. Gainty is notorious here
and seems to pride himself on concocting the most off-the-wall red
herrings imaginable.  I'll admit some of them are truly breathtaking.  I
guess it's some sort of quest to build a global reputation as the
world's most incompetent developer.  I dunno.

> To be clear, I'm trying to modify the response that comes back from the
> service. I have a header that I may or may not need to set based on the
> response code. I believe the service sets the response code?

That's true.  Unfortunately, by the time your filter gets control again,
the response will very likely be committed thus shutting out any
possibility of setting any headers.

Doing this in a Filter, while intuitively sensible, will always be a
highly fragile solution.  You would have to set a buffer large enough to
accommodate the largest conceivable response size.  Once a response is
committed you can't set the response code or headers -- they're already
on their way to the client.  There's no getting around this.

I think the best approach is to conditionally set the header before any
response is generated.  If your application has an MVC structure you
could do this just before the Controller invokes the View.  You should
know the response code by then.

HTH

-- Tim

> 
> 
> On Thu, Mar 13, 2014 at 6:20 PM, Martin Gainty <mg...@hotmail.com> wrote:
> 
> > you'll need to pass your modified response to service method of servlet
> > which is *in* the filterChain
> >
> >
> > ApplicationFilterChain::internalDoFilter(ServletRequest request,
> > ServletResponse response)
> >         throws IOException, ServletException
> >
> > {
> > ............
> > servlet.service(request, response);
> >
> > ...........
> >
> > }
> >
> > Martin
> >
> >
> >
> >
> >
> >
> > > Date: Thu, 13 Mar 2014 17:51:59 -0700
> > > Subject: filter question
> > > From: catphive@catphive.net
> > > To: users@tomcat.apache.org
> > >
> > > I have a filter with doFilter method like this:
> > >
> > > public void doFilter(ServletRequest request,
> > > ServletResponse response,
> > > FilterChain chain)
> > > throws IOException, ServletException {
> > > HttpServletRequest req = (HttpServletRequest) request;
> > > HttpServletResponse resp = (HttpServletResponse) response;
> > >
> > > resp.setHeader("Cache-Control",
> > > "must-revalidate, max-age=0, post-check=0,
> > > pre-check=0");
> > >
> > > chain.doFilter(request, response);
> > > }
> > >
> > > This sets the header. However, if I set the header *after*
> > chain.doFilter,
> > > the header is not set. Why is this?
> > >
> > > public void doFilter(ServletRequest request,
> > > ServletResponse response,
> > > FilterChain chain)
> > > throws IOException, ServletException {
> > > HttpServletRequest req = (HttpServletRequest) request;
> > > HttpServletResponse resp = (HttpServletResponse) response;
> > >
> > > chain.doFilter(request, response);
> > >
> > > resp.setHeader("Cache-Control",
> > > "must-revalidate, max-age=0, post-check=0,
> > > pre-check=0");
> > > }
> > >
> > > Programmatically I can see the header is null.
> > >
> > > Has the content already been sent to the web browser after
> > chain.doFilter?
> > > If so, is there a way to delay sending data to the browser? I need to
> > > inspect the status code in the response before setting my header (to
> > > prevent 404's from being cached).
> > >
> > > Thanks,
> > > Brendan Miller
> >
> >



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


Re: filter question

Posted by Brendan Miller <ca...@catphive.net>.
I'm confused by what you mean by that. Are you saying I need to somehow
rewrite the class of the FilterChain object passed to my filter?

To be clear, I'm trying to modify the response that comes back from the
service. I have a header that I may or may not need to set based on the
response code. I believe the service sets the response code?


On Thu, Mar 13, 2014 at 6:20 PM, Martin Gainty <mg...@hotmail.com> wrote:

> you'll need to pass your modified response to service method of servlet
> which is *in* the filterChain
>
>
> ApplicationFilterChain::internalDoFilter(ServletRequest request,
> ServletResponse response)
>         throws IOException, ServletException
>
> {
> ............
> servlet.service(request, response);
>
> ...........
>
> }
>
> Martin
>
>
>
>
>
>
> > Date: Thu, 13 Mar 2014 17:51:59 -0700
> > Subject: filter question
> > From: catphive@catphive.net
> > To: users@tomcat.apache.org
> >
> > I have a filter with doFilter method like this:
> >
> > public void doFilter(ServletRequest request,
> > ServletResponse response,
> > FilterChain chain)
> > throws IOException, ServletException {
> > HttpServletRequest req = (HttpServletRequest) request;
> > HttpServletResponse resp = (HttpServletResponse) response;
> >
> > resp.setHeader("Cache-Control",
> > "must-revalidate, max-age=0, post-check=0,
> > pre-check=0");
> >
> > chain.doFilter(request, response);
> > }
> >
> > This sets the header. However, if I set the header *after*
> chain.doFilter,
> > the header is not set. Why is this?
> >
> > public void doFilter(ServletRequest request,
> > ServletResponse response,
> > FilterChain chain)
> > throws IOException, ServletException {
> > HttpServletRequest req = (HttpServletRequest) request;
> > HttpServletResponse resp = (HttpServletResponse) response;
> >
> > chain.doFilter(request, response);
> >
> > resp.setHeader("Cache-Control",
> > "must-revalidate, max-age=0, post-check=0,
> > pre-check=0");
> > }
> >
> > Programmatically I can see the header is null.
> >
> > Has the content already been sent to the web browser after
> chain.doFilter?
> > If so, is there a way to delay sending data to the browser? I need to
> > inspect the status code in the response before setting my header (to
> > prevent 404's from being cached).
> >
> > Thanks,
> > Brendan Miller
>
>

RE: filter question

Posted by Tim Watts <ti...@cliftonfarm.org>.
On Thu, 2014-03-13 at 21:20 -0400, Martin Gainty wrote:
> you'll need to pass your modified response to service method of
> servlet which is *in* the filterChain

Utter nonsense.

> ApplicationFilterChain::internalDoFilter(ServletRequest request,
> ServletResponse response)
>         throws IOException, ServletException 
> 
> {
> ............
> servlet.service(request, response);
> 
> ...........
> 
> }
> 
> Martin 
> 
> 
>   
> 
> 
> 
> > Date: Thu, 13 Mar 2014 17:51:59 -0700
> > Subject: filter question
> > From: catphive@catphive.net
> > To: users@tomcat.apache.org
> > 
> > I have a filter with doFilter method like this:
> > 
> > public void doFilter(ServletRequest request,
> > ServletResponse response,
> > FilterChain chain)
> > throws IOException, ServletException {
> > HttpServletRequest req = (HttpServletRequest) request;
> > HttpServletResponse resp = (HttpServletResponse) response;
> > 
> > resp.setHeader("Cache-Control",
> > "must-revalidate, max-age=0, post-check=0,
> > pre-check=0");
> > 
> > chain.doFilter(request, response);
> > }
> > 
> > This sets the header. However, if I set the header *after* chain.doFilter,
> > the header is not set. Why is this?
> > 
> > public void doFilter(ServletRequest request,
> > ServletResponse response,
> > FilterChain chain)
> > throws IOException, ServletException {
> > HttpServletRequest req = (HttpServletRequest) request;
> > HttpServletResponse resp = (HttpServletResponse) response;
> > 
> > chain.doFilter(request, response);
> > 
> > resp.setHeader("Cache-Control",
> > "must-revalidate, max-age=0, post-check=0,
> > pre-check=0");
> > }
> > 
> > Programmatically I can see the header is null.
> > 
> > Has the content already been sent to the web browser after chain.doFilter?
> > If so, is there a way to delay sending data to the browser? I need to
> > inspect the status code in the response before setting my header (to
> > prevent 404's from being cached).
> > 
> > Thanks,
> > Brendan Miller
>  		 	   		  



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org


RE: filter question

Posted by Martin Gainty <mg...@hotmail.com>.
you'll need to pass your modified response to service method of servlet which is *in* the filterChain


ApplicationFilterChain::internalDoFilter(ServletRequest request, ServletResponse response)
        throws IOException, ServletException 

{
............
servlet.service(request, response);

...........

}

Martin 


  



> Date: Thu, 13 Mar 2014 17:51:59 -0700
> Subject: filter question
> From: catphive@catphive.net
> To: users@tomcat.apache.org
> 
> I have a filter with doFilter method like this:
> 
> public void doFilter(ServletRequest request,
> ServletResponse response,
> FilterChain chain)
> throws IOException, ServletException {
> HttpServletRequest req = (HttpServletRequest) request;
> HttpServletResponse resp = (HttpServletResponse) response;
> 
> resp.setHeader("Cache-Control",
> "must-revalidate, max-age=0, post-check=0,
> pre-check=0");
> 
> chain.doFilter(request, response);
> }
> 
> This sets the header. However, if I set the header *after* chain.doFilter,
> the header is not set. Why is this?
> 
> public void doFilter(ServletRequest request,
> ServletResponse response,
> FilterChain chain)
> throws IOException, ServletException {
> HttpServletRequest req = (HttpServletRequest) request;
> HttpServletResponse resp = (HttpServletResponse) response;
> 
> chain.doFilter(request, response);
> 
> resp.setHeader("Cache-Control",
> "must-revalidate, max-age=0, post-check=0,
> pre-check=0");
> }
> 
> Programmatically I can see the header is null.
> 
> Has the content already been sent to the web browser after chain.doFilter?
> If so, is there a way to delay sending data to the browser? I need to
> inspect the status code in the response before setting my header (to
> prevent 404's from being cached).
> 
> Thanks,
> Brendan Miller
 		 	   		  

Re: filter question

Posted by Tim Watts <ti...@cliftonfarm.org>.
On Thu, 2014-03-13 at 17:51 -0700, Brendan Miller wrote:
> I have a filter with doFilter method like this:
> 
>     public void doFilter(ServletRequest request,
>                          ServletResponse response,
>                          FilterChain chain)
>         throws IOException, ServletException {
>         HttpServletRequest req = (HttpServletRequest) request;
>         HttpServletResponse resp = (HttpServletResponse) response;
> 
>         resp.setHeader("Cache-Control",
>                        "must-revalidate, max-age=0, post-check=0,
> pre-check=0");
> 
>         chain.doFilter(request, response);
>     }
> 
> This sets the header. However, if I set the header *after* chain.doFilter,
> the header is not set. Why is this?
> 
A similar question came up last week.  Basically, it's because the
response has already been committed.  A response becomes committed once
the 1st byte is sent back to the client -- e.g. if flush() is called or
the buffer becomes full while more response data is written.

You can search the archive for how it was resolved.  Don't recall the
subject line.  Sorry.

-- Tim

>     public void doFilter(ServletRequest request,
>                          ServletResponse response,
>                          FilterChain chain)
>         throws IOException, ServletException {
>         HttpServletRequest req = (HttpServletRequest) request;
>         HttpServletResponse resp = (HttpServletResponse) response;
> 
>         chain.doFilter(request, response);
> 
>         resp.setHeader("Cache-Control",
>                        "must-revalidate, max-age=0, post-check=0,
> pre-check=0");
>     }
> 
> Programmatically I can see the header is null.
> 
> Has the content already been sent to the web browser after chain.doFilter?
> If so, is there a way to delay sending data to the browser? I need to
> inspect the status code in the response before setting my header (to
> prevent 404's from being cached).
> 
> Thanks,
> Brendan Miller



---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org