Servlet: Cannot forward after response has been committed

前端 未结 4 1732
难免孤独
难免孤独 2020-12-17 06:22

I\'m working on servlet page that renders content based on geo-location, and I want to use both sendRedirect and forward together; e.g

相关标签:
4条回答
  • 2020-12-17 06:58

    You have to be aware that a redirect is a complete response to the browser and the browser will in turn issue a new request to the url you redirected to. Even though you can't really sse it when dealing with the browser you always have to be aware that this is what happens.

    Now, if you use the same controller for the second request you have to check wether a redirect is necessary or you can now do the forward instead.

    if (!path.startsWith(locationPrefix)) {
      response.sendRedirect(locationPrefix + path);
      return;
    } else {
      RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
      view.forward(request, response);
      return;
    }
    

    Of course it would be nicer to have a distinct controller per request, but depending of url structure and framework this is not always possible.

    0 讨论(0)
  • 2020-12-17 07:04

    When you call

    response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
    

    you are sending your client a 302 HTTP status code with the location to redirect to. Your client then needs to make a new HTTP request to that location. Whichever Servlet is supposed to handle the path REDIRECT_URL_BASED_ON_GEO should then use the RequestDispatcher to forward to the resource described by RESOURCES_PAGE.

    To better explain your exception

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

    a committed response is a response where HTTP headers are already sent. If we look at your code

    response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
    

    After this line, you've already sent the response along with the headers (302).

    RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
    view.forward(request, response);
    

    After these lines, you're asking the resource RESOURCES_PAGE to finish processing the request. That includes writing HTTP headers and body. But the request has already been processed and a response has already been sent, so it will fail, throwing the exception.

    0 讨论(0)
  • 2020-12-17 07:06
     response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
      // after redirect forward the resources page
    

    After that line , Your response start writing to clinet.

    And you are trying to add additional data to it.

    The server has already finished writing the response header and is writing the body of the content, and which point you are trying to write more to the header - of course it cant rewind.

    So,Thumb rule while dealing with servlet is

    Finish your logic before redirect or forward add return statement.So execution ends there .

    0 讨论(0)
  • 2020-12-17 07:06

    Once you redirect, the servlet you're working on is no longer in control. You need to get the servlet that is the target of the redirect to recognize the correct condition to forward and then call forward there, with similar code:

    RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
    view.forward(request, response);
    

    Even if it's the same servlet, it's a new invocation of the servlet's doGet( or other similar method.

    0 讨论(0)
提交回复
热议问题