0

我无法让 preRenderView 事件侦听器处理 JSF 2.1 中的 GET 请求。

我发现了很多关于它的信息,但似乎没有任何效果,例如:
JSF 中的条件重定向
http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/#get-prerenderview-event
http://developer.am/j2eetutorial/jsf/?page=jsf-2-prerenderviewevent-example
JSF、Spring 和 PreRenderViewEvent
http://balusc.blogspot.dk/2011/09/communication-in-jsf-20 .html#ProcessingGETRequestParameters

我有一个带有 4 个插入块的模板,我试图在所有这些地方插入事件代码,但没有任何运气。我已经尝试过使用和不使用 f:metadata 围绕它的标签。

<f:event type="preRenderView" listener="#{applicationData.redirectIfNoResults}" />

豆:

@ManagedBean
@ApplicationScoped
public class ApplicationData implements Serializable {
    public void redirectIfNoResults() throws IOException { 
        if (getTotal() < 1) { 
            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); 
            ec.redirect(ec.getRequestContextPath() + "/noResults.xhtml"); 
        } 
    } 
    ...
}

模板:

<?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 xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <ui:insert name="beforeHeader" />
    <f:view>
        <ui:insert name="inView" />
    </f:view>
    <h:head>
        <meta http-equiv="cache-control" content="no-store" />
        <link href="style.css" rel="stylesheet" type="text/css" />
        <title>Quick Poll</title>
        <ui:insert name="header" />
    </h:head>
    <h:body>
        <h1>Quick Poll</h1>
        <ui:insert name="content" />
    </h:body>
</html>

看法:

    <ui:define name="content">
        #{applicationData.question}?<p/>
        <h:panelGrid columns="3" border="0">
                Yes: 
                <h:panelGrid bgcolor="black" height="20" width="#{300*applicationData.yes/applicationData.total}"/>
                #{applicationData.yes}
                <h:outputText value="No:"/> 
                <h:panelGrid bgcolor="black" height="20" width="#{300*applicationData.no/applicationData.total}"/>
                #{applicationData.no}
        </h:panelGrid>
    </ui:define>
</ui:composition>

请帮我弄清楚如何让它工作..

更新 1:
我按照 BalusC 的建议进行了更改,但仍然无法正常工作..

模板:

<?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 xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <meta http-equiv="cache-control" content="no-store" />
        <link href="style.css" rel="stylesheet" type="text/css" />
        <title>Quick Poll</title>
        <ui:insert name="header" />
    </h:head>
    <h:body>
        <h1>Quick Poll</h1>
        <ui:insert name="content" />
    </h:body>
</html>

看法:

<?xml version='1.0' encoding='UTF-8' ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
     template="template.xhtml">
    <ui:define name="content">
        <f:event listener="#{applicationData.redirectIfNoResults}" type="preRenderView"></f:event> 
        #{applicationData.question}?<p/>
        <h:panelGrid columns="3" border="0">
                Yes: 
                <h:panelGrid bgcolor="black" height="20" width="#{300*applicationData.yes/applicationData.total}"/>
                #{applicationData.yes}
                <h:outputText value="No:"/> 
                <h:panelGrid bgcolor="black" height="20" width="#{300*applicationData.no/applicationData.total}"/>
                #{applicationData.no}
        </h:panelGrid>
    </ui:define>
</ui:composition>
4

3 回答 3

2

<f:view>没有正确使用,它必须包装整个视图。删除它(JSF 会隐式创建一个),或者至少让它包裹整个视图,包括<h:head><h:body>标签。

顺便说一句,<f:event>不需要进入<f:metadata>. 这仅适用于<f:viewParam>. 一个<f:event>依赖于结果的听众<f:viewParam>确实经常出于单独的自我记录目的放置在同<f:metadata>一块中,但这不是<f:event>它自己的要求。

在你的情况下,把它放进去会更容易<ui:define name="content">

于 2012-09-09T12:08:47.160 回答
0

方法签名中似乎缺少 ComponentSystemEvent。

方法需要如下所示:

public void newRequest(final ComponentSystemEvent event) {
System.out.println("Someone requested me");
}

然后在模板或单独的视图中放置一个调用者,这不会有任何区别。

<f:event listener="#{userSessionAction.newRequest}" type="preRenderView"></f:event>
于 2012-09-09T11:56:35.220 回答
0

我最终在视图范围 bean 中使用 PostConstruct 方法制作了一个解决方案。
像这样:使用 JSF 2.0 在页面加载时使用参数初始化支持 Bean

豆:

@ManagedBean 
@ViewScoped
public class ResultsController {
    @ManagedProperty(value="#{applicationData.total}")  
    private int total; 
    @ManagedProperty(value="#{applicationData.yes}")  
    private int yes; 
    @ManagedProperty(value="#{applicationData.no}")  
    private int no; 

    @PostConstruct 
    public void postConstruct() {
        if (getTotal() < 1) { 
            ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext(); 
            try {
                ec.redirect(ec.getRequestContextPath() + "/noResults.jsf");
            } catch (IOException e) {
                System.out.println("noResults.jsf redirect failed.");
                e.printStackTrace();
            } 
        } 
    }
    ...
}

看法:

<?xml version='1.0' encoding='UTF-8' ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:c="http://java.sun.com/jsp/jstl/core"
    xmlns:f="http://java.sun.com/jsf/core"
     template="template.xhtml">
    <ui:define name="content">
        #{applicationData.question}?<p/>
        <h:panelGrid columns="3" border="0">
                Yes: 
                <h:panelGrid bgcolor="black" height="20" width="#{300*resultsController.yes/resultsController.total}"/>
                #{resultsController.yes}
                <h:outputText value="No:"/> 
                <h:panelGrid bgcolor="black" height="20" width="#{300*resultsController.no/resultsController.total}"/>
                #{resultsController.no}
        </h:panelGrid>
    </ui:define>
</ui:composition>
于 2012-09-10T13:42:59.637 回答