spring boot 参数校验设置默认错误提示,核心做法是自定义全局异常处理器捕获 methodargumentnotvalidexception,并在其中统一格式化返回结果。具体实现时,需要注册一个 @controlleradvice 类,重写 @exceptionhandler 方法,遍历校验失败信息并组装成前端友好的 json 结构。这样做可以避免每个 controller 重复处理校验逻辑,确保所有接口返回一致的错误格式。

@Validated 注解在 Controller 层如何触发校验
当 Controller 方法的参数前加上 @Validated 或 @Valid 注解时,Spring 会在方法执行前自动调用 JSR-380 校验器对参数进行验证。如果参数不符合约束条件(如 @NotNull、@Size),校验器会抛出 MethodArgumentNotValidException 异常。此时程序流程中断,不会进入 Controller 业务逻辑,而是直接跳转到全局异常处理器。这种机制确保了数据在进入业务层之前就已经过清洗和验证。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ValidationApplication {
public static void main(String[] args) {
SpringApplication.run(ValidationApplication.class, args);
}
}
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
public class UserDTO {
@NotBlank(message = "用户名不能为空")
private String username;
@Size(min = 6, max = 20, message = "密码长度必须在6到20之间")
private String password;
// getters and setters
}
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
@RestController
@RequestMapping("/api/users")
public class UserController {
@PostMapping
public String createUser(@Valid @RequestBody UserDTO user) {
return "User created: " + user.getUsername();
}
}
预期结果:当发送 POST 请求且 body 中缺少 username 或 password 长度不符时,系统返回 400 状态码及自定义的错误详情 JSON,而不是默认的堆栈跟踪信息。
全局异常处理器如何捕获并格式化校验异常
在全局异常处理器中,通过 @ExceptionHandler(MethodArgumentNotValidException.class) 精准捕获校验失败异常。获取异常对象后,调用 getBindingResult().getFieldErrors() 提取所有字段错误。通常将这些错误转换为列表形式,包含字段名、错误消息和原始值,以便前端展示。同时,可以设置统一的 HTTP 状态码为 400 Bad Request,保持 API 规范的一致性。这种方式将校验细节与业务逻辑解耦,提高了代码的可维护性。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>> handleValidationExceptions(
MethodArgumentNotValidException ex) {
Map<String, Object> body = new HashMap<>();
List<Map<String, String>> errors = ex.getBindingResult().getFieldErrors()
.stream()
.map(error -> {
Map<String, String> err = new HashMap<>();
err.put("field", error.getField());
err.put("message", error.getDefaultMessage());
err.put("rejectedValue", String.valueOf(error.getRejectedValue()));
return err;
})
.toList();
body.put("status", HttpStatus.BAD_REQUEST.value());
body.put("error", "Validation Failed");
body.put("details", errors);
return new ResponseEntity<>(body, HttpStatus.BAD_REQUEST);
}
}
预期结果:对于上述 UserDTO 的校验失败,返回的 JSON 结构如下:
{
"status": 400,
"error": "Validation Failed",
"details": [
{"field": "username", "message": "用户名不能为空", "rejectedValue": ""},
{"field": "password", "message": "密码长度必须在6到20之间", "rejectedValue": "123"}
]
}
当校验失败时,未绑定的字段是否会被包含在错误列表中
在校验失败时,只有那些被校验注解标记且实际发生错误的字段才会出现在 FieldError 列表中。如果一个字段没有添加任何校验注解,或者虽然添加了注解但值符合约束条件,它就不会出现在错误详情中。此外,如果请求体中的某个字段完全缺失且未标记为 @NotNull,该字段也不会产生错误。这意味着错误列表仅反映具体的违规项,而非所有输入字段的完整性检查。开发者可以根据这一特性,在前端只高亮显示有问题的字段,提升用户体验。


















