使用immutables.org库时Javax validation注解未传递到生成类如何解决
问题描述
使用immutables.org库添加Javax注解验证时,验证注解没有传递到生成的类中,已引入spring-boot-starter-validation和javax.validation依赖,相关代码如下:
相关代码
Immutable实体定义
@Value.Immutable public interface Entity { @Valid @Size(min = 19) int age(); @Valid @NotBlank String name(); }
Controller层代码
@PostMapping("/entity/") public ResponseEntity post2(@RequestBody @Valid ImmutableEntity entity) { return new ResponseEntity<Object>("", HttpStatus.OK); }
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.5</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>testImmutable</artifactId> <version>0.0.1-SNAPSHOT</version> <name>testImmutable</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.immutables</groupId> <artifactId>value</artifactId> <version>2.8.8</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.1.Final</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.5</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
问题成因
- Immutables库默认不会将父接口方法上的注解拷贝到生成的实现类对应方法中,你定义在
Entity接口方法上的@Size、@NotBlank等注解,默认不会出现在生成的ImmutableEntity类的同名方法上。 - Javax Validation默认仅扫描参数类自身携带的注解,不会主动追溯父接口的注解,当你Controller参数指定为
ImmutableEntity类型时,校验器找不到对应注解,自然不会触发校验逻辑。 - 额外说明:你代码里加在基础类型、String类型方法上的
@Valid是冗余的,@Valid仅用于级联校验嵌套的复杂对象,普通字段不需要添加该注解。
解决方案
- 方案1(最简便):修改Controller参数类型为接口
Entity而非生成的实现类ImmutableEntity。Spring Boot的校验器支持直接解析接口上的方法注解完成校验,反序列化时Jackson依然会自动生成ImmutableEntity实例,不需要额外修改Immutables配置。 - 方案2:配置Immutables开启注解传递。在实体接口上添加
@Value.Style(passAnnotations = {Size.class, NotBlank.class})注解,指定需要传递到生成类的校验注解,生成的ImmutableEntity类的对应方法就会携带这些注解,Controller使用ImmutableEntity作为参数类型也能正常触发校验。 - 方案3:开启Immutables内置校验。在
@Value.Style中配置validationMethod = Value.Style.ValidationMethod.JAVAX_VALIDATION,生成的Builder在调用build()方法构建对象时就会自动触发校验,不需要等到Controller层再校验,提前拦截非法参数。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

