tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Kaleb Pederson <kpeder...@mail.ewu.edu>
Subject Re: Subclassing ServletOutputStream/PrintWriter
Date Tue, 03 Aug 2004 17:33:42 GMT
On Tuesday 03 August 2004 7:44 am, Shapira, Yoav wrote:
> >Thus, I can't use the incoming response object to write to.  As there
> >doesn't
> >seem to be a default means of getting at a new outputStream object, or
> >printWriter, I presume that I have to subclass ServletOutputStream or
> >PrintWriter - correct?
>
> No, not correct.  That's the part you're missing.  That's a good thing
> in this case because we'll save you work ;)

Yes! Sounds good to me! :)

> Your servlet using sendError is fine.  You would then configure an error
> page for this error in your web.xml using the <error-page> directive.
> The server will go to this error page, which can be a servlet, JSP, or
> static page as you wish.  This error page will have a fresh response
> object to which you can write whatever you want.

I would expect it to have a fresh response object but it *doesn't*.

I have the <error-page> directive setup and that's what calls my servlet.  If 
I call my servlet directly (http://myhost/myservlet), it works -- I can issue 
getWriter() and getOutputStream():

My code is:

protected void doGet(HttpServletRequest request, HttpServletResponse response) 
throws ServletException, IOException {
	log("Calling getWriter()");		// line 81
	PrintWriter out = response.getWriter(); // line 82
	log("Finished calling getWriter()");	// line 83
	// out.println("blah"); // this works if I call my servlet directly
	
	// ... log to db
}

// tomcat v5's log file....
StandardContext[/kaleb]ErrorLogServlet: Calling getWriter()
StandardContext[/kaleb]ErrorLogServlet: Finished calling getWriter()

Furthermore, anything that I send to the client using out.println("blah") 
makes it to the client.

If I call the other servlet (a commercial servlet that I have no control over) 
via (http://myhost/comservlet/cause_error.xml), it generates an error using 
sendError, which tomcat hands off to my servlet based on the error-page 
directive, but I can't get access to the ServletOutputStream or PrintWriter.

// tomcat's logfile in this case
StandardContext[/kaleb]ErrorLogServlet: Calling getWriter()
ApplicationDispatcher[/kaleb] Servlet.service() for servlet ErrorLogServlet 
threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for 
this response at 
org.apache.coyote.tomcat5.CoyoteResponse.getWriter(CoyoteResponse.java:599) 
at 
org.apache.coyote.tomcat5.CoyoteResponseFacade.getWriter(CoyoteResponseFacade.java:163) 
at ErrorLogServlet.doGet(ErrorLogServlet.java:82)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:697)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:810)
at 
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:237)
...

There is *no* difference in my processing of the servlet being called directly 
and from the other servlet via the error-page directive.  My init function 
only sets up the DB that I log to and doGet is immediately called.  The calls 
to printWriter and getOutputStream are at the very beginning of doGet.

In reading through the docs for sendError it says:

"Sends an error response to the client using the specified status code and 
clearing the buffer. If the response has already been committed, this method 
throws an IllegalStateException. After using this method, the response should 
be considered to be committed and should not be written to. "

I was presuming that the response was, therefore, committed, although I was 
hoping it was only for the duration of the calling servlet and not into the 
life of my servlet, which is why I was leaning toward subclassing 
ServletOutputStream and PrintWriter.

> You don't need to subclass ServletOutputStream or PrintWriter.  In fact
> it's fairly rare that you'd need to extend these for servlet
> applications.

That's what I would expect and hope to be true.

> You can accomplish a similar thing to the above declarative error-page
> behavior by using response.sendRedirect in your original servlet that's
> now using sendError.

Unfortunately, it's a closed-source commercial servlet so I can't change it.  
I've found bugs in it before, so I'm hoping this isn't another one.

Thanks for all the help.

--Kaleb

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


Mime
View raw message