3

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

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

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

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

4

2 回答 2

4

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

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

但是,如果您遇到响应中返回的字段名称与 bean 中的属性名称不匹配的情况,例如,如果您正在返回蛇案例响应(即user_name),但您的 bean 属性名称是username,则必须多一点创意。

在这种情况下,您可以将字段的名称存储为Payloadbean 验证注释上的 a。

响应字段:

@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();
于 2013-07-04T19:04:35.733 回答
1

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

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

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

于 2013-07-04T09:11:51.543 回答