groupsの指定
【前提条件】
[参考資料]
Bean Validation1.1仕様書
The Java Community Process(SM) Program - communityprocess - final
【グループインターフェイス】
groupsを使用する場合はグループごとに
インターフェイスを作成する必要があります。
各インターフェイスは目印として使うだけなので、
メソッドの定義は不要です。
サンプルでは↓の2つを用意します。
public interface Group01 {} public interface Group02 {}
【Bean】
import javax.validation.constraints.Size; import javax.validation.groups.Default; import javax.ws.rs.FormParam; import jp.glory.sample03.groups.Group01; import jp.glory.sample03.groups.Group02; public class GroupBean { @Size(min = 10, groups = { Default.class }) @FormParam("firstName") private String firstName = null; @Size(min = 10, groups = { Default.class }) @FormParam("lastName") private String lastName = null; @Size(min = 10, groups = { Group01.class, Group02.class }) @FormParam("telephone") private String telephone = null; @Size(min = 10, groups = { Group01.class }) @FormParam("zipCode01") private String zipCode01 = null; @Size(min = 10, groups = { Group01.class }) @FormParam("address01") private String address01 = null; @Size(min = 10, groups = { Group02.class }) @FormParam("zipCode02") private String zipCode02 = null; @Size(min = 10, groups = { Group02.class }) @FormParam("address02") private String address02 = null; @Size(min = 10) @FormParam("note") private String note = null; @FormParam("pattern") private String pattern = null; // アクセサメソッドは省略 }
groupsに先ほど作成したインターフェイスを配列で指定します。
複数のグループでチェックを行いたい場合は配列の中で複数指定します。
javax.validation.groups.Defaultアノテーションは
ValidatorのAPIに標準で用意されているもので、
入力チェック時に必ずチェックが行われるようになります。
groupsに何も指定しない場合、空の配列を指定した場合は
Defaultと同じ挙動になります。
サンプルでは下のようにチェックを行っています。
Default | Group01 | Group02 | |
---|---|---|---|
firstName | ○ | ||
lastName | ○ | ||
telephone | ○ | ○ | |
zipCode01 | ○ | ||
address01 | ○ | ||
zipCode02 | ○ | ||
address02 | ○ | ||
note | ○ |
【Validator】
グループを指定してチェックを行う場合は
Validator#validateにグループの配列を指定します。
Defaultのみを実行させたい場合は↓のようにします。
validator.validate(bean, new Class[] { Default.class }); validator.validate(bean, new Class[] {}); validator.validate(bean);
各グループのみを実行する場合は↓のようにします。
Defaultで指定したプロパティのチェックは行われません。
validator.validate(bean, new Class[] { Group01.class }); validator.validate(bean, new Class[] { Group02.class });
複数のグループを実行する場合は↓のようにします。
validator.validate(bean, new Class[] { Default.class, Group01.class }); validator.validate(bean, new Class[] { Default.class, Group02.class }); validator.validate(bean, new Class[] { Default.class, Group01.class, Group02.class });
【サンプル】
今回のサンプルはグループを利用して、
パターンごとにチェックする項目を変えます。
import java.text.ParseException; import java.util.Set; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import javax.validation.groups.Default; import javax.ws.rs.BeanParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; import jp.glory.sample03.bean.GroupBean; import jp.glory.sample03.groups.Group01; import jp.glory.sample03.groups.Group02; @Path("sample03") public class GroupSampleResource { @Inject private Validator validator = null; @POST public Response postRequest(@BeanParam final GroupBean bean) throws ParseException { final Class<?>[] groups = getGroups(bean); final Set<ConstraintViolation<GroupBean>> result = validator.validate(bean, groups); if (result.isEmpty()) { return createSuccessResponse(); } return createErrorResponse(result); } private Class<Object>[] getGroups(final GroupBean bean) { if ("2".equals(bean.getPattern())) { return new Class[] { Default.class, Group01.class }; } if ("3".equals(bean.getPattern())) { return new Class[] { Default.class, Group02.class }; } if ("4".equals(bean.getPattern())) { return new Class[] { Default.class, Group01.class, Group02.class }; } if ("5".equals(bean.getPattern())) { return new Class[] {}; } return new Class[] { Default.class }; } private Response createErrorResponse(final Set <ConstraintViolation<GroupBean>> validateResult) { 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>"); for (final ConstraintViolation<GroupBean> result : validateResult) { builder.append("<div>"); builder.append(result.getPropertyPath().toString()); builder.append(" : "); builder.append(result.getInvalidValue()); builder.append(" : "); builder.append(result.getMessage()); builder.append("</div>"); } builder.append("</body>"); builder.append("</html>"); return Response.ok(builder.toString()).build(); } private Response createSuccessResponse() { 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>Input value is valid!</div>"); builder.append("</body>"); builder.append("</html>"); return Response.ok(builder.toString()).build(); } }
<!DOCTYPE html> <html> <head> <title>Base Validation</title> <meta charset="UTF-8" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css"> p.label { background: #00ffff; font-weight: bold; } </style> </head> <body> <form method="POST" id="validateForm" action="../service/sample03" > <p class="label">Default</p> <div> <span>First Name : </span> <input type="text" name="firstName" value="" /> </div> <div> <span>Last Name : </span> <input type="text" name="lastName" value="" /> </div> <p class="label">Group01 and Group02</p> <div> <span>Phone : </span> <input type="text" name="phone" value="" /> </div> <p class="label">Group01</p> <div> <span>Zip Code : </span> <input type="text" name="zipCode01" value="" /> </div> <div> <span>Address : </span> <input type="text" name="address01" value="" /> </div> <p class="label">Group02</p> <div> <span>Zip Code : </span> <input type="text" name="zipCode02" value="" /> </div> <div> <span>Address : </span> <input type="text" name="address02" value="" /> </div> <p class="label">No Mark</p> <div> <span>Note : </span> <input type="text" name="note" value="" /> </div> <p class="label">Pattern</p> <div> <select name="pattern"> <option value="1">Default</option> <option value="2">Default + Group01</option> <option value="3">Default + Group02</option> <option value="4">Default + Group01 + Group02</option> <option value="5">No Mark</option> </select> </div> <div> <input type="submit" value="送信" /> </div> </form> </body> </html>
【まとめ】
groupsを使用するとValidatorのAPI内で
チェックする項目を分けることができました。
実際に使う場合は今回のサンプルのように
パターンごとに判定を行い、必要なグループを選択する形になると思います。