[J2EE] RequestDispatcher.include problem

Discussion in 'Java' started by John English, Jul 15, 2005.

  1. John English

    John English Guest

    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()?
     
    John English, Jul 15, 2005
    #1
    1. Advertising

  2. 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
     
    Andrea Desole, Jul 15, 2005
    #2
    1. Advertising

  3. 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.
     
    Raymond DeCampo, Jul 15, 2005
    #3
  4. John English

    John English Guest

    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, Jul 17, 2005
    #4
  5. John English

    John English Guest

    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.
     
    John English, Jul 18, 2005
    #5
  6. John English

    junaid Guest

    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>
     
    junaid, Jul 19, 2005
    #6
  7. 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() );
     
    Andrea Desole, Jul 19, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Paul Vincent Craven

    Multiple includes with RequestDispatcher

    Paul Vincent Craven, Aug 29, 2003, in forum: Java
    Replies:
    0
    Views:
    659
    Paul Vincent Craven
    Aug 29, 2003
  2. Will Handley
    Replies:
    1
    Views:
    593
    Nigel Wade
    Dec 10, 2003
  3. Ryan Stewart

    RequestDispatcher.include() behavior

    Ryan Stewart, May 20, 2004, in forum: Java
    Replies:
    0
    Views:
    505
    Ryan Stewart
    May 20, 2004
  4. Joshua
    Replies:
    2
    Views:
    448
  5. Replies:
    0
    Views:
    591
Loading...

Share This Page