Spring Boot加载JSON配置属性时的校验问题
嘿,别担心,你其实完全可以用JSR-303(Bean Validation)来实现配置加载时的校验,它可不是只给Rest API用的!Spring Boot在绑定@ConfigurationProperties的时候,完全支持触发校验逻辑,只要你做几个简单的配置就行。
步骤1:添加校验依赖
首先,确保你的项目里有校验相关的依赖。如果是Spring Boot 2.3及以上版本,spring-boot-starter-validation是单独的依赖,需要手动引入(Maven为例):
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
步骤2:给配置类添加校验注解
在你的MyConfig类上加上@Validated注解,同时在需要校验的字段上添加对应的JSR-303校验注解:
@Component @ConfigurationProperties(prefix = "my-config") @RefreshScope @Validated // 关键:开启配置类的校验 public class MyConfig { // 校验services集合不能为null,且至少有1个元素 @NotNull(message = "services集合不能为空") @Size(min = 1, message = "services集合至少需要包含1个元素") private List<@Valid Service> services; // 如果Service内部也需要校验,加上@Valid @NotNull(message = "consumers集合不能为空") @Size(min = 1, message = "consumers集合至少需要包含1个元素") private List<@Valid Consumer> consumers; // getter、setter省略 }
步骤3:嵌套对象的校验(如果需要)
如果Service或者Consumer类内部的字段也需要校验,比如某个属性不能为null,记得在对应的字段上添加校验注解,并且在集合的泛型前加上@Valid,这样Spring会递归校验嵌套对象:
public class Service { @NotBlank(message = "service的name不能为空") private String name; @NotNull(message = "service的port不能为null") @Min(value = 1, message = "service的port必须大于0") private Integer port; // getter、setter省略 }
校验生效的效果
当Spring Boot启动加载配置的时候,如果配置不符合校验规则(比如services集合为空,或者某个Service的name是空字符串),应用会直接启动失败,抛出ConstraintViolationException,并在日志里清晰显示具体的校验失败信息,这样你就能在启动阶段就发现配置问题,而不是等到运行时才报错。
为什么之前以为JSR-303只适用于Rest API?
其实是误解啦!JSR-303是通用的Bean校验规范,Spring Boot对@ConfigurationProperties的绑定过程做了扩展,只要给配置类加上@Validated,就会触发校验逻辑,和Rest API的校验是同一个机制,只是触发时机不同——一个是请求时校验,一个是配置加载时校验。
内容的提问来源于stack exchange,提问作者adesai

