Spring Boot POST JSON数据校验异常:字段缺失仍生成实例并入库
解决方案
1. 修正实体类的校验注解与字段类型
int类型字段默认值为0,无法触发@NotNull校验(0是合法值而非null),必须把id改为Integer包装类型。同时给所有必填字段添加适配的校验注解:
@Entity public class Alien{ @Id @NotNull(message = "id不能为空或缺失") private Integer id; // 改为Integer类型,支持null判断 @NotBlank(message = "name不能为空或缺失") private String name; @NotBlank(message = "planet不能为空或缺失") private String planet; // Getter and setter }
@NotNull:用于包装类型,检查字段是否为null@NotBlank:用于字符串,检查是否为null、空字符串或仅含空白字符,比@NotNull更贴合字符串非空需求
2. 控制器添加校验触发与错误拦截
在@RequestBody参数前加@Valid触发校验,通过BindingResult获取校验结果,失败时直接返回错误,不执行保存:
import org.springframework.http.ResponseEntity; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import java.util.List; import java.util.stream.Collectors; import org.springframework.validation.DefaultMessageSourceResolvable; @RequestMapping(value="/create", method=RequestMethod.POST, consumes={"application/json"}) public ResponseEntity<?> addDetails(@Valid @RequestBody Alien alien, BindingResult result){ if(result.hasErrors()){ // 提取所有错误信息返回 List<String> errorMessages = result.getAllErrors().stream() .map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.toList()); return ResponseEntity.badRequest().body(errorMessages); } // 校验通过才执行保存 Alien savedAlien = repo.save(alien); return ResponseEntity.ok(savedAlien); }
3. 确保校验依赖存在(Spring Boot场景)
Spring Boot 2.3及以上版本中,spring-boot-starter-web不再包含校验依赖,需手动添加:
Maven
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
Gradle
implementation 'org.springframework.boot:spring-boot-starter-validation'
可选:全局异常处理(更简洁的写法)
不想每个控制器方法都写BindingResult逻辑的话,用@ControllerAdvice全局捕获校验异常:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import java.util.List; import java.util.stream.Collectors; @ControllerAdvice public class GlobalValidationExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<List<String>> handleValidationExceptions(MethodArgumentNotValidException ex) { List<String> errors = ex.getBindingResult().getAllErrors().stream() .map(DefaultMessageSourceResolvable::getDefaultMessage) .collect(Collectors.toList()); return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); } }
此时控制器方法可简化为:
@RequestMapping(value="/create", method=RequestMethod.POST, consumes={"application/json"}) public Alien addDetails(@Valid @RequestBody Alien alien){ return repo.save(alien); }
内容的提问来源于stack exchange,提问作者SKY-BIRD Web Media
相关产品推荐
相关产品推荐

