Immutables库javax.validation校验注解被忽略不生效如何解决
根本原因
Immutables 库默认不会将定义在抽象接口方法上的javax.validation系列注解复制到生成的实现类对应方法/字段上,校验框架读取不到注解,自然无法触发校验逻辑。
解决步骤
- 配置Immutables复制校验注解
在你的实体接口上添加@Value.Style注解,指定需要复制的校验注解范围,修改后的代码如下:
import javax.validation.Valid; import javax.validation.constraints.Size; import org.immutables.value.Value; @Value.Immutable // 复制所有javax.validation包下的注解到生成类的对应方法 @Value.Style(copyAnnotations = "javax.validation.**") public interface Entity { @Valid @Size(max = 10) String name(); }
如果只需要复制特定注解,也可以写成:@Value.Style(copyAnnotations = {Valid.class, Size.class})
- 校验逻辑触发说明
如果没有额外配置,校验注解不会在Immutables执行build()方法时自动触发,你需要手动调用校验器验证对象,单元测试示例如下:
import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; public class EntityTest { private final ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); private final Validator validator = factory.getValidator(); @Test void testNameLengthValidation() { // 构造超出长度限制的实体 Entity invalidEntity = ImmutableEntity.builder().name("abcdefghijk").build(); // 手动触发校验 var violations = validator.validate(invalidEntity); // 验证有校验不通过的项 assertThat(violations).isNotEmpty(); } }
- (可选)build时自动触发校验
如果希望在调用builder().build()方法时自动执行校验,不需要每次手动调用校验器,可以在接口中添加@Value.Check方法:
import javax.validation.Valid; import javax.validation.constraints.Size; import javax.validation.Validation; import javax.validation.Validator; import org.immutables.value.Value; @Value.Immutable @Value.Style(copyAnnotations = "javax.validation.**") public interface Entity { @Valid @Size(max = 10) String name(); @Value.Check default void checkParams() { Validator validator = Validation.buildDefaultValidatorFactory().getValidator(); var violations = validator.validate(this); if (!violations.isEmpty()) { throw new IllegalArgumentException("参数校验失败:" + violations); } } }
pom.xml优化
你当前的pom依赖配置没有问题,仅可以移除单独引入的javax.validation:validation-api依赖,spring-boot-starter-validation已经包含该依赖,重复引入可能会导致版本冲突。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

