SE成長痛日記

アラサーSEが技術力を高めるために日々感じる痛みを綴るBlogです。

JSFのカスタムバリデータを作成する

今回はカスタムバリデータを作成してみます。

入力されたメールアドレスに 特殊な文字があった場合に、エラーをだすように してみたいと思います。

バリデータを作成するにはjavax.faces.validator.Validatorを実装した クラスを作成し、alidate(FacesContext fc, UIComponent uic, Object o) にバリデートの条件を定義します。

ところObject o はStringとMailAddresのどちらが渡ってくるのでしょうか? (コンバート前なのか、後なのか) ちょっと以下のようなコードで検証してみます。

@FacesValidator(value = "mailAddressValidator")
public class MailAddressValidator implements Validator {

    @Override
    public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException {
        if (o == null) {
            return;
        }
        if (o instanceof MailAddress) {
            System.out.println("validate:MailAddress");
        } else if (o instanceof String) {
            System.out.println("validate:String");
        } else {
            System.out.println("validate:その他");
        }
        return;
    }
}

f:id:hirohisoEx:20190309225140p:plain
バリデート
これを見る限り、コンバートされた後のオブジェクトがわたってきていそうです。

では、できるだけデータとそれに関する処理はまとめていきたいため、 MailAddressクラスにチェック処理を作成する方針でやっていきましょう

とりあえずおためしなので、アドレスに&が含まれてたらエラーとしてみます。

@FacesValidator(value = "mailAddressValidator")
public class MailAddressValidator implements Validator {

    @Override
    public void validate(FacesContext fc, UIComponent uic, Object o) throws ValidatorException {
        if (o == null) {
            return;
        }
        if (!(o instanceof MailAddress)) {
            return;            
       } 
       
        if(!((MailAddress)o).isValidMailaddres()){
            throw new ValidatorException(new FacesMessage("無効なアドレスです"));
        }
    }

}
    public boolean isValidMailaddres() {
        if (this.address.contains("&")) {
            return false;
        } else {
            return true;
        }
    }
        <h:form>
            <h:outputLabel>名前</h:outputLabel>
            <h:inputText  value="#{responseBean.name}" p:placeholder="#{responseBean.defaultName}"></h:inputText>
            <h:outputLabel>e-mail</h:outputLabel>
            <h:inputText value="#{responseBean.EMail}" p:placeholder="#{responseBean.defaultEMail}" converter="mailAddressConverter" validator="mailAddressValidator"></h:inputText>
            <div>
                <h:inputTextarea cols="50" rows="10" value="#{responseBean.res}"></h:inputTextarea>
            </div>
            <h:commandButton action="#{responseBean.tweetResponse()}" value="投稿"></h:commandButton>
        </h:form>

f:id:hirohisoEx:20190309230139p:plain
バリデートエラー

このような感じになります。

フェーズを確認すると、バリデーションエラーの場合は、 PROCESS_VALIDATIONS → RENDER_RESPONSE となっていました。