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]