To minimize session scope bloat, it makes sense to use scope of request as much as possible. Without the redirect element, you can use request scoped beans that are shown in the next view.
However, consider what happens with a redirect.
- The client sends a request to the server.
- The request scope map is populated with the request scoped beans.
- The server sends HTTP 302 (Moved Temporarily) status to the client, together with the redirect location. This ends the current request, and the request scoped beans are removed.
- The client makes a GET request to the new location.
- The server renders the next view. However, the previous request scoped beans are no longer available.
To overcome this problem, JSF 2.0 provides a flash object that can be populated in one request and used in the next. (The flash concept is borrowed from the Ruby on Rails web framework.) A common use of the flash is for messages.
The way the could be used for accessing the flash is by invoking the getFlash() from ExternalContext that already exist in the FacesContext singleton instance. By calling of getFlash() the object that being returned is implements Map<String,Object>. In a JSF page, you reference the flash object with the flash variable. In short, variables stored in the flash scope will survive a redirection and they will be discarded afterwards.
After the message has been rendered and the redirected view has been delivered to the client, the message string is automatically removed from the flash. You can keep a value in the flash for more than one request by using the expression #{flash.keep.message} yields the value of the message key in the flash and adds it back for another request cycle.
Also Read:
1.Managed Bean
IndexBean.java
package net.javabeat.jsf.data; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.RequestScoped; import javax.faces.context.FacesContext; @ManagedBean @RequestScoped public class IndexBean { private String username; private String password; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String login(){ if(username.equalsIgnoreCase("javabeat") && password.equalsIgnoreCase("javabeat")){ FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "You're logged in","")); FacesContext.getCurrentInstance().getExternalContext().getFlash().put("message", new FacesMessage(FacesMessage.SEVERITY_INFO, "You're logged in","")); return "index?faces-redirect=true"; // Redirect } else { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "You're not logged in","")); return ""; // Without Redirection } } }
2. The View
index.xhtml
<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"> <f:view> <h:form> <h1>JavaBeat JSF 2.2 Examples</h1> <h2>JSF2 Redirection & Flash Example</h2> <h:messages globalOnly="true" errorStyle="color:red;" infoStyle="color:blue;"/> <br/> <h:outputText style="color:blue" value="Flash Variable Without Keep: #{flash.keep.message.summary}"/> <h:panelGrid columns="2"> <h:outputText value="Enter Username: "/> <h:inputText value="#{indexBean.username}"/> <h:outputText value="Enter Password: "/> <h:inputText value="#{indexBean.password}"/> </h:panelGrid> <h:commandButton value="Login" action="#{indexBean.login}"/> </h:form> </f:view> </html>
3. Faces Configuration File
faces-config.xml
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd" version="2.2"> <application> <resource-bundle> <base-name>net.javabeat.jsf.application</base-name> <var>msg</var> </resource-bundle> </application> </faces-config>
4. The Deployment Descriptor
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5" metadata-complete="true"> <context-param> <description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2 </description> <param-name>javax.faces.STATE_SAVING_METHOD</param-name> <param-value>client</param-value> </context-param> <context-param> <param-name>javax.faces.application.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config.xml</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> <listener> <listener-class>com.sun.faces.config.ConfigureListener</listener-class> </listener> </web-app>
5. JSF 2 Redirection & Flash Variable Demo
The below snapshots show you the using of flash variable for keeping the messages even if you’ve used the redirection for seeing the next view.
- The user has met the Login screen for entering the username and password.
- Once the user has activated the login action, the method binding has evaluated.
- If you entered the javabeat as username and password, the system will assume that the login operation has finished successfully. A confirmation message has to be shown that confirm you You’re logged in.
- The login action that already executed, has returned you into the same view with a redirection. The redirection kills the request scoped map and the faces message.
- Displaying of confirmation message does take its place cause the message is retained inside the flash variable. See the login implementation within the IndexBean.
- The user has entered a not valid password, the faces message has been shown cause there is no redirection.
- After the message has been rendered and the redirected view has been delivered to the client, the message string is automatically removed from the flash. So the message of flash variable hasn’t rendered.
- This result will be like you’ve seen once you are considering the using of #{flash.keep.message.summary} instead of using #{flash.message.summary}.