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; } }
これを見る限り、コンバートされた後のオブジェクトがわたってきていそうです。
では、できるだけデータとそれに関する処理はまとめていきたいため、 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>
このような感じになります。
フェーズを確認すると、バリデーションエラーの場合は、 PROCESS_VALIDATIONS → RENDER_RESPONSE となっていました。