Re: setHeader after DoFilter delegation in filter?

2008-10-16 Thread slioch

Thanks for the responses. The reason we need to look at the response before
setting a header value is to support a dynamic caching behavior, where the
caching determination is made after examining the response and what database
interactions are made as a result of building the response.

So, I took your advice and implemented a responsewrapper object. This worked
in buffering the response, however a new problem cropped up. I think it's
mine--but I found out that I need to also buffer the header values and
commit these to the response as well. Still looking at my source though. 

Thanks all!



Pid-2 wrote:
 
 André Warnier wrote:
 Hi.
 I found an approximative example for you, here :
 http://www.javafaq.nu/java-example-code-237.html
 (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
 example.
 
 p
 
 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 java.io.IOException, 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 [mailto:[EMAIL PROTECTED]
 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

Re: setHeader after DoFilter delegation in filter?

2008-10-10 Thread slioch

Thanks much for the responses. I understand.

It makes sense to use HttpServletRequestWrapper, but there are no methods in
HttpServletRequestWrapper or HttpServletRequest that initiates the sending
of the response back to the client. So, by subclassing HttpServletRequest
there doesn't appear to be any way to suppress the sending on the response
back to the client (until I've completed processing).

What I would like to do is to prevent the response from being sent back to
the client until my filter has completed it's processing (and this is after
my filter delegates the doFilter() call to the other filters).

Mike


Pid-2 wrote:
 
 André Warnier wrote:
 slioch wrote:
 [...]
 I'll risk an explanation here..
 
 I think maybe the issue is a misunderstanding of how a servlet filter
 works.  It took me a while too, but I think I've got it in the end.
 Sorry if this is level 101, that's my own level.
 
 What was confusing to me at first, is that this is different from, for
 instance, Apache input and output filters.  There there is a clear
 distinction between an input filter, which sees all the data on the way
 in to the application, and an output filter, which sees all the data
 that the application produces, before it goes out to the browser.  An
 input filter and and output filter are two separate pieces of code, and
 you can install them independently.
 
 In the Java servlet view of things, a filter is a wrapper, within
 which the other filters and the webapp run.
 It's like an onion : your filter is the outer layer, within which there
 are possibly further layers (other filters), and at the center is the
 webapp.  When your filter calls doFilter(), it executes all its inner
 layers in one go.  The bummer is that, unless you take pains to change
 that, each of these layers has a direct access to the output buffers,
 which live outside the onion. So unless you prevent them from doing
 that, they will start putting bytes there, and by the time your
 doFilter() returns, it's too late to change that.
 
 When you execute doFilter(), in fact you execute, at that point, all the
 further filters that are in the chain, and the webapp at the deepest
 level.  If any of these starts sending output, then by the time the
 doFilter() returns, that output is already past your filter, and there
 is nothing you can do anymore to modify it.
 
 If you want something else to happen, then you have to do something like
 this :
 - in your filter, subclass the HttpRequest, say as myHttpRequest.  In
 this subclass, redefine the methods that the underlying filters and
 webapp will (presumably) use to send output to the buffer.  In these
 redefined methods, you can then do whatever you want to transform what
 the application sends out via these methods.
 - then, instead of passing the original HttpRequest to the doFilter(),
 pass your own myHttpRequest instance of it.
 
 Close enough; the spec has some stuff that covers this type of problem,
 so I'd recommend investigating:
 
  javax.servlet.http.HttpServletRequestWrapper
  javax.servlet.http.HttpServletResponseWrapper (hereafter HSRsW)
 
 Using the latter should allow you to modify the appropriate header.
 
  HSRsW wrappedHres = new HttpServletResponseWrapper(hres);
  chain.doFilter(hreq, wrappedHres);
 
 Where your HSRsW contains appropriate code to modify the header, perhaps
 in the construction phase.
 
 p
 
 
 This way, whenever the application thinks it is just using the (say)
 HttpRequest.setHeader() method, it is in fact using *your*
 myHttpRequest.setHeader() method, in which you can catch and pervert
 whatever you want, before passing it on to the real
 HttpRequest.setHeader() method.
 
 The point is, if you let any underlying (from the point of your filter)
 other filter or webapp call i.e. the original setHeader(), then that's
 it : that line of output is now already in the HTTP output buffer queue,
 and by the time your doFilter() returns, it no longer can claw it back.
 
 
 
 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 
 
 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 

-- 
View this message in context: 
http://www.nabble.com/setHeader-after-DoFilter-delegation-in-filter--tp19862960p19925786.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



RE: setHeader after DoFilter delegation in filter?

2008-10-10 Thread slioch

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 java.io.IOException, 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 [mailto:[EMAIL PROTECTED]
 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
 
 
 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 start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 

-- 
View this message in context: 
http://www.nabble.com/setHeader-after-DoFilter-delegation-in-filter--tp19862960p19929361.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: setHeader after DoFilter delegation in filter?

2008-10-09 Thread slioch

Thanks for the response Christopher. 

Unfortunately I need to set a value in the header after the doFilter()
delegation. The reason is that header valuedepends on the result of the page
rendering.

So, if autoflush is disabled and the buffer size is not exceeded for the
page shouldn't a setHeader() call made after the doFilter() call be able to
set the value in the response header?

Or, to put it another way, does the j2ee spec (or tomcat design) always
start sending the response to the client when the page is rendered (after
the last filter has been executed in a filter chain), or after the
filterchain has completed its processing?

Mike



Christopher Schultz-2 wrote:
 
 -BEGIN PGP SIGNED MESSAGE-
 Hash: SHA1
 
 Michael,
 
 Michael Larson wrote:
 I'm debugging a tomcat filter. The filter has been designed as follows:
 
 MyFilter::DoFilter(ServletRequest request, ServletResponse response,
 FilterChain chain)
 {
do_some_stuff();
 
//now delegate the call the chain
chain.DoFilter();
 
//the header value below doesn't always show up at the client
response.setHeader(post-filter,true);
 }
 
 This might not work because the response could have been committed. If
 the response buffer is filled, then the headers will be sent back to the
 client. If you come along later and try to set a header, you'll get an
 exception.
 
 For the jsp page being accessed I've turned off AutoFlush (via a server
 side directive). However, I'm still seeing this page (if it exceeds a
 certain size but well below the jspwriter buffer size) will be sent back
 to the client before the response header has been modified.
 
 I'm not sure about autoFlush, but it may be that you're hitting a hard
 buffer limit and the data is being sent, anyway.
 
 If AutoFlush is turned off for the jsp page and the page doesn't exceed
 the buffer size can it still send the response back to the client before
 the filter chain has completed (and in this example before the header
 has been modified)? Is it a bad idea to modify the response header after
 the call to chain.DoFilter()?
 
 It's much better to do it up front if you can. Why do you need the
 header to be set after the fact?
 
 If you really must do this, you can always do your own buffering by
 wrapping the request along with your own OutputStream/Writer that
 buffers itself.
 
 The version of tomcat is v5.5.23, and no exceptions are thrown when the
 setHeader call is made.
 
 That's interesting that no exceptions are thrown. :(
 
 - -chris
 -BEGIN PGP SIGNATURE-
 Version: GnuPG v1.4.9 (MingW32)
 Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
 
 iEYEARECAAYFAkjrrxwACgkQ9CaO5/Lv0PAKdwCfbEXaoIj5cnMLIYZciiEXcAL8
 0TMAn0CWqgdA8qQNsZwDabIQHbRHPoqY
 =Gqzj
 -END PGP SIGNATURE-
 
 -
 To start a new topic, e-mail: users@tomcat.apache.org
 To unsubscribe, e-mail: [EMAIL PROTECTED]
 For additional commands, e-mail: [EMAIL PROTECTED]
 
 
 

-- 
View this message in context: 
http://www.nabble.com/setHeader-after-DoFilter-delegation-in-filter--tp19862960p19912296.html
Sent from the Tomcat - User mailing list archive at Nabble.com.


-
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]