如何使用 Spring 验证器验证嵌套 POJO

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

我认为 @Valid 注释可以启用嵌套 POJO 的验证。但它失败并出现 IllegalArgumentException。

我有两个POJO

# EmailAddress.java

import jakarta.validation.constraints.Email;

public class EmailAddress {
    
    @Email
    private final String value;

    public EmailAddress(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

# Person.java
import jakarta.validation.Valid;

public class Person {
    
    @Valid
    private EmailAddress email;

    public void setEmail(EmailAddress email) {
        this.email = email;
    }

    public EmailAddress getEmail() {
        return email;
    }
}

我的测试因非法参数异常而失败

    @Test
    public void testInvalidEmailAddress() {
        Person person = new Person();
        EmailAddress email = new EmailAddress("invalid");
        person.setEmail(email);

        Errors errors = validator.validateObject(person);
        assertEquals(1, errors.getErrorCount());
    }

发生错误

java.lang.IllegalArgumentException: Cannot retrieve value for field 'email.value' - neither a getter method nor a raw field found
 at org.springframework.validation.SimpleErrors.getFieldValue(SimpleErrors.java:145)
 at org.springframework.validation.SimpleErrors.rejectValue(SimpleErrors.java:104)
 at org.springframework.validation.beanvalidation.SpringValidatorAdapter.processConstraintViolations(SpringValidatorAdapter.java:180)
 at org.springframework.validation.beanvalidation.SpringValidatorAdapter.validate(SpringValidatorAdapter.java:106)

我希望 validateObject 方法不会抛出异常。

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

我也遇到了同样的问题,但我找到了解决方案。 引用

SimpleErrors
类的文档

请注意,此错误实现不支持嵌套路径。 它专门为验证各个顶级对象而设计, 不汇总多个来源的错误。 如果这不足以满足您的目的,请使用可绑定的错误 实现例如 BeanPropertyBindingResult。

我设法通过使用建议的实现并更改用于直接提供

Errors
实例的验证方法来使您的示例正常工作

    @Autowired
    private Validator validator;

    @Test
    public void testInvalidEmailAddress() {
        Person person = new Person();
        final BeanPropertyBindingResult errors = new BeanPropertyBindingResult(person, "person");
        EmailAddress email = new EmailAddress("invalid");
        person.setEmail(email);

        validator.validate(person, errors);
        Assertions.assertEquals(1, errors.getErrorCount());
    }
© www.soinside.com 2019 - 2024. All rights reserved.