tomcat-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Craig R. McClanahan" <>
Subject Re: jsp:include of servlet using getOutputStream
Date Wed, 05 Apr 2000 15:21:06 GMT
Luc Pardon wrote:

> Hello,
>   I'd like to have your opinion on the following issue.
>   I'm jsp:including a servlet and get an IllegalStateException.
>   Bugzilla has a bug report for it, #037, but it was closed for not
> being reproducible. So I looked into this.
>  It turns out this is because the called servlet uses getOutputStream to
> send its data. The calling servlet (code generated from the JSP) uses
> getWriter. Both servlets share the same instance of ServletResponse, and
> you can't use both writer and output streams mechanisms (say the servlet
> specs).
>  I think this is not acceptable. You should be able to jsp:include
> something without having to worry how that "something" is doing its job
> (CGI, servlet, pure HTML, ...). You're including HTML, not a servlet, at
> least that's my view.

Not everyone generates HTML with servlets.  You can generate any content type
you like.  Mixing binary content from a servlet that is creating a dynamic
image, for example, into the HTML or XML generated by a JSP page would not be
a good thing.

Besides, if you are using your servlet for HTML generation but you're using a
ServletOutputStream, you are giving up all the character code conversion that
a PrintWriter does for you automatically, to assist in internationalization of
your pages.

>   I happen to have the source for that particular servlet, but not
> everybody will be so lucky. And I used an OutputStream to sidestep
> locale conversion issues introduced by the dual conversion from bytes to
> chars and back when using a Writer (the servlet is a wrapper for a CGI
> program, I just want to echo the bytes that it sends and was getting
> garbage for non-US character sets).
>   So I reopened bug 037.
>   However, it was closed again, stating that it is a spec issue. I agree
> with that, but don't agree that Tomcat is behaving according to the
> specs. A quick look at the JSP spec doesn't show that including a
> servlet that uses an OutputStream is explicitly forbidden. So I think it
> should be allowed, for the sake of transparency.

The JSP implementation is specified to use the PrintWriter stream from the
servlet response object.  (JSP Spec 1.1 section 6.1.2).  Therefore, any
included object (servlet or JSP page) must also use the writer, not servlet
output stream, to be compliant, because the generated JSP page is a servlet,
and must therefore conform to the servlet API requirements (documented many
places; for example see JSP Spec 1.1, section 2.5).

>   Any way, the specs should be tightened, either to document the
> restriction, or to explicitly state you should be able to include
> anything and/or to draw implementer's attention to this pitfall.
>   What do you think ? Is the Tomcat restriction in agreement with the
> specs or not ?

Yes :-)

> If so, are the specs right or wrong?

Not really relevant to a discussion of Tomcat (see next point)

> Is this list the
> appropriate place at all (if not, where do I take this?).

Feedback EMAIL addresses for both the servlet and JSP specs are on the front
pages of the corresponding spec documents:

There is also the opportunity to review and comment on the public drafts of
new versions of the specification as they come out. There is a current effort,
under the Java Community Process -- see JSR-053 -- to create the next version
of the servlet and JSP specifications.

>   Thanks,
>   Luc Pardon
>   Skopos Consulting
>   Belgium

Craig McClanahan

>   PS for the technically inclined:
>  The fix seems easy (I think). Looking in the Java code, there are tests
> in ServletResponseImpl that check the state the response is in. There is
> also an isIncluded method. Adding an "if not included" to the test would
> not throw the IllegalStateException. As far as I can see this should not
> have side effects, as all the output ultimately goes to the same
> BufferedServletOutputStream.

The difference is that the PrintWriter will have performed any character set
translations specified, while the binary output won't.

>  Alternatively, the included servlet should be given a separate response
> object, and somehow the two should be merged.

In the original servlet spec, there was only ServletOutputStream, and it was
used for both text and binary output.  Beginning with version 2.0, the
PrintWriter version of output was also included, designed to handle text
output -- leaving ServletOutputStream for binary output (dynamic images,
serialized Java objects, downloading binary static files (like a web server
does), and so on.  They serve two different purposes.

Craig McClanahan

View raw message