Spring Boot控制器@NotNull/@NotEmpty参数校验未生效如何解决
问题根因
- 控制器类未添加
@Validated注解,Spring默认不会触发方法参数上的JSR-303校验注解,你写的@NotNull/@NotEmpty根本没有执行。 id参数仅加了@NotNull注解,当请求传id=时,Spring会将空参数转换为一个空的ArrayList实例,并非null,因此可以顺利通过@NotNull校验进入方法逻辑。@RequestParam的required = true属性仅校验参数名是否存在,不会校验参数值是否为空,因此传空值的参数不会被它拦截。
实现步骤
1. 引入校验依赖
如果是Spring Boot项目,先确认引入了官方校验starter,原生Spring MVC项目需自行引入hibernate-validator依赖并配置方法校验后置处理器:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2. 修正控制器代码
给控制器类添加@Validated注解开启方法级参数校验,同时调整参数上的校验注解覆盖所有空场景:
import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.validation.constraints.NotEmpty; import java.util.List; @Slf4j @RestController @Validated // 必须添加,否则参数校验注解不生效 public class ClusterController { @GetMapping(value = "/omnichannel/cluster/id", produces = "application/json") public String clusterid( @RequestParam @NotEmpty // 替换原@NotNull,同时拦截null、空列表两种非法场景 List<Long> id, @RequestParam @NotEmpty // 同时拦截null、空字符串两种非法场景 String country) { log.info("Log: {}, {}", id, country); return country; } }
覆盖场景说明
修改后以下所有非法请求都会被直接拦截,不会进入方法逻辑:
- country有合法值,但id为null
- country有合法值,但id为空列表
- id有合法值,但country为null
- id有合法值,但country为空字符串
- id、country均为null/均为空值
注意:方法级参数校验抛出的异常类型为
ConstraintViolationException,如果需要自定义错误返回格式,在全局异常处理器中捕获该类异常统一处理即可。
内容的提问来源于stack exchange,提问作者M-sAnNan
相关产品推荐
相关产品推荐

