You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Len Popp <le...@gmail.com> on 2009/04/30 06:15:17 UTC

Re: Servlets that use response.getOutputStream(): do they play nicely with Tomcat's error pages?

There's no possible way for Tomcat to "start from scratch". If some
data has already been sent to the client, it can't be called back to
the server. What's sent is sent.

Typically, the HTTP response is buffered because the JSP handler does
that automatically. So if an error occurs before the response headers
are sent to the client, the error page can be sent instead.

I write my servlets so that they do whatever they need to do, gather
the output data, and then write the output page. If errors occur they
generally happen before any output is written.

Another way this is often handled is to just write an error message in
the middle of the web page if an error occurs. But I guess that won't
work for you because you're writing an Excel file, not a web page.
-- 
Len



On Wed, Apr 29, 2009 at 22:41, Dave Cherkassky <dc...@djinnsoft.com> wrote:
> PID, thanks for your insight.
>
>
> Two comments about that:
>
> 1) I agree with you for includes and forwards, but for errors?  I would have
> thought that the definition of "error" is that something went wrong, and
> Tomcat should start from scratch and just render the error page.  I didn't
> think of it as really a forward...
>
> 2) So you are suggesting that writing out to the response.getOutputStream()
> as I go is wrong?  Instead, I need to:
> a. buffer my output locally
> b. once I am sure that it can all be created correctly, *then* I write out
> the buffer to the response?
>
> Am I understanding you correctly?
>
> Thanks,
> --
> Dave Cherkassky
>  VP of Software Development
>  DJiNN Software Inc.
>  416.504.1354
>
>
> Pid wrote:
>>
>> Dave Cherkassky wrote:
>>>
>>> A long question:
>>>
>>> First, I have a Servlet that writes to response.getOutputStream(). Here's
>>> a snippet:
>>>  public class AuditTrailServlet extends HttpServlet {
>>>   public void doGet( HttpServletRequest request, HttpServletResponse
>>> response )
>>>     response.setContentType( "application/vnd.ms-excel" );
>>>     response.setHeader( "Content-Disposition", "attachment; filename="
>>> + fileName );
>>>
>>>     ResultSet rs = ...;
>>>     for ( int row = 0 ; rs.next(); row++ ) {
>>>       // iterate over each row in the ResultSet
>>>       for( int col = 0; fieldNameIt.hasNext(); col++ ) {
>>>         // iterate over each column in the results, write to spreadsheet
>>>                  // custom code.
>>>         // let us assume this block has a bug that occasionally throws
>>> a NullPointerException,          // but only after a bunch of cells are
>>> written first.
>>>                  response.getOutputStream().write( /* excel byte[] */ );
>>>                  // more custom code.
>>>       }
>>>     }
>>>     rs.close();
>>>       response.setStatus( HttpServletResponse.SC_OK );
>>>   }
>>>  }
>>>
>>> Second, I have the following in the web.xml file, to tell tomcat to use
>>> a custom error page:
>>>  <error-page>
>>>   <exception-type>java.lang.Throwable</exception-type>
>>>   <location>/myError.jsp</location>
>>>  </error-page>
>>>
>>> Last, here's myError.jsp:
>>>  <%@ page isErrorPage='true' %>
>>>  <html>
>>>  <body>
>>>  <h1>System Error</h1>
>>>  <p>
>>>  You have encountered a system error.
>>>  </p>
>>>   <%-- custom error processing that can't be done in a static .html page
>>> --%>
>>>   </body>
>>>  </html>
>>>
>>>
>>> So, it all seems standard and straight-forward, right?
>>>
>>>
>>>
>>> However, instead of seeing a nice custom error page when the NPE
>>> happens, I get the "ugly" Tomcat error page, and
>>> the following in the Tomcat logs:
>>>  java.lang.IllegalStateException: getOutputStream() has already been
>>> called for this response
>>>  at
>>>
>>> org.apache.catalina.connector.ResponseBase.getWriter(ResponseBase.java:709)
>>>  at
>>>
>>> org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:127)
>>>
>>>  at
>>> org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:128)
>>>  at
>>>
>>> org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:121)
>>>  at
>>>
>>> org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:137)
>>>  at
>>>
>>> org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:153)
>>>
>>>  at
>>>
>>> org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:148)
>>>
>>>  at org.apache.jsp.error_jsp._jspService(error_jsp.java:284)
>>>
>>>
>>> Yes, I know -- I *am* using Tomcat 4.1 (rather than the latest and
>>> greatest) for various legacy and political reasons.
>>>
>>>
>>> But my question is this:
>>> - Is this a known bug?  Or am I doing something wrong with either the
>>> servlet, the web.xml or with the jsp page?
>>
>> I'm not sure it's a bug; logically, if you've sent a chunk of the
>> response (and therefore committed the response, sent headers etc)
>> *before* an exception happens how is Tomcat then supposed to tell the
>> client to stop and then display a different page?
>>
>> p
>>
>>
>>
>>> Thanks,
>>
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
> For additional commands, e-mail: users-help@tomcat.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org