JSF 2.1 preRenderEvent不适用于GET请求

问题描述:

我无法让preRenderView事件侦听器在JSF 2.1中的GET请求上工作。JSF 2.1 preRenderEvent不适用于GET请求

我发现了很多关于它,但似乎没有任何工作如:
Conditional redirection in 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, and the 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> 

我最终在视图范围bean中使用PostConstruct方法制作解决方案。
像这样:Initializng a Backing Bean With Parameters on Page Load with JSF 2.0

豆:

@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> 

ComponentSystemEvent似乎在方法签名中缺失。

方法需要看起来像这样:

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

,然后将呼叫者在模板或独立意见,认为不会有什么差别。

<f:event listener="#{userSessionAction.newRequest}" type="preRenderView"></f:event> 
+0

这样的说法是可选的,所以这个答案并不适用。 – BalusC

+0

我以前也试过这个签名,并且在文档中发现我并不需要。我在beforeHeader标签中再次尝试过 - 没有任何改变。你可以使用GET请求来处理页面吗?你能让我的代码工作吗? –

<f:view>不正确地使用,它具有包住整个图。删除它(JSF将隐式创建一个),或者至少让它包装整个视图,包括<h:head><h:body>标记。

顺便说一下,<f:event>不需要去<f:metadata>。这仅适用于<f:viewParam>。取决于<f:viewParam>的结果的听众确实经常用于唯一的自我记录目的被放置在相同的<f:metadata>块中,但这因此不是<f:event>本身的要求。

就你而言,将它放在<ui:define name="content">会更容易。

+0

好的..我已经在内容标签内添加了这一行:''但没有变化.. –

+0

您是否删除/修复了错误''以及? ''即隐含地附在''上,但如果它错误/被破坏,那么这个机会是合理的,它不会被调用。 – BalusC

+0

是 - 我已更新该帖子。 –