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 (or at
different times) in order to provide their functionality.

> Best Regards,
>
> Daniel
>

Craig McClanahan


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

Reply via email to