はじめてのBean Validation
Java EE 6のJavadocみていたら(NetBeansにはJava EEのドキュメントも付属している)javax.validationパッケージがあった。
そうだ、こいつもきていたんだった。
というわけでBean Validation (JSR-303)を触ってみる。
こいつはBeanに対する値のチェックをするライブラリである。
検査対象Bean
public class InputBean { @NotNull(message="なんかいれろ") String data; public String getData() { return data; } public void setData(String data) { this.data = data; } }
バリデーションする側。今回はサーブレットでやってる。
@WebServlet(name="ValidateServlet", urlPatterns={"/ValidateServlet"}) public class ValidateServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { InputBean ib = new InputBean(); ib.setData(request.getParameter("data")); ValidatorFactory vf = Validation.buildDefaultValidatorFactory(); Validator v = vf.getValidator(); Set<ConstraintViolation<InputBean>> result = v.validate(ib); String message = ""; for(ConstraintViolation<InputBean> cv : result){ message += cv.getInvalidValue()+":"+cv.getMessage() + "<br>"; } request.setAttribute("message", message); request.getRequestDispatcher("index.jsp").forward(request, response); } }
送信JSP
${message} <form action="ValidateServlet"> <input type="text" name="data" value="${param.data}" > <input type="submit" value="そうしん"> </form>
何も入力しないと「なんかいれろ」と表示されるかと思いきやそうではない。
あくまでも@NotNullはNullかどうかをチェックするためだ。リクエストパラメータ自体がある場合は長さ0の文字列がセットされるためである。
ためしに送信後にURLのパラメータ部分を削除して(GETなのですぐ消せる)サーブレットマッピングそのままでアクセスをすると「なんかいれろ」というバリデーションエラーメッセージが表示される。
では長さをチェックするアノテーションはあるのだろうか。
@Sizeというのがそれだ。
@Size(min=4,max=6,message="{min}から{max}文字の間のみおれが許す") String data;
とやると4文字以上6文字以下というチェックが可能だ。ただし、nullの場合はチェックをしない。必須チェックをしたい場合は先ほどの@NotNullと合わせて@Size(min=1)と利用するとよいだろう。
メッセージについてだが、メッセージのパラメータに4と6の文字列がちゃんと挿入される。全体が「{}」で囲われている場合はメッセージリソースを参照するようだ。
数値の桁範囲チェック
@Digits(integer=4,fraction=1,message="整数{integer}桁、少数{fraction}桁までにしてくださいね♪")
Stringも使えるので便利かもしれない。
integer=9,fraction=0とやればIntegerの範囲内にマッピングできると覚えておくといいかも。
数値の範囲チェック
@Max(29,message="この年増が!") @Min(20,message="この若造が!") Integer data;
こいつはStringはダメ。数値系のみ。
文字列も対象にしたい場合は以下のようにする。
@DecimalMax("29",message="この年増が!") @DecimalMin("20",message="この若造が!") Integer data;
こちらは引数自体も文字列だけあって小数点設定も可能だ。BigDecimalのシンタックスがないからこんなことになってる予感。
@Nullもしくは@NotNull以外は、nullの場合バリデーションをしないので注意しておこう。日時関係もあるが標準のは使い道がないので無視でいいと思う。自分で作ろう!