51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

验证类,不能通过添加新注解来修改。

英文:

Validating class which cannot be modified by add new annotations

问题 {#heading}

这个模型是由一些工具生成的。特定字段例如使用 @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&lt; ConstraintViolation&lt; E &gt; &gt; validationErrors = validator.validate(aEntity);
Field[] fields = aEntity.getClass().getDeclaredFields();
for (Field f : fields) {
Class&lt;?&gt; 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&lt;E&gt;() {
@Override
public String getMessage() {
return null;
}
@Override
public String getMessageTemplate() {
return null;
}
@Override
public E getRootBean() {
return null;
}
@Override
public Class&lt;E&gt; 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&lt;?&gt; getConstraintDescriptor() {
return null;
}
@Override
public &lt;U&gt; U unwrap(Class&lt;U&gt; type) {
return null;
}
});
}
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}

Is it possible to make this easier?

答案1 {#1}

得分: 0

以下是翻译好的部分:

  1. 对于无法编辑类以添加验证注解的情况,有两种选项:

通过XML指定约束 {#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>

有关更多详细信息,您可以查看规范的此部分

编程约束定义 {#heading-1}

另外,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 {#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:

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;constraint-mappings
    xmlns=&quot;https://jakarta.ee/xml/ns/validation/mapping&quot;
    xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
    xsi:schemaLocation=&quot;
        https://jakarta.ee/xml/ns/validation/mapping
        https://jakarta.ee/xml/ns/validation/validation-mapping-3.0.xsd&quot;
    version=&quot;3.0&quot;&gt;

    &lt;!-- note that you can use ignore-annotations 
        to either ignore any annotation constraints 
        or include them, depending on your needs --&gt;
    &lt;bean class=&quot;com.acme.common.model.SomeType&quot; ignore-annotations=&quot;false&quot;&gt;
       &lt;field name=&quot;someField&quot;&gt;
           &lt;constraint annotation=&quot;jakarta.validation.constraints.NotBlank&quot;/&gt;
           [...]
       &lt;/field&gt;
       [...]
    &lt;/bean&gt;
&lt;/constraint-mappings&gt;

for more details you should check this section of the specification.

Programmatic constraint definition {#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( &quot;manufacturer&quot; )
            .constraint( new NotNullDef() )
        .field( &quot;licensePlate&quot; )
            .ignoreAnnotations( true )
            .constraint( new NotNullDef() )
            .constraint( new SizeDef().min( 2 ).max( 14 ) )
    .type( RentalCar.class )
        .getter( &quot;rentalStation&quot; )
            .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(..)


赞(0)
未经允许不得转载:工具盒子 » 验证类,不能通过添加新注解来修改。