メッセージの設定

【前提条件】

[環境]
[参考資料]

Bean Validation1.1仕様書
The Java Community Process(SM) Program - communityprocess - final

[その他]

Validatorの生成はCDIを利用しています。

【概要】

BeanValidationのメッセージについてです。

前回のBeanValidationのサンプルでは
デフォルトのメッセージを使用していましたが、
今回は独自にメッセージを定義してみます。

【Bean】

import java.util.Date;
import javax.validation.constraints.DecimalMax;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.Digits;
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.Past;
import javax.validation.constraints.Size;
import javax.ws.rs.FormParam;

public class ValidationBaseBean {

    @DecimalMax(value = "100", message = "DecimalValueは{value}以下で入力してください。")
    @DecimalMin(value = "5", message = "DecimalValueは{value}以上で入力してください。")
    @FormParam("decimalValue")
    private Integer decimalValue = null;

    @Max(value = 20, message = "MaxMinValueは{value}以下で入力してください。")
    @Min(value = 10, message = "MaxMinValueは{value}以上で入力してください。")
    @FormParam("maxMinValue")
    private Integer maxMinValue = null;
  
    @Size(min = 5, max = 10, message = "SizeValueは{min}〜{max}文字で入力してください。")
    @FormParam("sizeValue")
    private String sizeValue = null;

    @Digits(integer = 3, fraction = 2, message = "DigitValueは整数{integer}桁以内、小数{fraction}桁以内で入力してください。")
    @FormParam("digitValue")
    private Double digitValue = null;

    @Future(message = "FutureDateには未来の日付を入力してください。")
    private Date futureDate = null;

    @FormParam("futureDate")
    private String futureDateValue = null;

    @Past(message = "PastDateには過去の日付を入力してください。")
    private Date pastDate = null;

    @FormParam("pastDate")
    private String pastDateValue = null;

    // アクセサメソッドは省略

}

アノテーションにはmessageが設定できるようになっています。

チェックエラーがある場合にはConstraintViolationのメッセージとして
設定した内容が設定されます。

messsageではEL式が使用できるようになっていて、
アノテーションのプロパティが使用できます。

【実行用のリソースクラス】

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
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.sample01.bean.ValidationBaseBean;

@Path("/sample01")
public class ValidationBaseResource {

    @Inject
    private Validator validator = null;
    
    @POST
    public Response postRequest(@BeanParam final ValidationBaseBean bean) throws ParseException {

        bean.setFutureDate(convertDate(bean.getFutureDateValue()));
        bean.setPastDate(convertDate(bean.getPastDateValue()));
        final Set<ConstraintViolation<ValidationBaseBean>> result =  validator.validate(bean);

        if (result.isEmpty()) {

            return createSuccessResponse();
        }

        return createErrorResponse(result);
    }

    private Date convertDate(final String dateValue) throws ParseException {
        final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        if (dateValue.isEmpty()) {
            return null;
        }
        return format.parse(dateValue);
    }

    private Response createErrorResponse(final Set <ConstraintViolation<ValidationBaseBean>> 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<ValidationBaseBean> 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();
    }
}

実行用のソースはJAX-RSを使用してHTMLを出力しています。

【まとめ】

メッセージもアノテーションを設定して出力されるようになっています。

アノテーションで指定しているので国際化対応はできませんが、
日本国内のみで使用する場合には
アノテーションで指定すると良いと思います。