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

Description

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 available during @PostConstruct, allowing a much easier way of processing without the need for a <f:event type="preRenderView">.

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

*) String is actually not injected itself, but is wrapped in a value holder class called ParamValue. This is due to the fact that a CDI producer cannot produce an arbitrary object and a parameterized wrapper type is needed. For OmniFaces 1.7 we plan to look into a CDI extension to work around this and directly inject the converted type. ParamValue does have merit on its own though, as it allows access to the raw (non-converted) value and allows non-serializable types to be injected into a passivation capable bean. This last feature works by reconverting from the raw value after a bean is restored (changes made to the converted instance before passivation took place will be lost though).

**) NOTE: bean validation at the moment is done against the ParamValue instance that is injected. In many cases this will only be of limited use. We hope to directly inject the converted type in a future OmniFaces version and then bean validation will make more sense.

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>NonSerializableEntity</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" />

<p>
    *) <code>String</code> is actually not injected itself, but is wrapped in a value holder class called <code>ParamValue</code>. This is
    due to the fact that a CDI producer cannot produce an arbitrary object and a parameterized wrapper type is needed. For OmniFaces 1.7
    we plan to look into a CDI extension to work around this and directly inject the converted type. <code>ParamValue</code> does have
    merit on its own though, as it allows access to the raw (non-converted) value and allows non-serializable types to be injected into
    a passivation capable bean. This last feature works by reconverting from the raw value after a bean is restored (changes made to the
    converted instance before passivation took place will be lost though).
</p>

<p>
    **) <b>NOTE:</b> bean validation at the moment is done against the <code>ParamValue</code> instance that is injected. 
    In many cases this will only be of limited use. We hope to directly inject the converted type in a future OmniFaces version and then bean validation 
    will make more sense.
</p>