如何在 Spring/Spring Boot 中做参数校验?你需要了解的都在这里!

数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,避免用户绕过浏览器直接通过一些 HTTP 工具直接向后端请求一些违法数据。

本文结合自己在项目中的实际使用经验,可以说文章介绍的内容很实用,不了解的朋友可以学习一下,后面可以立马实践到项目上去。

下面我会通过实例程序演示如何在 Java 程序中尤其是 Spring 程序中优雅地的进行参数验证。

基础设施搭建 相关依赖

如果开发普通 Java 程序的的话,你需要可能需要像下面这样依赖:

<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.9.Final</version> </dependency> <dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.6</version> </dependency>

使用 Spring Boot 程序的话只需要spring-boot-starter-web 就够了,它的子依赖包含了我们所需要的东西。除了这个依赖,下面的演示还用到了 lombok ,所以不要忘记添加上相关依赖。

<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> 实体类

下面这个是示例用到的实体类。

@Data @AllArgsConstructor @NoArgsConstructor public class Person { @NotNull(message = "classId 不能为空") private String classId; @Size(max = 33) @NotNull(message = "name 不能为空") private String name; @Pattern(regexp = "((^Man$|^Woman$|^UGM$))", message = "sex 值不在可选范围") @NotNull(message = "sex 不能为空") private String sex; @Email(message = "email 格式不正确") @NotNull(message = "email 不能为空") private String email; }

正则表达式说明:

- ^string : 匹配以 string 开头的字符串 - string$ :匹配以 string 结尾的字符串 - ^string$ :精确匹配 string 字符串 - ((^Man$|^Woman$|^UGM$)) : 值只能在 Man,Woman,UGM 这三个值中选择

下面这部分校验注解说明内容参考自:https://www.cnkirito.moe/spring-validation/ ,感谢@徐靖峰。

JSR提供的校验注解:

@Null 被注释的元素必须为 null

@NotNull 被注释的元素必须不为 null

@AssertTrue 被注释的元素必须为 true

@AssertFalse 被注释的元素必须为 false

@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值

@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值

@Size(max=, min=) 被注释的元素的大小必须在指定的范围内

@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内

@Past 被注释的元素必须是一个过去的日期

@Future 被注释的元素必须是一个将来的日期

@Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式

Hibernate Validator提供的校验注解

@NotBlank(message =) 验证字符串非null,且长度必须大于0

@Email 被注释的元素必须是电子邮箱地址

@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内

@NotEmpty 被注释的字符串的必须非空

@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

验证Controller的输入 验证请求体(RequestBody)

Controller:

我们在需要验证的参数上加上了@Valid注解,如果验证失败,它将抛出MethodArgumentNotValidException。默认情况下,Spring会将此异常转换为HTTP Status 400(错误请求)。

@RestController @RequestMapping("/api") public class PersonController { @PostMapping("/person") public ResponseEntity<Person> getPerson(@RequestBody @Valid Person person) { return ResponseEntity.ok().body(person); } }

ExceptionHandler:

自定义异常处理器可以帮助我们捕获异常,并进行一些简单的处理。如果对于下面的处理异常的代码不太理解的话,可以查看这篇文章 。

@ControllerAdvice(assignableTypes = {PersonController.class}) public class GlobalExceptionHandler { @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity<Map<String, String>> handleValidationExceptions( MethodArgumentNotValidException ex) { Map<String, String> errors = new HashMap<>(); ex.getBindingResult().getAllErrors().forEach((error) -> { String fieldName = ((FieldError) error).getField(); String errorMessage = error.getDefaultMessage(); errors.put(fieldName, errorMessage); }); return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors); } }

通过测试验证:

下面我通过 MockMvc 模拟请求 Controller 的方式来验证是否生效,当然你也可以通过 Postman 这种工具来验证。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwypxy.html