Reputation: 7796
I can't get the preRenderView event listener to work on a GET request in JSF 2.1.
I have found a lot about it but nothing seems to work e.g.:
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
I have a template with 4 insert blocks and I have tried to insert the event code at all those places but without any luck. I have tried both with and without the f:metadata tag surrounding it.
<f:event type="preRenderView" listener="#{applicationData.redirectIfNoResults}" />
Bean:
@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");
}
}
...
}
Template:
<?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>
View:
<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>
Please help me figure out how to get it working..
Update 1:
I have made changes as suggested by BalusC but it is still not working..
Template:
<?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>
View:
<?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>
Upvotes: 0
Views: 1458
Reputation: 7796
I ended up making a solution with a PostConstruct method in a view scope bean.
Like this: Initializng a Backing Bean With Parameters on Page Load with 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();
}
}
}
...
}
View:
<?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>
Upvotes: 0
Reputation: 1108632
That <f:view>
isn't rightly used, it has to wrap the entire view. Remove it (JSF will implicitly create one), or at least let it wrap the entire view, including <h:head>
and <h:body>
tags.
By the way, the <f:event>
does not need to go in a <f:metadata>
. That applies only to <f:viewParam>
. A <f:event>
listener which depends on results of <f:viewParam>
is indeed often for sole self-documentary purposes also placed in the same <f:metadata>
block, but that is thus not a requirement of <f:event>
itself.
In your case, it'd be easier to just put it in <ui:define name="content">
.
Upvotes: 2
Reputation: 2435
ComponentSystemEvent seems to be missing in the method signature.
Method needs to look like this:
public void newRequest(final ComponentSystemEvent event) {
System.out.println("Someone requested me");
}
And then place a caller in the template or in the seperate views, that won't do any difference.
<f:event listener="#{userSessionAction.newRequest}" type="preRenderView"></f:event>
Upvotes: 0