You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 15:45:42