Servlet: Cannot forward after response has been committed

為{幸葍}努か 提交于 2019-12-29 06:33:10

问题


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; you browse example.com/aPage.jsp from France; first I want the servlet to redirect you to example.com/fr/aPage.jsp and then forward you to the resources page.

This is what I have in my servlet:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  ....
  response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
  // after redirect forward the resources page
  RequestDispatcher view = request.getRequestDispatcher(RESOURCES_PAGE);
  view.forward(request, response);
  ...
}

But I get:

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

I know the error appears because I can't use both sendRedirect and forward one after another, but I don't know how to achieve what I want (as described above) without this.

any help?


回答1:


 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 .




回答2:


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.




回答3:


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.




回答4:


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.



来源:https://stackoverflow.com/questions/18211497/servlet-cannot-forward-after-response-has-been-committed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!