The CDI annotation
Param allows you to inject, convert and validate a HTTP request parameter in a CDI managed bean. It's basically like
<f:viewParam>, but with the major difference that the injected HTTP request parameter is directly available during
PostConstruct, allowing a much easier way of processing without the need for a
<f:event type="preRenderView"> or
<f:viewAction> in the view.
By default the name of the request parameter is taken from the name of the variable into which injection takes place. The example below injects the request parameter with name
@Inject @Param private String foo;
The name can be optionally specified via the
name attribute. The example below injects the request parameter with name
foo into a variable named
@Inject @Param(name="foo") private String bar;
Multi-valued parameters are also supported by specifying a
List or array type. The support was added in OmniFaces 2.4.
@Inject @Param(name="foo") private List<String> foos; @Inject @Param(name="bar") private String bars;
Standard types for which JSF already has a build in converter like
Boolean, etc or for which there's already a converter registered via
forClass, can be injected without explicitly specifying a converter.
@Inject @Param private Long id;
Other types do need a converter. The following is an example of the injection of request parameter
user following a request such as
@Inject @Param(converter="userConverter", validator="priviledgedUser") private User user;
This also works on multi-valued parameters.
@Inject @Param(name="user", converter="userConverter") private List<User> users;
On multi-valued parameters, JSF native conversion and validation will run on each submitted value. Bean Validation, if any, will however be performed on the entire property.
Note that the
validator attributes can be specified in 3 ways:
- A string value representing the converter/validator ID like so
- An EL expression returning the converter/validator ID string like so
- An EL expression returning the concrete converter/validator instance like so
In case the converted parameter value is not serializable, while the managed bean is serializable, you could inject it into a field of type
V the actual type of the converted request parameter. Deserialization in this case works by converting from the original request parameter again.
@Inject @Param(converter="someIdToInputStreamConverter") private ParamValue<InputStream> content; // Extreme example :) Be careful with resource leaking.
If conversion or validation fails,
null is injected if the injection target is NOT
ParamValue. Otherwise a
ParamValue instance is injected, but it will contain a
null value. In both cases, the conversion and validation messages (if any) will be set in the JSF context then, and
FacesContext.isValidationFailed() will return
CDI issues in EAR
Note that CDI has known issues when OmniFaces is bundled in multiple WARs in a single EAR. It's important to understand that those issues are not related to OmniFaces, but to the broken CDI spec. For an overview of those issues, please refer Known issues of OmniFaces CDI features in combination with specific application servers.
Click the links below:
The following parameters will be injected and validated as:
- "text1" is injected as
Stringand is validated as JSF
- "text2" is injected as
Stringand is validated as JSF
- "text3" is injected as
List<String>and is validated as JSR303 (Bean Validation)
- "number" is injected as
Integerwith automatic JSF integer conversion
- "date" is injected as
Dateand is converted as JSF
- "nsEntity" is injected as
ParamValue<NonSerializableEntity>and is converted as JSF
<f:converter converterId="nonSerializableEntityConverter"/>(the example also demonstrates support for non-serializable values, which is important for CDI's passivating scopes)
Result: Validation has failed!