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

This error comes when a Servlet calls the getOutputStream() method on response object for writing something after calling the include() method. Suppose a Servlet calls the include() method to load the response of a JSP. Since JSP has already written the response on it hence again opening OutputStream on response object is illegal, you get the java.lang.IllegalStateException: getWriter() has already been called for this response error. This error also comes when you try to include response of another Servlet and than tries to write something on output stream again. In short, your Servlet should never write anything on response object after calling the include() method. 

Here is the detailed stack trace of exception :
java.lang.IllegalStateException: getWriter() has already been called for this response
org.apache.catalina.connector.Response.getOutputStream(Response.java:580)
org.apache.catalina.connector.ResponseFacade.getOutputStream(ResponseFacade.java:183)
HelloServlet.doGet(HelloServlet.java:20)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:723)


This a perfect beginner error who tries to learn Servlet and JSP by trial and error. If you know the correct way to use the include() and forward() method then you won't face this type of problem. That again highlights the important of learning new technology from a good book like Head First Servlet and JSP. The book will no doubt teach you the basics, which is quite important in the long journey of learning new feature every day.

How to solve java.lang.IllegalStateException: getWriter() has already been called for this response



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

If you look at the error carefully, you can see it pointing to HelloServlet.doGet() method at line 20, let's see the HelloServlet class to find out what's happening at line 20.

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 {
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String userAgent = req.getHeader("user-agent");
        String clientBrowser = "Not known!";
        if (userAgent != null)
            clientBrowser = userAgent;
        req.setAttribute("client.browser", clientBrowser);
        req.getRequestDispatcher("/hello.jsp").include(req, resp);
        resp.getOutputStream().println("This is written from Servlet");
    }

}

You can see that at line 20 we are calling the getOutputStream() after calling the include() method of RequestDispather, this is causing the problem. Remove this line and your program will run fine. The bottom line is you should try to write anything on output stream of Servlet after calling the include() and forward() method because the response is already committed.



No comments:

Post a Comment