Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Java (http://www.velocityreviews.com/forums/f30-java.html)
-   -   [J2EE] RequestDispatcher.include problem (http://www.velocityreviews.com/forums/t144874-j2ee-requestdispatcher-include-problem.html)

John English 07-15-2005 10:11 AM

[J2EE] RequestDispatcher.include problem
 
I have an application where the servlets generate XML and their output
goes through an XSLT filter. This all works fine, except when I try to
use RequestDispatcher's include() method to paste in some external
content. Whenever I try to do this, the XS:T filter bombs out with
an IllegalStateException at the point where it calls getWriter() to
get the output stream. The code looks something like this:

In the servlet, inside doGet(), I have:

println("<html>");
try {
RequestDispatcher disp =
context.getRequestDispatcher("/foo.html");
disp.include(request,response);
}
catch (Exception e) {
System.out.println("Include failed: " + e.getMessage());
// this never happens... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
e.printStackTrace();
}
println("</html>");

(using <html> to delimit HTML content in the enclosing XML).

In the XSLT filter I have:
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws ServletException, IOException {
try {
CharResponseWrapper wrapper =
new CharResponseWrapper((HttpServletResponse)response) ;
chain.doFilter(request,wrapper);
String s = wrapper.toString();
if (s.length() > 0) {
InputSource input = new InputSource(new StringReader(s));
SAXParserFactory spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
SAXParser parser = spf.newSAXParser();
reader = parser.getXMLReader();
stf = (SAXTransformerFactory) TransformerFactory.newInstance();
filter = stf.newXMLFilter(new StreamSource(stylesheet));
filter.setParent(reader);
StreamResult result = new StreamResult(response.getWriter());
// fails here... ^^^^^^^^^^^^^^^^^^^^
// but only when I've used include() in the servelt being filtered!
Transformer transformer = stf.newTransformer();
SAXSource transformSource = new SAXSource(filter, input);
transformer.transform(transformSource, result);
(... and so on...)

Does anyone have any idea why the response writer might end up in
an illegal state because of using include()?


Andrea Desole 07-15-2005 11:44 AM

Re: [J2EE] RequestDispatcher.include problem
 


John English wrote:
> Does anyone have any idea why the response writer might end up in
> an illegal state because of using include()?



the documentation is clear:

IllegalStateException - if the getOutputStream method has already been
called for this response object

maybe the included page uses getOutputStream? Try to call
response.getOutputStream instead of getWriter

Raymond DeCampo 07-15-2005 12:29 PM

Re: [J2EE] RequestDispatcher.include problem
 
John English wrote:
> I have an application where the servlets generate XML and their output
> goes through an XSLT filter. This all works fine, except when I try to
> use RequestDispatcher's include() method to paste in some external
> content. Whenever I try to do this, the XS:T filter bombs out with
> an IllegalStateException at the point where it calls getWriter() to
> get the output stream. The code looks something like this:
>
> In the servlet, inside doGet(), I have:
>
> println("<html>");
> try {
> RequestDispatcher disp =
> context.getRequestDispatcher("/foo.html");
> disp.include(request,response);
> }
> catch (Exception e) {
> System.out.println("Include failed: " + e.getMessage());
> // this never happens... ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> e.printStackTrace();
> }
> println("</html>");
>
> (using <html> to delimit HTML content in the enclosing XML).
>
> In the XSLT filter I have:
> public void doFilter(ServletRequest request,
> ServletResponse response,
> FilterChain chain)
> throws ServletException, IOException {
> try {

[snip]
> StreamResult result = new StreamResult(response.getWriter());
> // fails here... ^^^^^^^^^^^^^^^^^^^^
> // but only when I've used include() in the servelt being filtered!

[snip]
> (... and so on...)
>
> Does anyone have any idea why the response writer might end up in
> an illegal state because of using include()?
>


Here's a thought. The servlet API allows you to get a writer to write
the response or a stream to write the response, but not both. It is
possible that the RequestDispatcher.include() used the stream, not the
writer, thereby hosing your future attempt to use the writer.

HTH,
Ray

--
XML is the programmer's duct tape.

John English 07-17-2005 03:25 AM

Re: [J2EE] RequestDispatcher.include problem
 
Andrea Desole wrote:
> John English wrote:
>
>> Does anyone have any idea why the response writer might end up in
>> an illegal state because of using include()?

>
> the documentation is clear:
>
> IllegalStateException - if the getOutputStream method has already been
> called for this response object
>
> maybe the included page uses getOutputStream? Try to call
> response.getOutputStream instead of getWriter


The included page is just vanilla HTML. (Well, XHTML, suitable for shoving
through an XSLT filter.)

So, maybe include() uses getOutputStream() rather than getWriter(), which is
what I use everywhere else. In which case, it's a waste of space AFAICS.

Anyway, in the meantime I'm just creating a FileInputStream and reading from
that instead... Most of the J2EE API just seems to be designed to prevent you
doing anything useful in a finite amount of time!

However, when I get some free time to ponder this without worrying about
hitting targets, I might well investigate further... Suggestions welcome
in the meantime from anyone with more experience and/or free time.

Thanks...


John English 07-18-2005 04:35 PM

Re: [J2EE] RequestDispatcher.include problem
 
Andrea Desole wrote:

> John English wrote:
>
>> Does anyone have any idea why the response writer might end up in
>> an illegal state because of using include()?

>
> the documentation is clear:
>
> IllegalStateException - if the getOutputStream method has already been
> called for this response object
>
> maybe the included page uses getOutputStream? Try to call
> response.getOutputStream instead of getWriter


The included page is plain old HTML, not a servlet, so any streams needed
to include it must be opened by the server when it serves up the page...

Could try getOutputStream, but the examples I've seen show the base servlet
using getWriter and including another resource as well. What puzzles me is
that the error occurs in the filter, not in the original servlet. From examples
on Sun's website, I would expect what I've done to be perfectly legit.


junaid 07-19-2005 04:15 AM

Re: RequestDispatcher.include problem
 
have you tried to add following in web.xml

<filter-mapping>
<filter-name>VJFilterTest</filter-name>
<!--<servlet-name>VJServlet</servlet-name>-->
<url-pattern>/servlet/MyTest</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>


Andrea Desole 07-19-2005 07:54 AM

Re: [J2EE] RequestDispatcher.include problem
 


John English wrote:
>
> The included page is plain old HTML, not a servlet, so any streams needed
> to include it must be opened by the server when it serves up the page...


that's probably what happens

>
> Could try getOutputStream, but the examples I've seen show the base servlet
> using getWriter and including another resource as well. What puzzles me is
> that the error occurs in the filter, not in the original servlet. From
> examples
> on Sun's website, I would expect what I've done to be perfectly legit.
>


why should you have it in the servlet? You are not calling
response.getWriter there, are you?
I don't know the examples you are talking about (do you have a url?),
but looking better at the documentation I saw that getWriter should be
used for non binary streams, while for binary and mixed streams you
should use getOutputStream. So I was guessing that maybe setting the
content type to "text/html" (and maybe the character encoding) at the
beginning of the filter, before anything is written to the response,
might help.

Anyway, if you really need a writer you can use:

new PrintWriter( response.getOutputStream() );


All times are GMT. The time now is 12:11 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.