JSR-303是Java 的标准规范,而 Spring MVC 对其提供了完美的支持和集成
1.JSR-303 的身份
JSR-303 是 Java 标准
JSR:Java Specification Request(Java 规范请求)
JSR-303:Bean Validation 1.0(Bean 验证规范)
后续版本:JSR-349(Bean Validation 1.1)、JSR-380(Bean Validation 2.0)
2.添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>
3.实体类添加验证注解
public class User {@NotNull(message = "用户ID不能为空")private Long id;@NotBlank(message = "用户名不能为空")@Size(min = 2, max = 20, message = "用户名长度必须在2-20字符之间")private String username;@Email(message = "邮箱格式不正确")private String email;@Min(value = 18, message = "年龄必须大于18岁")@Max(value = 100, message = "年龄必须小于100岁")private Integer age;@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")private String phone;@Future(message = "生效时间必须是将来的时间")private LocalDateTime effectiveDate;// Getter和Setter
}
4. Controller 中使用验证
@RestController
@RequestMapping("/api/users")
public class UserController {// 1. 简单的参数验证@PostMappingpublic ResponseEntity<?> createUser(@RequestBody @Valid User user) {return ResponseEntity.ok(userService.createUser(user));}// 2. 获取验证错误信息@PostMapping("/with-binding")public ResponseEntity<?> createUserWithBinding(@RequestBody @Valid User user, BindingResult bindingResult) {if (bindingResult.hasErrors()) {// 手动处理验证错误List<String> errors = bindingResult.getFieldErrors().stream().map(error -> error.getField() + ": " + error.getDefaultMessage()).collect(Collectors.toList());return ResponseEntity.badRequest().body(errors);}return ResponseEntity.ok(userService.createUser(user));}
}
5.全局异常处理(推荐使用)
@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex) {List<FieldError> fieldErrors = ex.getBindingResult().getFieldErrors();List<String> errors = fieldErrors.stream().map(error -> error.getField() + ": " + error.getDefaultMessage()).collect(Collectors.toList());//这里封装太简单,也不具有扩展性ErrorResponse errorResponse = new ErrorResponse("VALIDATION_FAILED","参数验证失败",errors);return ResponseEntity.badRequest().body(errorResponse);}
}
对于异常,应该给上层和前端传递状态和消息,而不仅仅是抛出异常。而一个系统往往有很多异常,
此外如果只传递数字和信息,则未来如果变化,则数字信息都需要修改,这个改动范围很大,所以可以用枚举来定义各种异常的状态和信息,并生成文档
故应该使用
1.异常类:BizException
2.异常枚举类:BizExceptionEnume:列举出每个模块都会出现的异常情况
6.常见注解
注解 | 说明 | 示例 |
---|---|---|
@NotNull | 值不能为null | @NotNull(message = “不能为空”) |
@NotBlank | 字符串不能为空 | @NotBlank(message = “姓名不能为空”) |
@Size | 长度限制 | @Size(min=2, max=100) |
@Pattern | 正则表达式 | @Pattern(regexp = “^1[3-9]\d{9}$”) |
@Min / @Max | 数值范围 | @Min(18) @Max(100) |
@DecimalMin / @DecimalMax | 小数范围 | @DecimalMin(“0.0”) |
@Positive / @Negative | 正数/负数 | @Positive |
@Future / @Past | 时间限制 | @Future |
7.基本流程
1.方式一
1.导入注解
2.编写校验注解
3.使用@Valid告诉SpringMVC进行校验
4.BindingResult
2.方式二【推荐】
1.导入注解
2.编写校验注解
3.使用@Valid告诉SpringMVC进行校验
【推荐】4.编写一个全局异常处理器,处理MethodArgumentNotValidException并统一返回校验失败的提示信息