JSF 2.2ではf:eventのpreRenderViewではなくf:viewActionを使う?

JSF 2.2でf:viewActionというコンポーネントが追加されています。
基本はJSF 2.0で初期画面表示時に処理を動作させる時に使っていた
f:eventのpreRenderViewと同じなのですが微妙に違うところがあります。


まずは単純に呼び出された回数をカウントするバッキングビーンを作ります。

package sample;

import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class ViewAction {
    private int count = 0;
    public int getCount() {
        return count;
    }
    public void init() {
        count++;
    }
}


そして画面

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>ViewAction Sample</title>
    </h:head>
    <h:body>
        <f:metadata>
            <f:viewAction action="#{viewAction.init()}"/>
        </f:metadata>
        <div>Count: #{viewAction.count}</div>
        <h:form>
            <h:commandButton value="Click" />
        </h:form>
    </h:body>
</html>


f:viewActionのactionでバッキングビーンのinitメソッドを呼び出しています。
では実際に動かしてみます。


画面を表示するとinitメソッドが動作してカウントが1と表示されます。
f:id:den2sn:20130624213717p:plain


ボタンを押してもカウントは増えません。
f:eventのpreRenderViewでは画面表示の度に処理が実行されていましたが
f:viewActionでは初期表示時に1回しか動作しないようになっています。


再表示時に処理を動作させたい場合はonPostbackにtrueを指定します。

<f:viewAction action="#{viewAction.init()}" onPostback="true"/>


するとクリックを押す度にカウントが増えて行きます。
f:id:den2sn:20130624214117p:plain


また、f:viewActionでは処理を実行するフェーズを指定する事ができます。
指定出来るフェーズはフェーズ2から5のAPPLY_REQUEST_VALUES, PROCESS_VALIDATIONS,
UPDATE_MODEL_VALUES, INVOKE_APPLICATIONの4種類です。
たとえばAPPLY_REQUEST_VALUESフェーズで処理を実行させたい場合は

<f:viewAction action="#{viewAction.init()}"  phase="APPLY_REQUEST_VALUES"/>


と指定します。
f:eventのpreRenderViewはRenderer Responseフェーズで動作すると思いますが、
f:viewActionでは指定できないのでもしかすると使い分けが必要になってくるかもしれません。


f:viewActionはアクションというだけあってoutcome値を返すことも出来ます。
バッキングビーンで

public String init() {
    return "actionView";
}


とするとactionViewに遷移します。
f:viewParamと組み合わせることでパラメータによって画面分岐等も行うことができるようになっています。


最後におまけですが実は上記サンプルプログラムは現状のGlassFish4.0では動作させることができません。
実はネームスペースのバグがあって
http://xmlns.jcp.org/jsf/core
とすると動作しないようです。
2015/4/26 追記 GlassFish4.1で修正されました。


http://java.sun.com/jsf/core
を指定するとひとまず動作させる事ができます。