• cdi
  • components
  • contexts
  • converters
  • eventlisteners
  • exceptionhandlers
  • facesviews
  • filters
  • functions
  • managedbeans
  • renderkits
  • resourcehandlers
  • scripts
  • taghandlers
  • utils
  • validators
  • viewhandlers
-
  • Eager
  • FacesConverter
  • FacesValidator
  • Param
  • ViewScoped

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 foo.

 @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 bar.

 @Inject @Param(name="foo")
 private String bar;

Standard types for which JSF already has a build in converter like String, Long, 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 http://example.com/mypage?user=42:

 @Inject @Param(converter="userConverter", validator="priviledgedUser")
 private User user;

Note that the converter and validator attributes can be specified in 3 ways:

  • A string value representing the converter/validator ID like so converter="userConverter".
  • An EL expression returning the converter/validator ID string like so converter="#{bean.converterId}".
  • An EL expression returning the concrete converter/validator instance like so converter="#{converterBean}".

In case the converted parameter value is not serializable, while the managed bean is serializable, you could inject it into a field of type ParamValue, with 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 true.

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.

Demo

Click the links below:

The following parameters will be injected and validated as:

  • "text1" is injected as String and is validated as JSF required="true"
  • "text2" is injected as String and is validated as JSF <f:validateLength minimum="3">
  • "text3" is injected as String and is validated as JSR303 (Bean Validation) @NotNull
  • "number" is injected as Integer with automatic JSF integer conversion
  • "date" is injected as Date and is converted as JSF <f:convertDateTime pattern="yyyyMMdd">
  • "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!

  • text1: Validation Error: Value is required.
  • text3 is required
Source code
<p>Click the links below:</p>
<ul>
    <li>
        <h:link value="Set all params">
            <f:param name="text1" value="foo" />
            <f:param name="text2" value="bar" />
            <f:param name="text3" value="baz" />
            <f:param name="number" value="42" />
            <f:param name="date" value="19780326" />
            <f:param name="nsEntity" value="abc" />
        </h:link>
    </li>
    <li>
        <h:link value="Omit required param and set wrong values on others">
            <f:param name="text2" value="x" />
            <f:param name="number" value="NaN" />
            <f:param name="date" value="26 Mar 1978" />
        </h:link>
    </li>
</ul>
<p>The following parameters will be injected and validated as:</p>
<ul>
    <li>"text1" is injected as <code>String</code> and is validated as JSF <code>required="true"</code></li>
    <li>"text2" is injected as <code>String</code> and is validated as 
        JSF <code>&lt;f:validateLength minimum="3"&gt;
    </code></li>
    <li>"text3" is injected as <code>String</code> and is validated as JSR303 (Bean Validation) <code>@NotNull</code></li>
    <li>"number" is injected as <code>Integer</code> with automatic JSF integer conversion</li>
    <li>"date" is injected as <code>Date</code> and is converted as 
        JSF <code>&lt;f:convertDateTime pattern="yyyyMMdd"&gt;</code>
    </li>
    <li>"nsEntity" is injected as <code>ParamValue&lt;NonSerializableEntity&gt;</code> and is 
        converted as JSF <code>&lt;f:converter converterId="nonSerializableEntityConverter"/&gt;</code>
        <small>(the example also demonstrates support for non-serializable values, which is important for CDI's passivating scopes)</small>
    </li>
</ul>

<p>Result: #{cdiParamBean.result}</p>
<h:messages styleClass="messages" infoClass="info" errorClass="error" />