JAX-RS2.0でBean Validationを使用する
【前提条件】
[参考資料]
JavaEE7 JavaDoc
Java(TM) EE 7 Specification APIs
JAX-RS2.0 仕様書
The Java Community Process(SM) Program - communityprocess - final
【概要】
JAX-RSでBean Validationを使用してみます。
【ソース その1】
[リソースクラス]
import javax.validation.constraints.Size; import javax.ws.rs.BeanParam; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; import jp.glory.resources.bean.SecondValidationBean; @Path("/FirstValidate") public class FirstBeanValidatationResource { @Size(min = 20) @FormParam("firstName") private String firstName = null; @Size(min = 20) @FormParam("lastName") private String lastName = null; @POST public Response postExecute(@BeanParam SecondValidationBean bean) { final StringBuilder builder = new StringBuilder(); builder.append("<html>"); builder.append("<head>"); builder.append("<meta charset=\"utf-8\">"); builder.append("<title>Validation</title>"); builder.append("</head>"); builder.append("<body>"); builder.append("<div>firstName : ").append(firstName).append("</div>"); builder.append("<div>lastName : ").append(lastName).append("</div>"); builder.append("</body>"); builder.append("</html>"); return Response.ok(builder.toString()).build(); } }
今回はjavax.validation.constraints.Sizeアノテーションで
最小サイズを指定います。
これだけでBean Validationによる文字数チェックが行われます。
[実行用のHTML]
送信用のHTMLは↓のようなものを用意します。
(secondSubmitは後で使うものです。)
<!DOCTYPE html> <html> <head> <title>Binding</title> <meta charset="UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script> var firstSubmit = function() { var form = document.getElementById("validateForm"); form.action = "../service/FirstValidate"; form.submit(); }; var secondSubmit = function() { var form = document.getElementById("validateForm"); form.action = "../service/SecondValidate"; form.submit(); }; </script> </head> <body> <form method="POST" id="validateForm" > <div> <span>First Name : </span> <input type="text" name="firstName" value="" /> </div> <div> <span>Last Name : </span> <input type="text" name="lastName" value="" /> </div> <div> <input type="button" value="First送信" onclick="firstSubmit()" /> <input type="button" value="Second送信" onclick="secondSubmit()" /> </div> </form> </body> </html>
[実行]
フォームから20文字以上の値を入力して送信すると
入力した内容がHTMLで表示されます。
20文字未満の値を入力して送信すると
「HTTP Status 400 - Bad Request」の画面が表示されます。
Bean Validationが実行されエラーがある場合、
javax.validation.ConstraintViolationExceptionがスローされます。
そのためStatus400が返されます。
【ソース その2】
その1のソースだとBad Requestになってしまうので、
画面にエラーメッセージを表示するように変えます。
[Bean]
import javax.validation.constraints.Size; import javax.ws.rs.FormParam; public class SecondValidationBean { @Size(min = 20) @FormParam("firstName") private String firstName = null; @Size(min = 20) @FormParam("lastName") private String lastName = null; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
今回はパラメータを受け取るのはBeanに切り出します。
[リソースクラス]
import java.util.Set; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import javax.ws.rs.BeanParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; import jp.glory.resources.bean.SecondValidationBean; @Path("/SecondValidate") public class SecondBeanValidatationResource { @Inject private Validator validator; @POST public Response postExecute(@BeanParam final SecondValidationBean bean) { Set<ConstraintViolation<SecondValidationBean>> errorSet = validator.validate(bean); final StringBuilder builder = new StringBuilder(); builder.append("<!DOCTYPE html>"); builder.append("<html>"); builder.append("<head>"); builder.append("<meta charset=\"utf-8\">"); builder.append("<title>Validation</title>"); builder.append("</head>"); builder.append("<body>"); for (final ConstraintViolation<SecondValidationBean> error : errorSet) { builder.append("<p>").append(error.getMessage()).append("</p>"); } builder.append("<div>firstName : ").append(bean.getFirstName()).append("</div>"); builder.append("<div>lastName : ").append(bean.getLastName()).append("</div>"); builder.append("</body>"); builder.append("</html>"); return Response.ok(builder.toString()).build(); } }
javax.validation.Validatorクラスのオブジェクトをインジェクションしています。
Validator#validateメソッドに検証したいBeanオブジェクトを渡します。
検証した結果はConstraintViolationクラスのSetが返却されます。
サンプルではSetの中身を全て出力しています。
[実行]
エラーがある場合は画面上部に
「size must be between 20 and 2147483647」
と表示されます。
Bean Validationのメッセージを設定していないため、
デフォルトの値が表示されています。