Passing variables in JSF Flash Scope
This tutorial we’ll talk about JSF Flash Scope which is introduced in JSF 2.0 and is utilised when you need to pass parameters between views without the need to store them in the session. Variables stored in the flash scope will be available over a redirection and will be eliminated afterwards. It mostely is used with the POST-redirect-GET pattern.
Managing Values in JSF Flash Scope
Variables stored in the JSF flash scope survive only one redirect and then are deleted. We can read and write values into the JSF Flash Scope. The method setKeepMessages()
stores the messages in the JSF flash scope so they can survive the POST-redirect-GET pattern, so they are available in the next page.
package com.memorynotfound;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import javax.faces.context.Flash;
import javax.faces.event.ComponentSystemEvent;
@ManagedBean
@RequestScoped
public class UserBean {
private String firstName;
private String lastName;
public String goToConfirmView() {
Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
flash.put("firstName", firstName);
flash.put("lastName", lastName);
return "confirm?faces-redirect=true";
}
public String goToInputFormView() {
return "input?faces-redirect=true";
}
public String insertValue() {
Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
flash.setKeepMessages(true);
pullValuesFromFlash(null);
System.out.println("First name: " + firstName);
System.out.println("Last name: " + lastName);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Value inserted"));
return "done?faces-redirect=true";
}
public void pullValuesFromFlash(ComponentSystemEvent e) {
Flash flash = FacesContext.getCurrentInstance().getExternalContext().getFlash();
firstName = (String)flash.get("firstName");
lastName = (String)flash.get("lastName");
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Input values into Flash Scope
If the users decides to go back to the input screen we pull the values from the flash scope with the preRenderView
event.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<f:metadata>
<f:event type="preRenderView" listener="#{userBean.pullValuesFromFlash}"/>
</f:metadata>
<style>
.error {
color: red;
}
</style>
</h:head>
<h:body>
<h1>JSF Flash Scope Example</h1>
<h:form>
<h:messages styleClass="error"/>
<h:panelGrid columns="2">
<h:outputText value="First name:" />
<h:inputText value="#{userBean.firstName}" required="true"/>
<h:outputText value="Last name:" />
<h:inputText value="#{userBean.lastName}" required="true" />
</h:panelGrid>
<h:commandButton value="Next" action="#{userBean.goToConfirmView}" />
</h:form>
</h:body>
</html>
Keep values in the Flash Scope
This page displays the entered values from the input page. The #{flash.keep.firstName}
obtains the values from the flash scope. #{flash.firstName}
would also have worked. And tells JSF to keep the variables in the flash scope for the next request. This is needed because values in the flash scope only survive on redirect and we already had a redirect when entering the values.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:body>
<h1>JSF Flash Scope Example</h1>
<h:form>
<h:panelGrid columns="2">
<h:outputText value="First name:" />
<h:outputText value="#{flash.keep.firstName}" />
<h:outputText value="Last name:" />
<h:outputText value="#{flash.keep.lastName}" />
</h:panelGrid>
<h:commandButton value="Edit" action="#{userBean.goToInputFormView}" />
<h:commandButton value="Confirm" action="#{userBean.insertValue}" />
</h:form>
</h:body>
</html>
Flash Values survive POST-redirect-GET pattern
We obtain the values from the flash scope in the preRenderView
event to add the values to the managed bean. Note: that we are not keeping the values in the flash scope after the user clicks on back to input link.
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<f:metadata>
<f:event type="preRenderView" listener="#{userBean.pullValuesFromFlash}"/>
</f:metadata>
</h:head>
<h:body>
<h1>JSF Flash Scope Example</h1>
<h:messages />
<h:panelGrid columns="2">
<h:outputText value="First name:" />
<h:outputText value="#{userBean.firstName}" />
<h:outputText value="Last name:" />
<h:outputText value="#{userBean.lastName}" />
</h:panelGrid>
<h:link outcome="input" value="Back to input"/>
</h:body>
</html>
Demo
First time we enter values in the flash scope.
Values are put in the flash scope.
Values stil survive in the flash scope.
Values are automatically cleared in the flash scope because of the redirect.