jsf - 从 ADF Faces JSF 1.2 中的托管 bean 构造函数导航

标签 jsf exception-handling navigation oracle-adf jsf-1.2

是否可以从托管 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/

相关文章:

java - 需要提交两次表格才能处理吗?

css - Primefaces 数据表,嵌套条件行着色

java - 当我将表单发布到另一个页面时,JSP 表单参数消失

php - 在 PHP 中处理文件系统函数的错误和警告的正确方法是什么?

java - Android 应用程序在 Android 8.0 (Google Pixel XL) 上崩溃

python - 使用 Flask 在 Python 中实现面包屑?

jsf - 从当前行数据表中获取 id 以链接 JSF Primefaces Java

java - 重构异常处理

jquery - 尝试创建滚动水平缩略图导航,在不使用时隐藏在左侧

react-native - 在用户未通过身份验证的情况下路由到 native 登录屏幕