SeamFramework.orgCommunity Documentation

Chapter 5. Faces Artifact Injection

5.1. @*Scoped and @Inject in Validators and Converters
5.2. @Inject'able Faces Artifacts

One of the goals of the Seam Faces Module is to make support for CDI a more ubiquitous experience, by allowing injection of JSF Lifecycle Artifacts into managed beans, and also by providing support for @Inject where it would not normally be available. This section describes the additional CDI integration for faces artifact injection

Frequently when performing complex validation, it is necessary to access data stored in a database or in other contextual objects within the application itself. JSF does not, by default, provide support for @Inject in Converters and Validators, but Seam Faces makes this available. In addition to injection, it is sometimes convenient to be able to scope a validator just as we would scope a managed bean; this feature is also added by Seam Faces.

Notice how the Validator below is actually @RequestScoped, in addition to using injection to obtain an instance of the UserService with which to perform an email database lookup.

@RequestScoped

@FacesValidator("emailAvailabilityValidator")
public class EmailAvailabilityValidator implements Validator
{
   @Inject
   UserService us;
   @Override
   public void validate(final FacesContext context, final UIComponent component, final Object value)
            throws ValidatorException
   {
      String field = value.toString();
      try
      {
         us.getUserByEmail(field);
         FacesMessage msg = new FacesMessage("That email address is unavailable");
         throw new ValidatorException(msg);
      }
      catch (NoSuchObjectException e)
      {
      }
   }
}

An example Converter using @Inject

@SessionScoped

@FacesConverter("authorConverter")
public class UserConverter implements Converter
{
   @Inject
   private UserService service;
 
   @PostConstruct
   public void setup()
   {
      System.out.println("UserConverter started up");
   }
 
   @PreDestroy
   public void shutdown()
   {
      System.out.println("UserConverter shutting down");
   }
 
   @Override
   public Object getAsObject(final FacesContext arg0, final UIComponent arg1, final String userName)
   {
      // ...
      return service.getUserByName(userName);
   }
 
   @Override
   public String getAsString(final FacesContext context, final UIComponent comp, final Object user)
   {
      // ...
      return ((User)user).getUsername();
   }
}

This is the list of inject-able artifacts provided through Seam Faces. These objects would normally require static method-calls in order to obtain handles, but Seam Faces attempts to break that coupling by providing @Inject'able artifacts. This means it will be possible to more easily provide mocked objects during unit and integration testing, and also simplify bean code in the application itself.

Artifact ClassExample
javax.faces.context.FacesContext
public class Bean {
   @Inject FacesContext context;
}
javax.faces.context.ExternalContext
public class Bean {
   @Inject ExternalContext context;
}
javax.faces.application.NavigationHandler
public class Bean {
   @Inject NavigationHandler handler;
}
javax.faces.context.Flash
public class Bean {
   @Inject Flash flash;
}