英文:
Validating class which cannot be modified by add new annotations
问题
这个模型是由一些工具生成的。特定字段例如使用 @NotNull 注解进行了标注。我不能修改生成的类。我需要对生成的类进行额外的验证,比如检查字符串字段的值是否包含空字符串,然后抛出 ConstraintViolationException 异常。目前,我需要迭代遍历类来查找字符串字段的类型,然后在空字符串的情况下,我需要实现自己的 ConstraintViolation 接口,这非常困难。所以看起来像这样:
Validator validator = Validation.buildDefaultValidatorFactory()
.getValidator();
Set<ConstraintViolation<E>> validationErrors = validator.validate(aEntity);
Field[] fields = aEntity.getClass().getDeclaredFields();
for (Field f : fields) {
Class<?> type = f.getType();
if (type == String.class) {
try {
String v = (String) f.get(aEntity);
// 检查值是否不是空字符串
if (v == null || !v.trim().isEmpty()) {
validationErrors.add(new ConstraintViolation<E>() {
@Override
public String getMessage() {
return null;
}
@Override
public String getMessageTemplate() {
return null;
}
@Override
public E getRootBean() {
return null;
}
@Override
public Class<E> getRootBeanClass() {
return null;
}
@Override
public Object getLeafBean() {
return null;
}
@Override
public Object[] getExecutableParameters() {
return new Object[0];
}
@Override
public Object getExecutableReturnValue() {
return null;
}
@Override
public Path getPropertyPath() {
return null;
}
@Override
public Object getInvalidValue() {
return null;
}
@Override
public ConstraintDescriptor<?> getConstraintDescriptor() {
return null;
}
@Override
public <U> U unwrap(Class<U> type) {
return null;
}
});
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
是否有可能使这个过程更简单?
英文:
the model is generated by some tools. Particular fields are annotated by for instance @NotNull annotation. I cannot modify generated classes. I need to do additonal validation of generated classes like check that value of the string field does't contain empty string and then throw ConstraintViolationException. Currently I iterate over the class to find field type of String and then in case of empty string I need to implement my own ConstraintViolation interface which is deadly hard. So it looks like that:
Validator validator = Validation.buildDefaultValidatorFactory()
.getValidator();
Set< ConstraintViolation< E > > validationErrors = validator.validate(aEntity);
Field[] fields = aEntity.getClass().getDeclaredFields();
for (Field f : fields) {
Class<?> type = f.getType();
if (type == String.class) {
try {
String v = (String) f.get(aEntity);
// check that value is not an empty string
if (v == null || !v.trim().isEmpty()) {
validationErrors.add(new ConstraintViolation<E>() {
@Override
public String getMessage() {
return null;
}
@Override
public String getMessageTemplate() {
return null;
}
@Override
public E getRootBean() {
return null;
}
@Override
public Class<E> getRootBeanClass() {
return null;
}
@Override
public Object getLeafBean() {
return null;
}
@Override
public Object[] getExecutableParameters() {
return new Object[0];
}
@Override
public Object getExecutableReturnValue() {
return null;
}
@Override
public Path getPropertyPath() {
return null;
}
@Override
public Object getInvalidValue() {
return null;
}
@Override
public ConstraintDescriptor<?> getConstraintDescriptor() {
return null;
}
@Override
public <U> U unwrap(Class<U> type) {
return null;
}
});
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Is it possible to make this easier?
答案1
得分: 0
以下是翻译好的部分:
- 对于无法编辑类以添加验证注解的情况,有两种选项:
通过XML指定约束
要使用这种方法,您需要添加一个 META-INF/validation.xml
文件,然后在其中定义/重新定义您的约束:
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings
xmlns="https://jakarta.ee/xml/ns/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://jakarta.ee/xml/ns/validation/mapping
https://jakarta.ee/xml/ns/validation/validation-mapping-3.0.xsd"
version="3.0">
<!-- 请注意,您可以使用 ignore-annotations
来忽略任何注解约束或包含它们,具体取决于您的需求 -->
<bean class="com.acme.common.model.SomeType" ignore-annotations="false">
<field name="someField">
<constraint annotation="jakarta.validation.constraints.NotBlank"/>
[...]
</field>
[...]
</bean>
</constraint-mappings>
有关更多详细信息,您可以查看规范的此部分。
编程约束定义
另外,Hibernate Validator提供了以编程方式添加约束的方法:
HibernateValidatorConfiguration configuration = Validation
.byProvider( HibernateValidator.class )
.configure();
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.field( "manufacturer" )
.constraint( new NotNullDef() )
.field( "licensePlate" )
.ignoreAnnotations( true )
.constraint( new NotNullDef() )
.constraint( new SizeDef().min( 2 ).max( 14 ) )
.type( RentalCar.class )
.getter( "rentalStation" )
.constraint( new NotNullDef() );
Validator validator = configuration.addMapping( constraintMapping )
.buildValidatorFactory()
.getValidator();
有关更多详细信息,请查看Hibernate Validator文档的此部分。
如果您不知道哪些字段需要应用非空/空白约束,您可以尝试使用反射遍历字段,然后根据该信息通过编程API定义约束。一旦将约束添加到验证器中,您应该能够只需使用 Validator#validate(..)
来进行验证。
英文:
For cases when it is not possible to edit the classes to add validation annotations to it there are two options:
Specifying the constraints via XML
To use this approach you'd need to add a META-INF/validation.xml
and then inside of it you can define/redefine your constraints:
<?xml version="1.0" encoding="UTF-8"?>
<constraint-mappings
xmlns="https://jakarta.ee/xml/ns/validation/mapping"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
https://jakarta.ee/xml/ns/validation/mapping
https://jakarta.ee/xml/ns/validation/validation-mapping-3.0.xsd"
version="3.0">
<!-- note that you can use ignore-annotations
to either ignore any annotation constraints
or include them, depending on your needs -->
<bean class="com.acme.common.model.SomeType" ignore-annotations="false">
<field name="someField">
<constraint annotation="jakarta.validation.constraints.NotBlank"/>
[...]
</field>
[...]
</bean>
</constraint-mappings>
for more details you should check this section of the specification.
Programmatic constraint definition
Alternatively, Hibernate Validator provides a way to add constraints programmatically:
HibernateValidatorConfiguration configuration = Validation
.byProvider( HibernateValidator.class )
.configure();
ConstraintMapping constraintMapping = configuration.createConstraintMapping();
constraintMapping
.type( Car.class )
.field( "manufacturer" )
.constraint( new NotNullDef() )
.field( "licensePlate" )
.ignoreAnnotations( true )
.constraint( new NotNullDef() )
.constraint( new SizeDef().min( 2 ).max( 14 ) )
.type( RentalCar.class )
.getter( "rentalStation" )
.constraint( new NotNullDef() );
Validator validator = configuration.addMapping( constraintMapping )
.buildValidatorFactory()
.getValidator();
For more details, check this section of the Hibernate Validator documentation.
If you do not know which fields will need not empty/blank constraint being applied you can try to iterate through the fields using the reflection and then based on that information define the constraints via programmatic API. once constraints are added to the validator you should be able to just use Validator#validate(..)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论