来自程序的Bean验证消息

时间:2013-07-03 23:50:14

标签: java field message bean-validation

我有一个带有验证注释的bean。我将使用以下代码手动触发验证:

 Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
 Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, validationGroup);

我的问题是,1。)如何获得验证失败的字段和2.)如何获取相关消息?

我不想使用.properties文件。没有前端可以显示。但它是一项服务,我需要发送失败的验证消息和验证失败的字段的响应。

2 个答案:

答案 0 :(得分:4)

  

如何获得验证失败的字段?

验证失败的字段将在MethodConstraintViolationException中返回。您可以通过调用getConstraintViolations()来检索单个违规行为,然后getPropertyPath()可以检索该字段并遍历节点。

但是,如果您遇到响应中返回的字段名称与bean中的属性名称不匹配的情况,例如,如果您要返回snake case响应(即user_name),但是bean属性名称为username,您必须更具创造性。

在这种情况下,您可以将字段名称作为Payload存储在bean验证注释中。

回复字段:

@JsonProperty("user_name")
@NotEmpty(message = ErrorMessageKeys.USERNAME_REQUIRED, 
          payload = {FieldNamePayload.UserName.class})
private String username;

有效负载类:

public class FieldNamePayload 
{
    /**
     * Represents the field name "user_name"
     */
    public static class UserName implements ValuePayload
    {
        private static final String value = "user_name";

        @Override
        public String getValue() 
        {
            return value;
        }
    }
}

检索异常映射器中的有效负载:

    List<MethodConstraintViolation<?>> violations = new ArrayList<MethodConstraintViolation<?>>(exception.getConstraintViolations());

    for(MethodConstraintViolation<?> violation : violations)
    {
        String field = getFieldName(violation);
        String message = violation.getMessage();

        for(Class<? extends Payload> payload : new ArrayList<Class<? extends Payload>>(violation.getConstraintDescriptor().getPayload()))
        {
            //Retrieve field name from constraint payload
            if(payload.isAssignableFrom(FieldNamePayload.UserName.class))
            {
                field = getPayloadValue(payload);
            }
        }

        //Create an error response here!
    }

  

您如何获得相关消息?

默认情况下,bean验证框架使用以下命名约定在类路径的根目录下查找本地化文件中的消息:

  • ValidationMessages.properties表示默认语言区域。
  • ValidationMessages_{locale}.properties需要本地化时

如果要覆盖此行为并更改从中检索验证消息的位置,可以使用hibernate的验证提供程序并实现您要添加到ResourceBundleLocator的自定义ResourceBundleMessageInterpolator

ValidatorFactory validatorFactory = Validation
    .byProvider(HibernateValidator.class)
    .configure()
    .messageInterpolator(
        new ResourceBundleMessageInterpolator(
            new MyCustomResourceBundleLocator()))
    .buildValidatorFactory();

答案 1 :(得分:1)

关于1,你对场是什么意思? java.lang.reflect.Field?您无法直接访问它。你可以做的是调用ConstraintViolation#getPropertyPath来获取属性路径。您需要迭代节点,并且在叶节点处可以调用例如getName()来获取属性名称,使用getKind()来确定节点的类型。

关于2,ConstraintViolation#getMessage()为您提供插值错误消息

当您说您不想使用属性文件时,我不确定您的意思。 Bean Validation将默认从属性文件(内置的文件或您添加到应用程序中的文件)中读取错误消息。