Clarification on Filter API and Requestdispatcher

2002-01-09 Thread Daniel Hoppe

Hi all,

I'm trying to get a clarification on an ambiguity in the Servlet
specification 2.3. Consider a setup like this:

 JSP
 |--|
 |  | 
 |--|
 /-\
  |   |
  | Dispatched Request|  ResponseWrapper 
|   |
 \_/
  MVC Controllerservlet
 |--|
 |  | 
 |--|
 /-\
  |   |
  | Initial Request   |  ResponseWrapper  
|   |
 \_/
  Filter 
 |--|
 |  |  
 |--|
 /-\
  |   |
  | Initial Request   |  Underlying Response 
|   |
 \_/
  Browser 
 |--|
 |  | 
 |--|

A client browser issues a request to the Servlet container. The request goes
to a Controllerservlet which dispatches to a JSP. 

Additionally, a filterchain is activated. The configured filter is supposed
to manipulate the response, e.g. cache, compress, modify. Therefore it hands
out a HttpServletResponseWrapper with a derived ServletOutputStream class
which writes the contents of the JSP to e.g. a ByteArrayOutputStream. The
filter can then take the results of the request, manipulate them and write
them to the original response.

This is a likely approach for most of the Examples of Filtering Components
(SRV.6.1.1). When trying to implement a filter like this I recognized, that
Servlet containers differ in their interpretation of The forward Methid
(SRV.8.4). The statement Before the forward method of the RequestDispatcher
interface returns, the response content must be sent and committed, and
closed by the servlet container is applied to the ServletResponseWrapper by
some implementations (e.g. Resin), to the underlying original response by
others (Tomcat, WebLogic).  

In plain words that means: Once a dispatch is issued in Tomcat and WebLogic,
e.g. when using Struts or any other MVC approach, one can forget about
filters as the container commits the underlying response. If a filter is
activated, the user will get a blank browser as the content went to the
ServletResponseWrapper, the commit to the (empty) original response. In
Resin it works as I would have expected, but I'm not sure which
interpretation is correct.

I would be glad for opinions on this, clarifications on SRV.8.4 and the
intent behind this. As Tomcat is the reference implementation I guess that
other containers are likely to follow the interpretation made here. Please
let me know if you find my explanation incomplete or unclear. If someone
would like to have a simple reproducer for this behaviour let me know as
well, I have one prepared already.

Best Regards,

Daniel




sitewaerts GmbH
Hebelstraße 15
D-76133 Karlsruhe

Tel: +49 (721) 920 918 0
Fax: +49 (721) 920 918 29
http://www.sitewaerts.de




--
To unsubscribe:   mailto:[EMAIL PROTECTED]
For additional commands: mailto:[EMAIL PROTECTED]
Troubles with the list: mailto:[EMAIL PROTECTED]




Re: Clarification on Filter API and Requestdispatcher

2002-01-09 Thread Craig R. McClanahan



On Wed, 9 Jan 2002, Daniel Hoppe wrote:

 Date: Wed, 9 Jan 2002 13:00:09 +0100
 From: Daniel Hoppe [EMAIL PROTECTED]
 Reply-To: Tomcat Users List [EMAIL PROTECTED]
 To: '[EMAIL PROTECTED]' [EMAIL PROTECTED]
 Subject: Clarification on Filter API and Requestdispatcher

 Hi all,

 I'm trying to get a clarification on an ambiguity in the Servlet
 specification 2.3. Consider a setup like this:

  JSP
  |--|
  |  |
  |--|
  /-\
   |   |
   | Dispatched Request|  ResponseWrapper
   |   |
  \_/
   MVC Controllerservlet
  |--|
  |  |
  |--|
  /-\
   |   |
   | Initial Request   |  ResponseWrapper
   |   |
  \_/

If you want the ResponseWrapper returned here, then the Filter will have
to have passed it on when it calls chain.doFilter().

   Filter
  |--|
  |  |
  |--|
  /-\
   |   |
   | Initial Request   |  Underlying Response
   |   |
  \_/
   Browser
  |--|
  |  |
  |--|

 A client browser issues a request to the Servlet container. The request goes
 to a Controllerservlet which dispatches to a JSP.

 Additionally, a filterchain is activated. The configured filter is supposed
 to manipulate the response, e.g. cache, compress, modify. Therefore it hands
 out a HttpServletResponseWrapper with a derived ServletOutputStream class
 which writes the contents of the JSP to e.g. a ByteArrayOutputStream. The
 filter can then take the results of the request, manipulate them and write
 them to the original response.


Sounds like you're on the right track.

There's an example of a filter that does this kind of thing somewhere on
the Java Developer's Connection (I don't recall the URL at the moment,
though).  There's another example (that does on-the-fly compression if the
client supports it) -- see the CompressionFilter source in the examples
application shipped with Tomcat.

 This is a likely approach for most of the Examples of Filtering Components
 (SRV.6.1.1). When trying to implement a filter like this I recognized, that
 Servlet containers differ in their interpretation of The forward Methid
 (SRV.8.4). The statement Before the forward method of the RequestDispatcher
 interface returns, the response content must be sent and committed, and
 closed by the servlet container is applied to the ServletResponseWrapper by
 some implementations (e.g. Resin), to the underlying original response by
 others (Tomcat, WebLogic).

 In plain words that means: Once a dispatch is issued in Tomcat and WebLogic,
 e.g. when using Struts or any other MVC approach, one can forget about
 filters as the container commits the underlying response. If a filter is
 activated, the user will get a blank browser as the content went to the
 ServletResponseWrapper, the commit to the (empty) original response. In
 Resin it works as I would have expected, but I'm not sure which
 interpretation is correct.


My interpretation (and what Tomcat 4 actually does) is that the container
must indeed call response.flushBuffer(), and then close the underlying
ServletOutputStream or PrintWriter that it is writing to.  But, remember,
the container is calling these methods on *your* wrapper class, so you can
intercept them and do whatever you want to the real underlying response.

To be specific, in the sentence:

Before the forward method of the RequestDispatcher
returns, the response content must be sent and committed,
and closed by the servlet container.

the the response that is referenced is your wrapper class, not the
original response.

 I would be glad for opinions on this, clarifications on SRV.8.4 and the
 intent behind this. As Tomcat is the reference implementation I guess that
 other containers are likely to follow the interpretation made here. Please
 let me know if you find my explanation incomplete or unclear. If someone
 would like to have a simple reproducer for this behaviour let me know as
 well, I have one prepared already.


The basic language of Section 8.4 was written before filters and response
wrapping existed, because it was carried over from Servlet 2.2.  But the
introduction of wrappers means that the container must allow your wrapper
classes to intercept servlet API calls and do things differently

RE: Clarification on Filter API and Requestdispatcher

2002-01-09 Thread Daniel Hoppe

Thanks a lot Craig, that was the interpretation I had expected and hoped
for!

Daniel



sitewaerts GmbH
Hebelstraße 15
D-76133 Karlsruhe

Tel: +49 (721) 920 918 0
Fax: +49 (721) 920 918 29
http://www.sitewaerts.de




--
To unsubscribe:   mailto:[EMAIL PROTECTED]
For additional commands: mailto:[EMAIL PROTECTED]
Troubles with the list: mailto:[EMAIL PROTECTED]