作成 2004/4/26
バリデーションのメモ
バリデーションは、入力値のチェックの仕組みです。 バリデーションはバリデータクラス、あるいはバリデートメソッドを指定することで実行します。 デフォルトのバリデートクラスもいくつかあります。
次の3種類のバリデータはJSFにデフォルトで組み込まれており、 JSPタグ中に指定するだけで利用できます。
クラス | タグ |
---|---|
DoubleRangeValidator | validateDoubleRange |
LengthValidator | validateLength |
LongRangeValidator | validateLongRange |
例えば、文字列の長さをチェックするLengthValidatorは次のように使用します。
<h:form> <p>a: <h:inputText value="#{hoge.s}" <f:validateLength maximum="8"/> </h:inputText> <p><h:commandButton value="GOGO" action="val2"/> <p><h:messages/> </h:form>
実行結果は以下のようになります。バリデーションで、エラーになった場合は、 次の画面に遷移せず(actionは実行されず)、バリデーションのエラーメッセージが表示されます。
必須チェックは、単純にrequired="true"を指定するだけです。
<h:inputText value="#{hoge.s}" required="true"/>
UIInputのタグのvalidate属性にバッキングビーンのメソッドを指定することで、 メソッドによる自作のメソッドによるバリデーションを行うことができます。
<h:inputText value="#{hoge.s}" validator="#{hoge.validateS}"/>
メソッドは次のような引数で定義します。
public void validateS(FacesContext context, UIComponent component, Object value){ String text = value.toString(); if(text.equals("shit")){ context.addMessage(component.getClientId(context), new FacesMessage("下品はダメです")); ((UIInput)component).setValid(false); } }
この例では、"shit"という文字列が入力値に入力されたとき、バリデーションエラーにしています。 エラーにするには、FacesContext#addMessage(...)でエラーメッセージを設定し、UIInput#setValid(...)で 妥当性をfalseに(バリデーションが失敗した状態に)指定してます。
setValidする方法の他に、以下のようにValidatorExceptionをthrowsしても同様のことが行えます。
public void validateS(FacesContext context, UIComponent component, Object value){ String text = value.toString(); if(text.equals("shit")){ throw new ValidatorException(new FacesMessage("下品はダメです")); } }
バリデーションだけに関連するのではありませんが、JSFでのメッセージリソースの取り扱いについて簡単にメモしておきます(予定)。
@TODO
メッセージの追加と表示
指定した場所にメッセージを出す
メッセージの日本語化
グローバルメッセージ
バリデータはクラスとして新たに定義、利用することができます。
次のリストはカスタムバリデータクラスの例です。 バリデータクラスはValidatorインターフェイスを実装して作成します。 validateメソッドの中身は、さきほどのメソッドのバリデータとほとんど同じです。
public class BannedWordValidator implements Validator{ public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { String text = value.toString(); if(text.equals("shit")){ throw new ValidatorException(new FacesMessage("下品はダメです")); } } }
つっこみいただきました。正しくはStateHolderを実装する必要があるようです(そうしないと困る場面がある)。例えばSTATE_SAVING_METHODをclientにしているとき、RegExpValidator.patternの値がnullになります。Validatorに限らず、カスタムうんぬん作るときは全部ですな。
作成したバリデータをJSP側から利用するには、faces-config.xmlへ登録します。
<validator> <validator-id>BannedWordValidator</validator-id> <validator-class>hoge.BannedWordValidator</validator-class> </validator>
JSP側は次のようになります。<f:validator>タグを利用します。 validatorIdにはfaces-config.xmlに登録したidを指定します。
<h:inputText value="#{hoge.s}"> <f:validator validatorId="BannedWordValidator"/> </h:inputText>
上の例では、JSPからバリデータに何らかのパラメータがわたせません。 パラメータを渡したい場合は、バリデータ用のカスタムタグを作成します。
ここで作成するバリデータは正規表現チェックバリデータです。正規表現のパターンを セットできるようにしています。
public class RegExpValidator implements Validator{ private String pattern; public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { String text = value.toString(); if(!text.matches(pattern)){ throw new ValidatorException(new FacesMessage("書式が違うかも")); } } public void setPattern(String pattern){ this.pattern = pattern; } }
このバリデータをfaces-config.xmlに登録します。ここまでは、前の例とほとんど同じですが、 attribute属性に設定できるパラメータを指定しているところが若干異なります。
<validator> <validator-id>RegExpValidator</validator-id> <validator-class>hoge.RegExpValidator</validator-class> <attribute> <attribute-name>pattern</attribute-name> <attribute-class>java.lang.String</attribute-class> </attribute> </validator>
このバリデータに対するカスタムタグは次のようになります。 コンストラクタでバリデータのIDをセットし、createValidator()で、バリデータのインスタンスを作成しています。
public class RegExpValidatorTag extends ValidatorTag{ private String pattern; public RegExpValidatorTag(){ setValidatorId("RegExpValidator"); } protected Validator createValidator() throws JspException { //RegExpValidator validator = new RegExpValidator(); RegExpValidator validator = (RegExpValidator)super.createValidator(); validator.setPattern(pattern); return validator; } public String getPattern() { return pattern; } public void setPattern(String pattern) { this.pattern = pattern; } }
TLDファイルはこうなります。
<tag> <name>validateRegExp</name> <tag-class>hoge.RegExpValidatorTag</tag-class> <attribute> <name>pattern</name> <required>true</required> </attribute> </tag>
JSP側は次のようになります。
<%@ taglib uri="WEB-INF/test.tld" prefix="myh" %> ... <h:inputText value="#{hoge.s}"> <myh:validateRegExp pattern="^.+@.+$"/> </h:inputText>
Sun J2EE 1.4 Tutorial
Chapter18 の Using the Standard Validators と Using Custom Objects
cardemoサンプルのFormatValidator
複数のUIコンポーネントの複合のバリデートはどこに書くべき?アクション? (ex.入力値の合計が100ポイント以下、AはBより小さい)