我想将请求从 JSF 操作方法转发到非 JSF 页面。 我在我的 JSF 操作中使用以下代码:
public String submitUserResponse() {
// ...
parseResponse("foo.jsp", request, response);
// ...
return "nextpage";
}
private String parseResponse(String uri, HttpServletRequest request, HttpServletResponse response) {
if (uri != null) {
RequestDispatcher dispatcher = request.getRequestDispatcher(uri);
dispatcher.forward(request, response);
return null;
}
// ...
return "xxxx";
}
当用户从 JSF 页面单击提交按钮时,将调用 submitUserResponse()
操作方法,该方法返回 nextpage
字符串。此处请求以正常流程转发到下一个 JSF 页面。但在我的要求中,我需要将请求转发到下一个非 JSF 页面。它正在运行,但它在服务器中显示以下异常。
java.lang.IllegalStateException: Cannot forward after response has been committed
我观察到 parseResponse(...)
和 return "nextpage";
之间的代码行在使用 dispatched.forward 转发我的请求后仍在执行(uri)
。 response.sendRedirect(url)
也发生了同样的事情。这是怎么引起的,我该如何解决?
最佳答案
Here my doubts are: 1.why next lines of code is being executed after forwarding my request using dispatched.forward(uri) . Same thing happening in response.sendRedirect("").
因为你没有调用return
跳出方法 block 。 include()
、forward()
或 sendRedirect()
确实没有一些魔法,它们会自动自动这样做。与其他任何方法一样,这些仍然只是 Java 方法(当然 System#exit()
除外)。它们将按顺序调用,代码将继续执行直到方法 block 或 return
语句结束。这只是您自己编写和控制的代码流。
也就是说,正常的 JSF 做法是您应该使用 ExternalContext#dispatch()
或 ExternalContext#redirect()
为此(第一个适用于您的情况)。它不仅使您的代码免于 JSF 代码(如 Servlet API)中不必要的“底层”困惑,而且还消除了调用 FacesContext#responseComplete()
的需要。您也可以这样做来解决您最初的 IllegalStateException
问题。
简而言之:将您的代码替换为
public void submitUserResponse(){
String uri = "foo.jsp";
FacesContext.getCurrentInstance().getExternalContext().dispatch(uri);
}
就是这样。无需从 JSF 引擎盖下不必要地挖掘 Servlet 请求/响应。请注意,该方法被声明为 void
。这是完全可以接受的,尽管有些像 IDE 这样的专家会提示它,如果是这样,那么只需忽略它或替换为 String
并添加 return null;
。
另见:
关于jsf - 如何在操作方法中将请求转发到非 JSF 页面?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1922154/