Download
FAQ
History
PrevHomeNext API
Search
Feedback
Divider

Writing Backing Bean Methods

Methods of a backing bean perform application-specific functions for components on the page. These functions include performing validation on the component's value, handling action events, handling value-change events, and performing processing associated with navigation.

By using a backing bean to perform these functions, you eliminate the need to implement a Validator interface to handle the validation or a Listener interface to handle events. Also, by using a backing bean instead of a Validator implementation to perform validation, you eliminate the need to create a custom tag for the Validator implementation. Creating a Custom Validator describes implementing a custom Validator. Implementing an Event Listener describes implementing a listener class.

In general, it's good practice to include these methods in the same backing bean that defines the properties for the components referencing these methods. The reason is that the methods might need to access the component's data to determine how to handle the event or to perform the validation associated with the component.

This section describes the requirements for writing the backing bean methods.

Writing a Method to Handle Navigation

A backing bean method that handles navigation processing--called an action method--must be a public method that takes no parameters and returns a String, which is the logical outcome string that the navigation system uses to determine what page to display next. This method is referenced using the component tag's action attribute.

The following action method in CashierBean is invoked when a user click the Submit button on the bookcashier.jsp page. If the user has ordered more than $100 (or 100 euros) worth of books, this method sets the rendered properties of the fanClub and specialOffer components to true. This causes them to be rendered on the page the next time the page is rendered.

After setting the components' rendered properties to true, this method returns the logical outcome null. This causes the JavaServer Faces implementation to rerender bookcashier.jsp page without creating a new view of the page. If this method were to return purchase (which is the logical outcome to use to advance to bookcashier.jsp, as defined by the application configuration resource file), the bookcashier.jsp page would rerender without retaining the customer's input. In this case, we want to rerender the page without clearing the data.

If the user does not purchase more than $100 (or 100 euros) worth of books or the thankYou component has already been rendered, the method returns receipt.

The default NavigationHandler provided by the JavaServer Faces implementation matches the receipt outcome, as well as the starting page (bookcashier.jsp) against the navigation rules in the application configuration resource file to determine which page to access next. In this case, the JavaServer Faces implementation loads the bookreceipt.jsp page after this method returns.

public String submit() {
  ...
  if(cart().getTotal() > 100.00 && 
    specialOffer.isRendered() != true)
  {
    specialOfferText.setRendered(true);
    specialOffer.setRendered(true);
    return null;
  } else if (specialOffer.isRendered() == true && 
    thankYou.isRendered() != true){
    thankYou.setRendered(true);
    return null;
  } else {
    clear();
    return ("receipt");
  }
} 

How the Pieces Fit Together provides more detail on this example. Referencing a Method That Performs Navigation explains how a component tag references this method. Binding a Component Instance to a Bean Property discusses how the page author can bind these components to bean properties. Writing Properties Bound to Component Instances discusses how to write the bean properties to which the components are bound. The section Configuring Navigation Rules provides more information on configuring navigation rules.

Writing a Method to Handle an ActionEvent

A backing bean method that handles an ActionEvent must be a public method that accepts an ActionEvent and returns void. This method is referenced using the component tag's actionListener attribute. Only components that implement ActionSource can refer to this method.

The following backing bean method from LocaleBean of the Duke's Bookstore application processes the event of a user clicking one of the hyperlinks on the chooselocale.jsp page:

public void chooseLocaleFromLink(ActionEvent event) {
  String current = event.getComponent().getId();
  FacesContext context = FacesContext.getCurrentInstance();
  context.getViewRoot().setLocale((Locale)
    locales.get(current));
} 

This method gets the component that generated the event from the event object. Then it gets the component's ID. The ID indicates a region of the world. The method matches the ID against a HashMap that contains the locales available for the application. Finally, it sets the locale using the selected value from the HashMap.

Referencing a Method That Handles an ActionEvent explains how a component tag references this method.

Writing a Method to Perform Validation

Rather than implement the Validator interface to perform validation for a component, you can include a method in a backing bean to take care of validating input for the component.

A backing bean method that performs validation must accept a FacesContext, the UIInput component whose data must be validated, and the data to be validated, just as the validate method of the Validator interface does. Only values of UIInput components or values of components that extend UIInput can be validated. A component refers to this method via its validator attribute.

Here is the backing bean method of the CheckoutFormBean in the Coffee Break example:

public void validateEmail(FacesContext context, 
  UIComponent toValidate, Object value) {
  
  String message = "";
  String email = (String) value;
  if (email.indexOf('@') == -1) {
    ((UIInput)toValidate).setValid(false);
    message = CoffeeBreakBean.loadErrorMessage(context, 
      CoffeeBreakBean.CB_RESOURCE_BUNDLE_NAME,
      "EMailError");
    context.addMessage(toValidate.getClientId(context),
      new FacesMessage(message));
  }
} 

The validateEmail method first gets the local value of the component. It then checks whether the @ character is contained in the value. If it isn't, the method sets the component's valid property to false. The method then loads the error message and queues it onto the FacesContext, associating the message with the component ID.

See Referencing a Method That Performs Validation for information on how a component tag references this method.

Writing a Method to Handle a Value-Change Event

A backing bean that handles a ValueChangeEvent must be a public method that accepts a ValueChangeEvent and returns void. This method is referenced using the component's valueChangeListener attribute.

The Duke's Bookstore application does not have any backing bean methods that handle value-change events. It does have a ValueChangeEvent implementation, as explained in the Implementing Value-Change Listeners section.

For illustration, this section explains how to write a backing bean method that can replace the ValueChangeEvent implementation.

As explained in Registering a ValueChangeListener on a Component, the name component of the bookcashier.jsp page has a ValueChangeListener registered on it. This ValueChangeListener handles the event of entering a value in the field corresponding to the component. When the user enters a value, a ValueChangeEvent is generated, and the processValueChange(ValueChangeEvent) method of the ValueChangeListener class is invoked.

Instead of implementing a ValueChangeListener, you can write a backing bean method to handle this event. To do this, you move the processValueChange(ValueChangeEvent) method from the ValueChangeListener class, called NameChanged, to your backing bean.

Here is the backing bean method that processes the event of entering a value in the name field on the bookcashier.jsp page:

public void processValueChangeEvent(ValueChangeEvent event)
  throws AbortProcessingException {
  if (null != event.getNewValue()) {
    FacesContext.getCurrentInstance().
      getExternalContext().getSessionMap().
        put("name", event.getNewValue());
  }
}   

The page author can make this method handle the ValueChangeEvent emitted by a UIInput component by referencing this method from the component tag's valueChangeListener attribute. See Referencing a Method That Handles a ValueChangeEvent for more information.

Divider
Download
FAQ
History
PrevHomeNext API
Search
Feedback
Divider

All of the material in The J2EE(TM) 1.4 Tutorial is copyright-protected and may not be published in other works without express written permission from Sun Microsystems.