A common misunderstanding among starters is that they think that the call of a forward(), sendRedirect(), or sendError() would magically exit and “jump” out of the method block, hereby ignoring the remnant of the code. For example:

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    }
    forward(); // This is STILL invoked when someCondition is true!
}

This is thus actually not true. They do certainly not behave differently than any other Java methods (expect of System#exit() of course). When the someCondition in above example is true and you’re thus calling forward() after sendRedirect() or sendError() on the same request/response, then the chance is big that you will get the exception:

java.lang.IllegalStateException: Cannot forward after response has been committed

If the if statement calls a forward() and you’re afterwards calling sendRedirect() or sendError(), then below exception will be thrown:

java.lang.IllegalStateException: Cannot call sendRedirect() after the response has been committed

To fix this, you need either to add a return; statement afterwards

protected void doPost() 
{
    if (someCondition) 
    {
        sendRedirect();
        return;
    }
    forward();
}

… or to introduce an else block.

protected void doPost() {
    if (someCondition) {
        sendRedirect();
    } else {
        forward();
    }
}

Another probable cause is that the servlet writes to the response while a forward() will be called, or has been called in the very same method.

protected void doPost() 
{
    out.write("some string");
    // ... 
    forward(); // Fail!
}

The response buffer size defaults in most server to 2KB, so if you write more than 2KB to it, then it will be committed and forward() will fail the same way:

java.lang.IllegalStateException: Cannot forward after response has been committed

Solution is obvious, just don’t write to the response in the servlet. That’s the responsibility of the JSP. You just set a request attribute like so request.setAttribute(“data”, “some string”) and then print it in JSP like so ${data}

The best way to resolve this problem just set the page (where you suppose to forward the request) dynamically according your logic. That is:

protected void doPost(request , response){
String returnPage="default.jsp";
if(condition1){
 returnPage="page1.jsp";
}
if(condition2){
   returnPage="page2.jsp";
}
request.getRequestDispatcher(returnPage).forward(request,response); //at last line
}