如何通过单个 Jakarta/Hibernate 验证器使用所有注释进行验证?

问题描述 投票:0回答:1

我正在使用 Jakarta/Hibernate 来验证 Java 中的一些字段。

问题是数据模型是从 Swagger 文件生成的,因此所有 Jakarta 注释(如 @Size 或 @Pattern)都是自动生成的。

我无法更改 Swagger 来生成一些自定义注释,但我必须根据分配给特定字段的所有约束/注释创建一条验证消息。

我的想法是实现自定义的MessageInterpolator。我可以使用 HibernateValidatorConfiguration 类获取默认插值器并设置约束映射:

 constraintMapping.constraintDefinition(->annotation here<-)
.validateBy(MyValidator.class);

configurationHibernate.addMapping(constraintMapping)
.messageInterpolator(myInterpolator);

如您所见,它只能处理一个注释,但我只想一次为所有注释编写一个验证器和一个插值器,以获得最小、最大、模式值,并根据它们创建一条消息。

有没有办法实现这样的实现,从特定字段获取所有可用注释并根据可用注释创建消息?

值得一提的是,一个字段可以拥有@Size和@Pattern,但另一个字段只能拥有@Size。对于这两个类字段,我想使用相同的验证器/消息插值器并动态创建消息。

我知道这不是 Hibernate 的设计方式,所以欢迎任何其他建议。 :)

我试图通过 Jakarta 验证 Context 类访问该字段和所有可用注释,但没有成功。

java spring-boot hibernate-validator jakarta-validation
1个回答
0
投票

假设虽然 Swagger 是生成对象的对象,但您仍然需要读取值并从中创建 POJO,您可以使用

jackson.databind.ObjectMapper
进行反序列化,并使用
javax.validation
类来触发注释验证。

public static <T> T deserialize(String serialized, Class<T> cls) throws JsonProcessingException {
  ObjectMapper mapper = new ObjectMapper();
  return mapper.readValue(serialized, cls);
}

public static <T> T deserializeAndValidate(String serialized, Class<T> cls) throws JsonProcessingException {
  T result = deserialize(serialized, cls);
  validateObject(result);   return result;
}

public static void validateObject(Object object) {
  ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
  Validator validator = factory.getValidator();
  Set<ConstraintViolation<Object>> opsConfigViolations = validator.validate(object, new Class[0]);
  if (!opsConfigViolations.isEmpty()) {
    throw new ValidationException(String.format("Validation failed for object of type '%s': %s", object.getClass().getName(), opsConfigViolations));
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.