请求调度程序转发在包含任何servlet之后不转发

时间:2012-12-30 04:57:07

标签: java java-ee servlets requestdispatcher

有人请帮助我。

 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);
}

这两个函数已经编写在我项目的每个servlet中,问题是当我在servlet中首先使用这两个函数时包含(“servlet / abc”,request.response);之后它使用了forward(“servlet / def”,request.response);所以使用Netbeans 7我一步一步地看着前进不是转发servlet的控制但是当我在转发前不使用include时它转发控件。

所以我想知道为什么会发生这种情况,原因是什么以及如何在包含任何servlet之后向前推进。

请有人帮助我...这是一个有趣的问题。

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


forward("servlet/def",request, response);   //HERE IS PROBLEM NOT FORWRDING AFTER INCLUDE

3 个答案:

答案 0 :(得分:6)

无论究竟为什么你似乎都会观察到这种行为,你所尝试的东西永远不会奏效。根据{{​​3}}的约定,“如果响应已经提交,则此方法抛出IllegalStateException”,并且“响应缓冲区中的未提交输出在转发之前自动清除。”

因此,无论转发是否成功,您都无法在转发之前和之后成功将内容发送回用户。这是因为转发的目的是允许“一个servlet对请求进行初步处理而另一个资源生成响应”,而不是让两个不同的servlet生成响应的不同部分。在Servlet模型中,生成响应始终只属于一个servlet。

如果您不知道“已提交”和“未提交”的含义,则为RequestDispatcher.forward()。当您撰写回复时,您实际上是在写referring to whether the response status and headers have been sent to the user yet。什么都不会立即发送。只要你写的所有东西仍然是本地的,你就可以自由地做任何事情,包括local buffer并重新开始,就像前锋一样,但是一旦发出一些东西,你就会承诺并且可以不再改变你将要做的事情。响应可以通过几种方式提交(即全部或部分发送给用户),包括填充缓冲区以便必须发送它以为更多内容腾出空间,resetting the buffer手动或刷新

flushing the bufferWriter回复。

最终,在你的情况下发生的可能是你正在使用include编写一些东西,并且它导致响应被提交,要么是因为你填充了缓冲区,要么是因为我似乎记得一个包含通常会导致自动刷新(不确定这个文档)。然后当你尝试转发时,它会抛出所需的IllegalStateException,你应该在你的日志中看到它,但是不会引起典型的500响应状态,因为正如我所讨论的那样,你已经提交了其他一些状态代码。

答案 1 :(得分:2)

提交响应后,您无法更改响应状态或状态。当您使用请求调度程序包含某个页面时,您实际上正在提交响应,并且数据开始发送到客户端。之后,您不允许将响应状态更改为302,这是重定向所必需的。

如果您尝试,则会收到错误java.lang.IllegalStateException: Cannot forward after response has been committed

答案 2 :(得分:0)

RequestDispatcher只有两种方法:

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;
}

您将其作为

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

但是在API中只提到servlet请求对象和响应对象作为参数,所以我猜你应该从那里删除你的url。如果我错了,请纠正我,因为我也在学习。