JSF 2.2: View actions

With JavaServer Faces 2.2 on the horizon, I am going to start a series on JSF 2.2 features. In my first post of the this series I would like to show how to use view actions.

Starting with JSF 2.0, HTTP GET support was significantly improved with h:link, h:button and view parameters. These tools make it easy to navigate with GET requests and to pass parameters around that are automatically bound to managed beans. Only one aspect was not taken care of: calling actions on GET requests. So JSF 2.2 introduces view actions to fill this gap (yes, there also is PreRenderViewEvent, but it is not completely the same as we will see a below).

For demonstration purposes, I will show a small example with a person list view and a person details view. The list view contains a data table with a h:link component linking the details page for each person:

<h:dataTable value="#{personPage.persons}" var="p">
  <h:column>
    <f:facet name="header">Person</f:facet>
    <h:link value="#{p.name}" outcome="personDetails">
      <f:param name="id" value="#{p.id}"/>
    </h:link>
  </h:column>
</h:dataTable>

Clicking the link in the list view triggers a GET request for the details page with the ID of the person as parameter. The parameter id is mapped to the property personPage.id as view parameter with f:viewParam. Having the ID in the bean, the next step is to load the corresponding person. With JSF 2.2 the easiest way to do this is a view action. View actions are added to the view with the tag f:viewAction inside f:metadata. The action method is referenced as method expression in the attribute action like it is done for h:commandLink or other command components.

The following example shows the view personDetails.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:h="http://java.sun.com/jsf/html">
<f:metadata>
    <f:viewParam name="id" value="#{personPage.id}"/>
    <f:viewAction action="#{personPage.loadPerson}"/>
</f:metadata>
<h:head>
    <title>JSFlive JSF 2.2 - Example 01</title>
</h:head>
<h:body>
  <h:panelGrid columns="2">
    <h:outputText value="Name:"/>
    <h:outputText value="#{personPage.person.name}"/>
    <h:outputText value="Email:"/>
    <h:outputText value="#{personPage.person.email}"/>
  </h:panelGrid>
</h:body>
</html>

View actions are called during the JSF lifecycle (phase 5 by default). The return value of view action methods is used for navigation like it is done for all action methods. There is only one difference: navigation from view actions is always performed as a redirect. The following listing shows the bean PersonPage with the action method referenced above (returning null to stay on the same page).

@ManagedBean
@RequestScoped
public class PersonPage {
  @ManagedProperty("#{personRepository}")
  private PersonRepository personRepository;
  private int id;
  private Person person;

  public String loadPerson() {
    person = personRepository.getPerson(id);
    return null;
  }
  // Getters and setters...
}

By default, view actions are executed in the Invoke Application Phase (phase 5) of the lifecycle. If this is not what you want, view actions can be executed in any phase from 2 to 5. The phase is changed in the phase attribute of f:viewAction with the possible values APPLY_REQUEST_VALUES, PROCESS_VALIDATIONS, UPDATE_MODEL_VALUES and INVOKE_APPLICATION.

The following view action is called in the Apply Request Values Phase (the same could be achieved by setting attribute immediate to true):

<f:viewAction action="#{bean.action}"
    phase="APPLY_REQUEST_VALUES"/>

By default, JSF executes view actions only for initial requests. Additional execution for postback requests can be enable by setting the onPostback attribute of f:viewAction to true. The following view action will be called on initial and postback requests:

<f:viewAction action="#{bean.action}"
     onPostback="true"/>

As mentioned before, the same behavior could have been achieved with a system event listener for PreRenderViewEvent. However, there are some important differences between view actions and listeners for PreRenderViewEvent:

  • View actions can be called in different phases.
  • View actions allow standard navigation (as redirect).
  • Listeners for PreRenderViewEvent are always called on every request.
    View actions are limited to initial requests by default.
  • The component tree is not yet built when view actions are called.

The source code for the JSF 2.2 series examples can be found in the JSFlive Github repository jsf22-examples (module jsf22-view-action).

Further official details about JSF 2.2 can be found in the JSR 344: JavaServer Faces 2.2.

Advertisements

11 responses to “JSF 2.2: View actions

  1. Pingback: JSF 2.2: CollectionDataModel | JSFlive: Michael Kurz's JSF Weblog

  2. Pingback: JSF 2.2 - View actions - Blog - Irian

  3. Pingback: What's new in JSF 2.2? | J-Development

  4. Good day,
    Have you been able to get the HTML 5 Markup Friendly feature to work in JSF 2.2? I have tried this in Glassfish 4.0 b86 but the jsf:value get a value from the managed bean but the input component’s value property is set. Looking at the HTML generated

    becomes

    and so the `value` of input is not set to “Hello World”.

    Regards,
    Mark P Ashworth

    • I did not try the HTML5 integration so far. But covering this topic is on my list for new posts in the JSF 2.2 series. Stay tuned!

      • Hi,
        I got it to work, the issue was the namespaces have changed from http://java.sun.com to http://xmlns.jcp.org. I saw that your git examples are also using the old namespaces which works for 2.1 features but the 2.2 features. Therefore providing the following works.

        Now I just need to get a converter attached to a Bootstrap HTML 5 input date component so that I do not get a conversion null error ;-S

        Regards,
        Mark P Ashworth

      • The reason I sticked with the old namespaces is that there was a problem with the Mojarra version I used. They did not work correctly yet.

  5. Yikes the XML did not show up

    <html xmlns=”http://www.w3.org/1999/xhtml”
    xmlns:h=”http://xmlns.jcp.org/jsf/html”
    xmlns:f=”http://xmlns.jcp.org/jsf/core”
    xmlns:jsf=”http://xmlns.jcp.org/jsf”
    xmlns:p=”http://xmlns.jcp.org/jsf/passthrough”>
    </html>

  6. Pingback: description_news_of_jsf2.2_and_samples_jsf2.2 | mauroprogram's Blog

  7. how to make cascading combos with jsf 2.2?
    Using two h:selectOneMenu and one f:ajax? I tried but could not ;//

    Tks

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s