Ale*_*ühl 6 cdi jsf-2 prerenderview
我对执行的顺序和执行次数有疑问f:event type="preRenderView".
在这里我的搜索,我发现从BalusC在通常的回答这个和这个职位涉及到我的问题-它仍然留下了两个问题要问:
当我f:event type="preRenderView"在模板文件中放置一个(用于管理常见任务,例如关于适用于我所有视图的用户状态的检查)和f:event type="preRenderView"每个视图中的另一个(用于处理视图特定的初始化)时,我想知道为什么调用视图中的监听器方法在模板之前.
当我把所有内容按照建议放在<f:metadata><f:event [..] /></f:metadata>后面时ui:define,它会在从登录页面重定向到该页面后被调用两次,但是当我将它调高一级后才ui:composition调用一次.
更新:示例
以下示例演示了上述行为:
这是模板文件template_test.xhtml,包含一个preRenderView事件监听器,用于调用所有视图的处理程序中的公共方法:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xml:lang="de" lang="de" xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<link rel="stylesheet" type="text/css" href="../resources/css/style.css" />
</h:head>
<h:body>
<f:event type="preRenderView" listener="#{testHandler.initCommon()}" />
<div id="content">
<ui:insert name="content" />
</div>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
这是视图文件test.xhtml,还包含一个侦听器,用于preRenderView在处理程序中调用视图特定方法的事件,以及通过处理程序方法重定向的命令按钮:
<?xml version="1.0" encoding="UTF-8"?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
template="template_test.xhtml">
<ui:define name="content">
<f:metadata>
<f:event type="preRenderView"
listener="#{testHandler.initIndividual()}"></f:event>
</f:metadata>
<h:form>
<h:commandButton value="Redirect" action="#{testHandler.redirect()}" />
</h:form>
</ui:define>
</ui:composition>
Run Code Online (Sandbox Code Playgroud)
这是TestHandler.java包含3种方法的处理程序类:
package test;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
@Named
@SessionScoped
public class TestHandler implements Serializable {
private static final long serialVersionUID = -2785693292020668741L;
public void initCommon() {
System.out.println("Common init called.");
}
public void initIndividual() {
System.out.println("Init for individual page called.");
}
public String redirect() {
return "test/test.xhtml?faces-redirect=true";
}
}
Run Code Online (Sandbox Code Playgroud)
现在,这是我在tomcat日志中查看请求测试页面时看到的内容:
Init for individual page called.
Common init called.
Init for individual page called.
Run Code Online (Sandbox Code Playgroud)
这显示没有.1,视图中的事件处理程序在模板之前调用,而不是.2,从视图中调用事件处理程序两次.
它还显示了第三点(这就是为什么我包含一个重定向到同一页面的按钮的原因),显示如果通过重定向请求页面会发生什么 - 单个页面被调用的次数更多:
Init for individual page called.
Common init called.
Init for individual page called.
Init for individual page called.
Run Code Online (Sandbox Code Playgroud)
两个都没有.通过将整个元数据部分放在上面,ui:define或者通过向视图的元数据部分添加虚拟参数(可以不包含在URL中),可以防止2和3 :
<f:metadata>
<f:viewParam name="dummyToDenySecondRedirect" />
<f:event type="preRenderView"
listener="#{testHandler.initIndividual()}"></f:event>
</f:metadata>
Run Code Online (Sandbox Code Playgroud)
有人能告诉我这些案件的原因吗?
我可以重现它.这是由/WEB-INF/beans.xmlCDI 的存在和隐含因此引起的.甚至在保留beans.xml文件时切换回标准JSF注释时也会发生这种情况.这已经作为问题1771和问题2162报告.然而,由于缺少具体的WAR文件来重现问题和低票,Mojarra开发人员并没有费心去仔细研究它.
我再次将其作为问题2719报告.可以用一个较小的例子重现该问题:
<!DOCTYPE html>
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
>
<f:metadata>
<f:event type="preRenderView" listener="#{bean.preRenderView}" />
</f:metadata>
<h:head>
<title>preRenderView fail</title>
</h:head>
<h:body>
<p>On initial request, you'll see the listener being invoked twice instead of only once.</p>
<p>On every postback by the below button, you'll see the listener being invoked once more.</p>
<h:form>
<h:commandButton value="submit" />
</h:form>
<p>Note however that this increments every time you issue the postback.</p>
<p>If you remove <code>/WEB-INF/beans.xml</code> and redeploy, then the issue will disappear.</p>
</h:body>
</html>
Run Code Online (Sandbox Code Playgroud)
和
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class Bean {
public void preRenderView() {
System.out.println("preRenderView called");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8683 次 |
| 最近记录: |