作成 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より小さい)