Java EE CDI ViewScoped example

20 February 2014
By Gonçalo Marques
In this tutorial we will cover the Java EE CDI ViewScoped scope.

Introduction

Java EE 7 introduced a new set of CDI bean scopes. One of them - and the one we will cover in this article - is the view scope. As with other CDI beans, we configure a view scoped bean by using the @ViewScoped annotation.

View scoped beans have the same life time as the view which initially referenced them. This means that their scope is shorter that session, but greater than request. As soon as a view references a view scoped bean, the CDI container will create a new bean instance and reuse it across the view life time.

This behaviour may be useful when we need to provide Ajax functionality within a JSF view: Since the view scoped beans will keep state during the view life time, and consequently across subsequent bean action method invocations, we may develop a kind of conversation between the client and the server. We issue requests to the server and update our view according to the received responses without the need of a full page refresh.

View scoped beans will be discarded by the container as soon as an invoked action method returns a value (a method that is not void). By returning a value we are navigating into a fresh view so the bean should be discarded as it's not needed any more.

This tutorial considers the following environment:

  1. Ubuntu 12.04
  2. JDK 1.7.0.21
  3. Glassfish 4.0

The CDI view scoped bean

We start this example by defining a CDI view scoped bean:

CDI view scoped bean

package com.byteslounge.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class TestBean implements Serializable {

  private static final long serialVersionUID = 1L;

  private List<String> items;
  private String item;

  @PostConstruct
  private void init() {
    items = new ArrayList<>();
    items.add("Item 1");
    items.add("Item 2");
    items.add("Item 3");
  }

  public void addItem() {
    if (item != null && !item.isEmpty()) {
      items.add(item);
      item = null;
    }
  }

  public String getItem() {
    return item;
  }

  public void setItem(String item) {
    this.item = item;
  }

  public List<String> getItems() {
    return items;
  }

}

As we have mentioned before, the view scoped bean must be annotated with @ViewScoped (note that we are using the Java EE 7 CDI view scoped package [javax.faces.view.ViewScoped] and not the one that is managed by JSF).

As soon as the bean instance is created, the method that is annotated with the standard @PostConstruct annotation will be executed. This is where we usually load the needed data in order to support the conversation with the client. In this example we are simply initializing a dummy ArrayList that will hold a list of items.

The client will be able to add new items to the list by the means of an Ajax enabled form, as we will see in the next section.

The view

Now we will define a JSF view that will interact with the view scoped bean we just created:

JSF view

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
  <title>CDI ViewScoped example</title>
</h:head>
<h:body>
  <h:form>
  
    <ui:repeat value="#{testBean.items}" var="item">
      <div>
        <h:outputText value="#{item}" />
      </div>
    </ui:repeat>
    
    <br />
    <h:inputText value="#{testBean.item}" />
    
    <h:commandButton value="Add item" action="#{testBean.addItem}">
      <f:ajax execute="@form" render="@form" />
    </h:commandButton>
    
  </h:form>
</h:body>
</html>

The view is very straight forward: We display the item list along with an input text that allows the user to add more items to the list.

The command button is Ajax enabled, so the form data will be submitted asynchronously to the server and the form will be refreshed with the new list data as soon as the server response arrives. The page will not be fully refreshed (only the form will be refreshed, as we defined in the render attribute of the ajax element within the command button).

Testing

Let's test our sample. As soon as we access the view, a new view scoped bean instance will be created (and initialized) resulting in the following content:

View displaying the list of items
Ajax enabled JSF view

Now we may add new items to the list and confirm that the page will not be fully refreshed. The items list will be preserved across requests so we may confirm that the bean life cycle is behaving as expected.

View containing new items
Ajax enabled JSF view containing new items

The source code used in this article is available for download at the end of this page.

Reference

ViewScoped (Java(TM) EE 7 Specification APIs)

Download source code from this article

Related Articles

Comments

About the author
Gonçalo Marques is a Software Engineer with several years of experience in software development and architecture definition. During this period his main focus was delivering software solutions in banking, telecommunications and governmental areas. He created the Bytes Lounge website with one ultimate goal: share his knowledge with the software development community. His main area of expertise is Java and open source.

GitHub profile: https://github.com/gonmarques

He is also the author of the WiFi File Browser Android application: