2

我正在处理基于 呈现内容的 servlet 页面,geo-location我想同时使用sendRedirect两者forward;例如; 您example.com/aPage.jspFrance; 首先,我希望 servlet 将您重定向到该页面example.com/fr/aPage.jsp,然后将您转发到该resources页面。

这就是我的 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);
  ...
}

但我得到:

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

我知道出现错误是因为我不能同时使用两者sendRedirectforward但我不知道如何在没有这个的情况下实现我想要的(如上所述)。

有什么帮助吗?

4

4 回答 4

4
 response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);
  // after redirect forward the resources page

在该行之后,您的回复开始写入 clinet。

您正在尝试向其中添加其他数据。

服务器已经完成了响应头的写入,并且正在写入内容的主体,而您正在尝试向标头写入更多内容 - 当然它不能倒带。

因此,处理 servlet 时的拇指规则是

在之前完成您的逻辑 redirectforward添加返回语句。因此执行到此结束。

于 2013-08-13T14:18:32.410 回答
3

你打电话时

response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);

您正在向您的客户端发送一个 302 HTTP 状态代码,其中包含要重定向到的位置。然后,您的客户端需要向该位置发出新的 HTTP 请求。无论哪个 Servlet 应该处理该路径REDIRECT_URL_BASED_ON_GEO,都应该使用RequestDispatcher转发到由RESOURCES_PAGE.

为了更好地解释您的异常

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

提交的响应是已经发送 HTTP 标头的响应。如果我们查看您的代码

response.sendRedirect(REDIRECT_URL_BASED_ON_GEO);

在此行之后,您已经发送了响应以及标头 (302)。

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

在这些行之后,您要求资源RESOURCES_PAGE完成对请求的处理。这包括编写 HTTP 标头和正文。但是请求已经被处理,并且已经发送了响应,所以它会失败,抛出异常。

于 2013-08-13T14:17:34.093 回答
1

您必须知道,重定向是对浏览器的完整响应,浏览器将依次向您重定向到的 url 发出新请求。即使在与浏览器打交道时您无法真正了解它,您也必须始终意识到这就是发生的事情。

现在,如果您对第二个请求使用相同的控制器,您必须检查是否需要重定向,或者您现在可以执行转发。

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

当然,每个请求都有一个不同的控制器会更好,但是根据 url 结构和框架,这并不总是可能的。

于 2013-08-14T08:01:51.817 回答
0

重定向后,您正在处理的 servlet 将不再受控制。您需要获取作为重定向目标的 servlet,以识别正确的转发条件,然后在那里调用 forward,代码类似:

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

即使它是同一个 servlet,它也是对 servletdoGet(或其他类似方法的新调用。

于 2013-08-13T14:14:49.377 回答