Tuesday 21 June 2016

java.lang.IllegalStateException: getOutputStream() has already been called for this response

This error comes when you call include() or forward() method after calling  the getOutputStream() from ServletResponse object and writing into it.  This error is similar to java.lang.IllegalStateException: getWriter() has already been called for this response error, which we have seen in the earlier article.

This is the exception:
org.apache.jasper.JasperException: java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:502)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:424)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
HelloServlet.doGet(HelloServlet.java:25)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)

and here is the root cause :


java.lang.IllegalStateException: getOutputStream() has already been called for this response
org.apache.catalina.connector.Response.getWriter(Response.java:611)
org.apache.catalina.connector.ResponseFacade.getWriter(ResponseFacade.java:198)
javax.servlet.ServletResponseWrapper.getWriter(ServletResponseWrapper.java:112)
org.apache.jasper.runtime.JspWriterImpl.initOut(JspWriterImpl.java:125)
org.apache.jasper.runtime.JspWriterImpl.flushBuffer(JspWriterImpl.java:118)
org.apache.jasper.runtime.PageContextImpl.release(PageContextImpl.java:180)
org.apache.jasper.runtime.JspFactoryImpl.internalReleasePageContext(JspFactoryImpl.java:118)
org.apache.jasper.runtime.JspFactoryImpl.releasePageContext(JspFactoryImpl.java:77)
org.apache.jsp.hello_jsp._jspService(hello_jsp.java:80)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:388)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
HelloServlet.doGet(HelloServlet.java:25)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)


If you look at the stack trace it points to 
HelloServlet class, which is our Servlet, the line 25 of HelloServlet seems to be causing the problem.

You can see that we are calling the 
include() method after calling the getOutputStream() on Servlet object. Just comment out the call to getOutputStream() and everything will be Ok.  To learn more about Servlet and JSP,  read Head First Servlet and JSP, one of the best books from last 10 years for learning JSP and Servlet.


Here is the complete Java Servlet for your testing, you can run this Servlet into Tomcat right from your Eclipse IDE.

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloServlet extends HttpServlet {

    public void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletExceptionIOException {
        String userAgent = req.getHeader("user-agent");
        String clientBrowser = "Not known!";
        if (userAgent != null) {
            clientBrowser = userAgent;
        }
        req.setAttribute("client.browser", clientBrowser);
        //req.getRequestDispatcher("/hello.jsp").forward(req, resp);

        resp.getOutputStream().println("This is written from Servlet");
        req.getRequestDispatcher("/hello.jsp").include(req, resp);
    }

}

That's all about java.lang.IllegalStateException: getOutputStream() has already been called for this response error in Servlet. You have learned what cause this error and how to fix this. In short, this error comes when you call the
include() or forward() method after committing the response or by calling the getOutputStream() on the response object. 

No comments:

Post a Comment