我正在使用 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 类访问该字段和所有可用注释,但没有成功。
假设虽然 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));
}
}