是否可以从托管 bean 的构造函数导航到另一个页面/ View ?如果发生任何异常,我想要这个重定向。我尝试了很多方法:
尝试-1:
getFacesContext().responseComplete();
getFacesContext().getApplication().getNavigationHandler().handleNavigation(getFacesContext(), null, "gotoPartError");
getFacesContext().renderResponse();
尝试-2:
getServletResponse().sendRedirect("partError.jspx")
尝试-3:
getFacesContext().responseComplete();
getFacesContext().getExternalContext().redirect(getServletRequest().getContextPath() + "/pages/partError.jspx");
尝试-4:
RequestDispatcher dispatcher = getServletRequest().getRequestDispatcher("partError.jspx");
dispatcher.forward(getServletRequest(), getServletResponse());
尝试-5:
FacesContext context = getFacesContext();
UIViewRoot newPage = context.getApplication().getViewHandler().createView(context, "/partError.jspx");
context.setViewRoot(newPage);
context.renderResponse();
尝试-6:
ControllerContext.getInstance().getCurrentViewPort().setViewId("partError");
尝试-7:
Exception Handler in adfc-config.xml
尝试-8:
Custom service handler defined in /.adf/META-INF/services/oracle.adf.view.rich.context.Exceptionhandler which extends oracle.adf.view.rich.context.Exceptionhandler
尝试-9:
By extending JSF Life Cycle
他们都没有工作。对于我收到的所有案例
java.lang.IllegalStateException: Cannot forward after response has been committed
在 JSF 1.2 中真的不可能吗?由于我使用的是 ADF 11.1.1.6.0,它使用 JSF 1.2,上面的一些“尝试”包含 ADF Faces 方法。
无论如何,我需要使用 JSF 1.2 或 ADF Faces 来导航到错误页面。我获得成功的唯一方法是使用从后端执行的 javascript 打开
_self
中的错误页面。窗口以防出错,但我真的不喜欢它。在这件事上的任何指针都会非常有帮助。
最佳答案
如果了解问题的原因,解决问题就容易多了。一个好的异常(exception)基本上已经说明了问题的原因。
仔细看:
java.lang.IllegalStateException: Cannot forward after response has been committed
响应已提交。这是一个不归路。也许您没有理解响应已提交意味着什么(这导致您也无法理解异常本身)。
默认情况下,HTTP 响应被写入一个缓冲区,该缓冲区每 ~2KB 刷新一次,具体取决于服务器配置。响应缓冲区的刷新导致写入的字节实际上从服务器发送到客户端。一旦第一次发生这种情况,就认为响应已提交。这是一个不归路。服务器无法从客户端取回已写入的字节,以防服务器随后实际需要更改响应。
如果您有一些可能需要更改响应的代码,那么您应该调用它 之前 响应已提交。
在您的特定情况下,托管 bean 显然是在生成 HTML 输出期间的 JSF 呈现响应阶段中构建的。生成的 HTML 输出的一部分已经发送到客户端(因此,响应已提交)。您显然在 JSF 页面中相对较晚地引用了请求范围的 bean,或者响应缓冲区相对较小,或者 HTML
<head>
相对较大,这在 <body>
之前已经导致冲洗开始等等。你真的需要调用代码之前 渲染响应阶段。在 JSF 1.2 中,您可以使用
<f:view beforePhase>
为了这。例如。
<f:view beforePhase="#{bean.navigate}">
和
public void navigate(PhaseEvent event) {
if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
// Do here your job which should run right before the RENDER_RESPONSE.
}
}
然后您的 Try-1 和 Try-3 将起作用(但是您可以将那些
responseComplete()
和 renderResponse()
行放在一边,它们已经隐式地被处理了)。Try-2 和 Try-4 很差。你应该避免使用
javax.servlet.*
在您的支持 bean 中导入。 Try-5 很笨拙。 Try-6、Try-7 和 Try-8 超出了我的范围。 Try-9 是可行的,但非常笨拙。
关于jsf - 从 ADF Faces JSF 1.2 中的托管 bean 构造函数导航,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17509599/