1

Someone please HELP ME.

 private void forward(String address,
                    HttpServletRequest  request,
                    HttpServletResponse response)
                        throws ServletException, IOException{
    getServletContext()
        .getRequestDispatcher("/" + address)
        .forward(request, response);
}
private void include(String address,
                    HttpServletRequest  request,
                    HttpServletResponse response)
                        throws ServletException, IOException{
    getServletContext()
        .getRequestDispatcher("/" + address)
        .include(request, response);
}

These two functions have been written in every servlet in my project and the problem is that when I have used these two functions in a servlet at first include("servlet/abc",request.response); and after it have used forward("servlet/def",request.response); so using Netbeans 7 I have step by step watched that forward is not forwarding the control of servlet but when I don't use include before the forward its forwarding the control.

So I want to know that why it is happening and what's the reason and how can I do forward after include any servlet.

Please someone HELP ME ...it's an interesting question.

include("servlet/abc",request, response);


forward("servlet/def",request, response);   //HERE IS PROBLEM NOT FORWRDING AFTER INCLUDE
sam
  • 73
  • 3
  • 10
  • I think there is something else going on with include call. – kosa Dec 30 '12 at 05:11
  • What is the logic you have in abc? I guess you might be having a forward over there. – kosa Dec 30 '12 at 05:19
  • @Nambari 51 please tell me should i use out.close() at the end of all forward and includes...???? because i have close it in all servlets so ...and now i have remove it and only close after all the forward and include...??? – sam Dec 30 '12 at 05:23
  • I would give a try. removing out.close() – kosa Dec 30 '12 at 05:27
  • Check your server logs and verify that no exception is being logged when you attempt the forward. If you are closing the output stream in the included servlet you will definitely be getting an illegal state exception if you try and use the output stream in your forwarded servlet. – Perception Dec 30 '12 at 05:49
  • @Nambari ..........thanks alot....i was commiting the response now i have corrected it... – sam Dec 30 '12 at 07:15
  • @Perception ..........thanks alot....i was commiting the response now i have corrected it... – sam Dec 30 '12 at 07:16
  • 2
    You should not be creating new accounts. You should just ask questions the smart way. – BalusC Dec 30 '12 at 12:00

3 Answers3

7

Regardless of exactly why you seem to observe this behavior, what you're attempting will never work. Per the contract of RequestDispatcher.forward(), "If the response already has been committed, this method throws an IllegalStateException," and "Uncommitted output in the response buffer is automatically cleared before the forward."

Therefore, whether the forward succeeds or not, you'll never be able to successfully send content back to the user both before and after a forward. This is because the purpose of a forward is to allow "one servlet to do preliminary processing of a request and another resource to generate the response", not to let two different servlets generate different parts of the response. In the Servlet model, generating a response always belongs to exactly one servlet.

If you don't know what "committed" and "uncommitted" means, it's referring to whether the response status and headers have been sent to the user yet. When you're writing a response, you're actually writing into a local buffer. Nothing will necessarily be sent immediately. As long as everything you've written is still local, you're free to do whatever, including resetting the buffer and starting over, like a forward does, but as soon as something is sent off, you're committed and can no longer change what you were going to do. A response can become committed (i.e. be all or partly sent to the user) in a few ways, including filling up the buffer so that it has to be sent to make room for more content, flushing the buffer manually, or flushing the Writer or OutputStream of a response.

Ultimately, what's probably happening in your case is that you're writing some stuff using an include, and it's causing the response to be committed, either because you've filled the buffer or because I seem to recall that an include generally causes an automatic flush (not sure about documentation on this one). Then when you try to forward, it's throwing the required IllegalStateException, which you should probably see in your logs somewhere, but won't cause the typical 500 response status since, as I've discussed, you've already committed with some other status code.

Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • thank you so much to giving me lots of knowledge about servlet forwarding and response buffer now it will help me to think any logic for servlets and its resposes output genration....Thank You ...!!! – sam Dec 30 '12 at 07:06
2

You cannot change the response status or state once response is committed. When you include some page using request dispatcher you are actually committing response and data is starting to be sent to client. After that you are not allowed to make a change of response status to 302 which is required for redirect.

You will get an error java.lang.IllegalStateException: Cannot forward after response has been committed if you try that.

Subin Sebastian
  • 10,870
  • 3
  • 37
  • 42
0

RequestDispatcher has only two methods:

public interface javax.servlet.RequestDispatcher {
  public abstract void forward(javax.servlet.ServletRequest, javax.servlet.ServletResponse) throws javax.servlet.ServletException, java.io.IOException;
  public abstract void include(javax.servlet.ServletRequest, javax.servlet.ServletResponse) throws javax.servlet.ServletException, java.io.IOException;
}

You are giving it as

include("servlet/abc",request, response);
forward("servlet/def",request, response);

but in the API it is mentioned only servlet request object and response object as parameters, so I guess you should remove your url from there. Correct me if I'm wrong, as I'm also learning.

rgettman
  • 176,041
  • 30
  • 275
  • 357