我想从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:在提交响应后无法转发
我发现在使用parseResponse(...)
转发请求后,return "nextpage";
和dispatched.forward(uri)
之间的代码行仍在执行。 response.sendRedirect(url)
也发生了同样的事情。这是怎么造成的,我该如何解决?
答案 0 :(得分:11)
我怀疑的是:1。为什么在使用dispatched.forward(uri)转发请求后执行下一行代码。在response.sendRedirect(“”)中发生了同样的事情。
因为您没有调用return
跳出方法块。 include()
,forward()
或sendRedirect()
实际上没有一些魔法,他们会自动执行此操作。那些仍然只是Java方法,与其他任何方法一样(当然除System#exit()
之外)。它们将按顺序调用,代码将一直持续到方法块或return
语句结束。这就是代码流你自己编写和控制的全部内容。
也就是说,正常的JSF实践是你应该使用ExternalContext#dispatch()
或ExternalContext#redirect()
(第一个适用于你的情况)。它不仅可以使您的代码免受JSF代码(例如Servlet API)中不必要的“底层”混乱的影响,而且还消除了调用FacesContext#responseComplete()
的需要,您也可以使用它来修复您的初始{ {1}}问题。
简而言之:用
替换你的代码IllegalStateException
这就是全部。无需从JSF引擎盖下不必要地挖掘Servlet请求/响应。请注意,该方法声明为public void submitUserResponse(){
String uri = "foo.jsp";
FacesContext.getCurrentInstance().getExternalContext().dispatch(uri);
}
。这是完全可以接受的,虽然有些知道更好的IDE会抱怨它,如果是这样,那么只需忽略它或替换为void
并添加String
。
答案 1 :(得分:2)
这对我有用:
FacesContext.getCurrentInstance()getExternalContext()调度( “/ ServletUrl”);。。
(特别注意fwd斜线'/')