【问题标题】:The Spring validation @NotNull does not validateSpring 验证 @NotNull 不验证
【发布时间】:2019-01-07 08:17:36
【问题描述】:

我正在尝试使用 Spring Validator 验证 POST 请求。这是我要验证的对象:

@Validated
public class Request implements Serializable {
    private static final long serialVersionUID = 1L;

    private Long id1;
    private Long id2;   
    private String s;   
    private List<Mapping> mappings;

    public Request() {}
    public Request (Long id1, Long id2, String s, List<Mapping> mappings) {
        this.id1 = id1;
        this.id2 = id2;
        this.s = s;
        this.mappings = mappings;
    }

    //getter() and setter() methods.
}

这是映射类:

@Validated
public class Mapping implements Serializable {
    private static final long serialVersionUID = 1L;
    @JsonProperty(value="id")
    private Long id;

    @JsonProperty(value="string")
    private String string;

    @JsonProperty(value="account_id")
    @NotNull
    private String accountId;

    @JsonProperty(value="last_updated_at")
    @NotNull    
    private OffsetDateTime lastUpdatedAt;

    // Getter and setters()
    // I'll skip the getter() and setter() for id and string fields.
    @Override
    public String getAccountId() {
        return accountId;
    }

    @Override
    public void setAccountId (@NotNull String accountId) {
        this.accountId = accountId;
    }

    @Override
    public OffsetDateTime getLastUpdatedAt() {
        return lastUpdatedAt;
    }

    @Override
    public void setLastUpdatedAt(@NotNull OffsetDateTime lastUpdatedAt) {
        this.lastUpdatedAt = lastUpdatedAt;
    }
}

这是正在发布的消息:

[Request [id1=null, id2=null, s=6eq2J6, mappings=

[Mapping [id=2779, string=6eq2J6, accountId=null, lastUpdatedAt=null]]]]

这是我接收请求的方式,但 bindingResult.hasErrors() 始终为空。 pushRequest 与发送时完全相同。

@RestController
@RequestMapping(value="/${path}", method={RequestMethod.GET, RequestMethod.POST, RequestMethod.PUT})
@Validated
public class MappingController {

@PostMapping(value="/", consumes={"application/json"})
public void processMappings (@Valid @RequestBody Optional<Request> pushRequest, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        log.info("Error!");
    }
}
}

为什么 accountId 和 lastUpdatedAt 的 @NotNull 在具有 Null 值时不会使验证失败?

我试图通过搜索这个错误找到解决方案,解决方案是将@Validated添加到Request, Mapping and MappingController类中,但没有解决问题。

另一种解决方案是将这些Beans 添加到Main() 类中,但没有解决问题。

public class Main {
    public static void main(String[] args) {        
        SpringApplication.run(Main.class, args);        
        //System.out.println("version: " + SpringVersion.getVersion()); // version: 5.1.0.RC1
    }

    @Bean
    public javax.validation.Validator localValidatorFactoryBean() {
       return new LocalValidatorFactoryBean();
    }

    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
                MethodValidationPostProcessor mvProcessor = new MethodValidationPostProcessor();
                mvProcessor.setValidator(validator());
                return mvProcessor;
    }

    @Bean
    public LocalValidatorFactoryBean validator() {
                    LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean();
                    validator.setProviderClass(HibernateValidator.class);
                    validator.afterPropertiesSet();
                    return validator;
    }
}

【问题讨论】:

标签: java spring spring-boot spring-restcontroller spring-validator


【解决方案1】:

就我而言,我缺少验证依赖项。来自baeldung;

Starting with Boot 2.3, we also need to explicitly add the spring-boot-starter-validation dependency:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-validation</artifactId> 
</dependency>

【讨论】:

    【解决方案2】:

    感谢这篇文章,我想我找到了答案:

    jsr-303-valid-annotation-nested-object-not-working

    所以只要我将@Valid 添加到这些字段:

    @Valid
    private List<Mapping> mappings;
    

    还有Mapping里面的这些字段:

    @JsonProperty(value="account_id")
        @Valid
        @NotNull
        private String accountId;
    
        @JsonProperty(value="last_updated_at")
        @Valid
        @NotNull    
        private OffsetDateTime lastUpdatedAt;
    

    验证开始工作。

    我还删除了setter() 方法中的@NotNull

    Setters() 像这样:

    @Override
        public void setAccountId (String accountId) {
            this.accountId = accountId;
        }    
    
        @Override
        public void setLastUpdatedAt(OffsetDateTime lastUpdatedAt) {
            this.lastUpdatedAt = lastUpdatedAt;
        }
    

    我的代码也可以在没有任何我添加到 Main() 的 Validator bean 的情况下工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-15
      • 2017-11-22
      • 2014-09-23
      • 2019-04-22
      • 1970-01-01
      • 2014-08-30
      • 1970-01-01
      • 2020-10-04
      相关资源
      最近更新 更多