payloadの指定
【前提条件】
[参考資料]
Bean Validation1.1仕様書
The Java Community Process(SM) Program - communityprocess - final
【Payload】
Payloadを指定するためには
javax.validation.Payloadを実装する必要があります。
Payloadにはメソッドは定義されていないため、
目印のためのインターフェイスとなります。
import javax.validation.Payload; public class Category { public static class Name implements Payload{}; public static class Address implements Payload{}; }
サンプルではカテゴリの用途で使用します。
NameとAddressがPayloadを実装しています。
【Bean】
import javax.validation.constraints.Size; import javax.ws.rs.FormParam; import jp.glory.sample04.payload.Category; public class PayloadBean { @Size(min = 10, payload = { Category.Name.class }) @FormParam("firstName") private String firstName = null; @Size(min = 10, payload = { Category.Name.class }) @FormParam("lastName") private String lastName = null; @Size(min = 10, payload = { Category.Address.class }) @FormParam("zipCode") private String zipCode = null; @Size(min = 10, payload = { Category.Address.class }) @FormParam("address") private String address = null; @Size(min = 10) @FormParam("note") private String note = null; // アクセサメソッドは省略 }
各チェック用のアノテーションにはpayload属性があるので、
先ほど作成したNameとAddressを配列の形で指定します。
payloadに指定できるのはClassです。
【チェック結果からの取得】
各アノテーションで指定したpayloadは
入力チェック結果のオブジェクトに付与されます。
final Set<ConstraintViolation<PayloadBean>> validateResult = validator.validate(bean); for (final ConstraintViolation<PayloadBean> result : validateResult) { final ConstraintDescriptor descriptor = result.getConstraintDescriptor(); final Set<Class> payloads = descriptor.getPayload(); }
チェック結果からpayloadを取得するためには
javax.validation.metadata.ConstraintDescriptorを経由して取得します。
ConstraintDescriptor#getPayloadでClassのSetで返却されます。
payloadに何も指定しなかった場合、空のSetが返却されます。
【サンプル】
先ほどの書いたPayloadBeanを使って、
チェック結果でカテゴリを出力するサンプルを作成します。
import java.text.ParseException; import java.util.Set; import javax.inject.Inject; import javax.validation.ConstraintViolation; import javax.validation.Validator; import javax.validation.metadata.ConstraintDescriptor; import javax.ws.rs.BeanParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Response; import jp.glory.sample04.bean.PayloadBean; @Path("sample04") public class PayloadSampleResource { @Inject private Validator validator = null; @POST public Response postRequest(@BeanParam final PayloadBean bean) throws ParseException { final Set<ConstraintViolation<PayloadBean>> result = validator.validate(bean); if (result.isEmpty()) { return createSuccessResponse(); } return createErrorResponse(result); } private Response createErrorResponse(final Set <ConstraintViolation<PayloadBean>> 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<PayloadBean> result : validateResult) { final ConstraintDescriptor descriptor = result.getConstraintDescriptor(); final Set<Class> payloads = descriptor.getPayload(); builder.append("<div>"); for (final Class payload : payloads) { builder.append(payload.getSimpleName()); } builder.append(" : "); 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>Payload 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/sample04" > <p class="label">Category : Name</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">Category : Address</p> <div> <span>Zip Code : </span> <input type="text" name="zipCode" value="" /> </div> <div> <span>Address : </span> <input type="text" name="address" value="" /> </div> <p class="label">Category : None</p> <div> <span>Note : </span> <input type="text" name="note" value="" /> </div> <div> <input type="submit" value="送信" /> </div> </form> </body> </html>
【まとめ】
サンプルではpayloadをNameとAddressにカテゴライズして使用しました。
Bean Validationの仕様書でも
エラー内容の優先度(Info、Error)として使用していたので、
カテゴライズとして使うのがかなり有効なようです。