JSF 2.0 の入力検証

そういやいっちばん基本的なことだったのに書いてなかったな。

コンバータは以前書いたのでバリデータも同様に作ることができる。


でも、ここはJSFのバリデータを呼ぶのではなく、Java EE 6らしくバリデーションも標準化されたBeanValidationを利用したい。BeanValidationはJavaSE単体でも使えるし、JPA 2.0やSpring Framework 3、もちろんRIであるHibernateでも利用できる。いまや標準的なバリデーション機能となった。覚えておいて損はあるまい。

というわけで今回はJSF2 + BeanValidationの組み合わせで入力検証を行う。過去のJSFとBean Validationのエントリをあわせればいいだけだけれども。

javaコード

package jsf;

import javax.faces.bean.ManagedBean;
import javax.validation.constraints.Pattern;

@ManagedBean(name="ローラ姫")
public class HogeBean {
    @Pattern(regexp="(はい|いいえ)" ,message="「はい」または「いいえ」で入力してください")
    String yesno;
    
    //こちらは出力専用
    String message;

    public String getYesno() {
        return yesno;
    }

    public void setYesno(String yesno) {
        this.yesno = yesno;
    }


    //出力専用なのでゲッターのみでよい
    public String getMessage() {
        return message;
    }

    //ボタンクリック時に呼ばれる
    public void po(){
        if(yesno.equals("はい")){
            message = "ローラ「うれしゅうございます。 ぽっ。";
        }else{
            message = "ローラ「そんな ひどい…";
        }
    }
}


テンプレート

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"     xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head><title>ぽっ</title></h:head>
    <body>
        <form jsfc="h:form">
            <h:messages/>
            ローラ「このローラも つれてって くださいますわね?<br/>
            <input jsfc="h:inputText" type="text" value="#{ローラ姫.yesno}"/>
            <f:ajax execute="@form" render="@form">
                <input jsfc="h:commandButton" value="回答" action="#{ローラ姫.po}" />
            </f:ajax>
            <hr/>
            #{ローラ姫.message}
        </form>
    </body>
</html>

実行!ドラゴンクエスト初代のラストのシーン。
「いいえ」を入力したとき。「はい」の場合もコードに書いたメッセージが表示される。
http://shin.cside.com/diary/2010/0915-01.png


それ以外はエラーとなってアクションは実行されない。
http://shin.cside.com/diary/2010/0915-02.png


ちなみに簡単にAjax対応したい場合は以下のとおり挟むだけ。これで画面遷移なし。

            <f:ajax execute="@form" render="@form">
                <input jsfc="h:commandButton" value="回答" action="#{ローラ姫.po}" />
            </f:ajax>


ちなみにCDIを利用している場合、

@Inject
Validator validator;

とするとバリデータが注入されるので、自由にバリデーションしたい場合これを利用するとよい。