Alan Wright wrote:

> Hi
>
> I have an application working well under Tomcat 3.1 and am trying to get it
> to work under 3.2.
>
> I had a sort of MVC thing going with a main servlet handling all requests
> by handing off to specific controller servlets using
> requestDispatcher.Include(request, response)  then returning to the user
> the results of a JSP using requestDispatcher.Forward(request, response).
>
> This approach worked just fine under 3.1 but fails under 3.2.
>
> The the first step is OK but when the application tries to Forward it fails
> with an error "Cannot forward as output stream or writer has already been
> obtained".  If I comment out the requestDispatcher.Include statement the
> JSP page returns OK but obvoiusly without any of the required changes to
> the data having taken place.
>
> Should I be able to do a requestDispatcher.Include followed by a
> requestDispatcher.Forward?
>
> Is anyone knowledgable enough to suggest whether this might be a bug?
>
> If it is a bug how should I report it?
>

The basic restriction causing this message is that you cannot do a
RequestDispatcher.forward() call after the response has been committed -- in
other words, when one of the following things happens:
* You write more data than can fit in the buffer size for this response.
* You call response.flushBuffer().

Normally, you should be able to do an include before a forward (although the
included JSP page might itself cause the response to become committed, so this
is pretty risky).  However, late in the development cycle of Tomcat 3.2 a
fundamental architectural problem was discovered that caused incorrect behavior
in a lot of "include" cases.  The only feasible workaround was to insert a
response.flushBuffer() call before the include was actually processed -- which
will make your proposed approach fail with the error you are getting.

Workaround approaches to consider:

* Use a RequestDispatcher.include() rather than forward()
  to invoke the view component at the end (since you are doing it last).

* Redesign so that the logic performed in your "controller"
  function is regular Java code, rather than an "included" servlet
  that has no visual result.  What your design calls the "controller"
  would be called an Action that contains business logic in the
  Struts framework, for example <http://jakarta.apache.org/struts>.

* Try this with Tomcat 4.0.

Craig McClanahan


Reply via email to