我对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>
这是视图文件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>
这是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";
}
}
现在,这是我在请求测试页面时在我的 tomcat 日志中看到的内容:
Init for individual page called.
Common init called.
Init for individual page called.
这表明没有。1,视图中的事件处理程序在模板中的事件处理程序之前被调用,并且没有。2,从视图中调用事件处理程序两次。
它还显示了第三点(这就是为什么我包含一个带有重定向到同一页面的按钮的原因)显示如果页面被重定向请求会发生什么 - 单个页面被调用更多次:
Init for individual page called.
Common init called.
Init for individual page called.
Init for individual page called.
两者都没有。2 和 3 可以通过将整个元数据部分放在上面ui:define
或通过向视图的元数据部分添加一个虚拟参数来防止,该参数不包含在 URL 中:
<f:metadata>
<f:viewParam name="dummyToDenySecondRedirect" />
<f:event type="preRenderView"
listener="#{testHandler.initIndividual()}"></f:event>
</f:metadata>
有人能告诉我这些案件的原因吗?