【问题标题】:Bean Validation Messages from the Program来自程序的 Bean 验证消息
【发布时间】:2013-07-03 23:50:14
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: java field message bean-validation


    【解决方案1】:

    如何获取未通过验证的字段?

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

    但是,如果您遇到响应中返回的字段名称与 bean 中的属性名称不匹配的情况,例如,如果您返回的是蛇案例响应(即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();
    

    【讨论】:

    • 如果我不想覆盖消息,而只想获取默认验证消息?
    • 默认消息位于 MessageConstraintViolation 对象上。调用 getMessage() 方法。看看上面的异常映射器代码。
    • 非常感谢您的澄清!
    【解决方案2】:

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

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

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

    【讨论】:

    • 1.) 字段表示,bean 变量/属性。不是“场”。如果我指定了@NotNull,并且如果该变量未通过此约束,我需要能够获取消息 2.) 使用 Bean 验证错误消息的属性文件对错误消息进行谷歌搜索返回了我的示例。但是,我不打算使用它。
    猜你喜欢
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多