SeamFramework.orgCommunity Documentation
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)
{
}
}
}
We recommend to always use @RequestScoped
converters/validators unless a
longer scope is required, in which case you should use the appropriate scope annotation, but
it should not be omitted.
Because of the way JSF persists Validators between requests, particularly when using
@Inject
inside a validator or converter, forgetting to use a
@*Scoped
annotation could in fact cause @Inject
'ed
objects to become null.
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 Class | Example |
---|---|
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; } |