protobuf 生成的 Java 对象上的级联 bean 验证不起作用
Posted
技术标签:
【中文标题】protobuf 生成的 Java 对象上的级联 bean 验证不起作用【英文标题】:Cascaded bean validation on protobuf generated Java object not working 【发布时间】:2021-11-10 16:06:45 【问题描述】:我正在尝试使用 Bean Validation 来验证 protobuf 消息生成的 Java 对象。我正在使用Hibernate Validator's Programmatic constraint definition fluent API。它适用于直接对象字段(实际上我正在验证“getters”),但由于某种原因valid()
方法没有触发级联对象的验证。
我尝试创建常规 Java 对象(没有验证注释的 POJO,只有我正在测试的字段的 getter)并应用相同的 Hibernate 验证器约束映射 - 它可以正常工作。
您知道为什么这种方法不适用于从 protobuf 消息生成的 Java 对象吗?
// protobuf example
message Car
com.mycompany.Driver driver = 1;
string manufacturer = 2;
...
message Driver
string name = 1;
...
// Java code
configuration.createConstraintMapping()
.type(Car.class)
.getter("driver")
.valid()
.getter("manufacturer")
.constraint(new NotEmptyDef())
.type(Driver.class)
.getter("name")
.constraint(new NotEmptyDef());
...
Car car = new Car();
car.setDriver(new Driver());
validator.validate(car);
// then - validation does not validate Driver object
【问题讨论】:
【参考方案1】:一位同事发现了一个问题。我们不得不更改DefaultGetterPropertySelectionStrategy
(link to documentation)。默认情况下,getter 方法被视为方法Object get*()
、boolean is*()
和boolean has*()
。由于从 protobuf 生成的 Java 类包含 boolean has*()
来指示该属性是否可用 - 它被 Hibernate Validator 错误地用作有效的 getter 方法。
所以,解决方案是基于DefaultGetterPropertySelectionStrategy
创建自定义getter方法策略,排除has*()
。然后在创建Validator
时注册为:
...
Validator validator = configuration.addMapping(configuration.createConstraintMapping())
.getterPropertySelectionStrategy(new ProtobufGetterPropertySelectionStrategy())
.buildValidatorFactory()
.getValidator();
【讨论】:
以上是关于protobuf 生成的 Java 对象上的级联 bean 验证不起作用的主要内容,如果未能解决你的问题,请参考以下文章