15
Feb
16

Managed Bean scope for a AJAX JSF Page @RequestScoped vs @ViewScoped


This page will demonstrate the difference between a @RequestScope and @ViewScoped managed bean in a AJAX enabled JSF application.

Background

The @RequestScoped bean lives as long as a single HTTP request-response cycle. This includes AJAX request and responses. At the end of the cycle the bean will be no longer available.

The @ViewScoped managed bean lives as long as you are on the same view like action calls with post-backs that don’t result in the page changing. This includes actions that result in output being sent to another component on the page.

To demonstrate the difference between @ViewScoped and @RequestScoped we will define 2 managed beans each with a different Scope and use them within a AJAX enabled JSF page. We will use the Java EE @PostConstruct and @PreDestroy annotations to print out when each bean is created and destroyed.

Full downloadable source for this page is available here. Corrections and enhancements are welcome, fork, change and push back to GitHub.

Requirements

  • Java 8 or above
  • Maven 3 or above
  • Tomcat 7

Create the pom.xml

vi pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test</groupId>
	<artifactId>JSFTest</artifactId>
	<version>20160215</version>
	<packaging>war</packaging>
	<name>JSFTest</name>

	<pluginRepositories>
		<pluginRepository> <!-- Ignore this repository. Its only used for document publication. -->
			<id>numberformat-releases</id>
			<url>https://raw.githubusercontent.com/numberformat/wordpress/master/20130213/repo/</url>
		</pluginRepository>
	</pluginRepositories>
	
	<repositories>
		<repository>
			<id>prime-repo</id>
			<name>PrimeFaces Maven Repository</name>
			<url>http://repository.primefaces.org</url>
			<layout>default</layout>
		</repository>
	</repositories>

	<dependencies>
		<dependency>
			<groupId>javax</groupId>
			<artifactId>javaee-web-api</artifactId>
			<version>6.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.glassfish</groupId>
			<artifactId>javax.faces</artifactId>
			<version>2.1.6</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>3.0-alpha-1</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.0</version>
		</dependency>

		<dependency>
			<groupId>net.bootsfaces</groupId>
			<artifactId>bootsfaces</artifactId>
			<version>0.8.0</version>
			<scope>compile</scope>
		</dependency>
		<dependency>
			<groupId>org.primefaces</groupId>
			<artifactId>primefaces</artifactId>
			<version>5.3</version>
		</dependency>
		<dependency>
			<groupId>org.primefaces.themes</groupId>
			<artifactId>bootstrap</artifactId>
			<version>1.0.9</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>2.3.2</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
			
			<plugin> <!-- Ignore this plugin. Its only used for document publication. -->
				<groupId>github.numberformat</groupId>
				<artifactId>blog-plugin</artifactId>
				<version>1.0-SNAPSHOT</version>
				<configuration>
					<gitUrl>https://github.com/numberformat/wordpress/tree/master/${project.version}/${project.artifactId}</gitUrl>
				</configuration>
				<executions>
					<execution>
						<id>1</id>
						<phase>site</phase>
						<goals>
							<goal>generate</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
						
		</plugins>
	</build>

</project>

The following is the Request Scoped Managed bean.

vi src/main/java/com/test/AddressBeanRequestScoped.java

package com.test;
 
import java.io.Serializable;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
 
@ManagedBean
@RequestScoped
public class AddressBeanRequestScoped implements Serializable {
 
    private static final long serialVersionUID = 1L;
     
    private Long id;
    private String name;
    private String address;
    private String city;
    private String state;
    private String zip;
 
    @PostConstruct
    void init() {
        System.out.println("Initializing " + this.getClass().getName());
    }
     
    @PreDestroy
    void destroy() {
        System.out.println("Destroying " + this.getClass().getName());
    }
 
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void handleKeyEvent() {
        address = address.toUpperCase();
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getZip() {
        return zip;
    }
    public void setZip(String zip) {
        this.zip = zip;
    }   
}

The following is the View Scoped Managed bean.

vi src/main/java/com/test/AddressBeanViewScoped.java

package com.test;
 
import java.io.Serializable;
 
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
 
@ManagedBean
@ViewScoped
public class AddressBeanViewScoped implements Serializable {
 
    private static final long serialVersionUID = 1L;
     
    private Long id;
    private String name;
    private String address;
    private String city;
    private String state;
    private String zip;
 
    @PostConstruct
    void init() {
        System.out.println("Initializing Address Bean.");
    }
     
    @PreDestroy
    void destroy() {
        System.out.println("Destroying Address Bean.");
    }
 
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void handleKeyEvent() {
        address = address.toUpperCase();
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getState() {
        return state;
    }
    public void setState(String state) {
        this.state = state;
    }
    public String getZip() {
        return zip;
    }
    public void setZip(String zip) {
        this.zip = zip;
    }   
}

The following AJAX enabled JSF page uses both beans.
vi src/main/webapp/ajaxExample.xhtml

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:b="http://bootsfaces.net/ui"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>BootsFaces Basic Page</title>
</h:head>
<h:body>
    <b:container>
        <b:navBar brand="JSF Demo" brandHref="index.xhtml" inverse="true">
            <b:navbarLinks>
                <b:navLink value="More about Ajax"
                    href="http://www.primefaces.org/showcase/ui/ajax/basic.xhtml"></b:navLink>
            </b:navbarLinks>
        </b:navBar>
        <h:form>
 
            <b:panel title="Ajax Listener (on keyUp) View Scoped Bean" look="primary">
                <h:outputText value="Keyup: " />
                <p:inputText value="#{addressBeanViewScoped.address}">
                    <p:ajax event="keyup" update="out"
                        listener="#{addressBeanViewScoped.handleKeyEvent}" />
                </p:inputText>
                <h:outputText id="out" value="#{addressBeanViewScoped.address}" />
            </b:panel>
            <b:panel title="Ajax Listener (on keyUp) Request Scoped Bean" look="primary">
                <h:outputText value="Keyup: " />
                <p:inputText value="#{addressBeanRequestScoped.address}">
                    <p:ajax event="keyup" update="out2"
                        listener="#{addressBeanRequestScoped.handleKeyEvent}" />
                </p:inputText>
                <h:outputText id="out2" value="#{addressBeanRequestScoped.address}" />
            </b:panel>
 
        </h:form>
 
    </b:container>
</h:body>
</html>

And finally the web.xml file.

vi src/main/webapp/WEB-INF/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"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>JSFTest</display-name>

	<welcome-file-list>
		<welcome-file>ajaxExample.xhtml</welcome-file>
	</welcome-file-list>

	<context-param>
		<param-name>primefaces.THEME</param-name>
		<param-value>bootstrap</param-value>
	</context-param>

	<context-param>
		<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
		<param-value>.xhtml</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>*.xhtml</url-pattern>
	</servlet-mapping>

</web-app>

Start tomcat 7 and navigate to the following page:
http://localhost:8080/JSFTest/ajaxExample.xhtml

You should be able to view the difference on the eclipse console or Tomcat 7 console log while you type within the text boxes on the JSF page.

Advertisements

0 Responses to “Managed Bean scope for a AJAX JSF Page @RequestScoped vs @ViewScoped”



  1. Leave a Comment

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 78 other followers

February 2016
S M T W T F S
« Dec   Mar »
 123456
78910111213
14151617181920
21222324252627
2829  

Blog Stats

  • 822,606 hits

%d bloggers like this: