Java后端发工作中经常会对前端传递过来的参数做一些校验,在业务中还要抛出异常或者不断的返回异常时的校验信息,充满了if-else这种校验代码,在代码中相当冗长。例如说,用户注册时,会校验手机格式的正确性,用户名的长度等等。虽说前端也可以做参数校验,但是为了保证我们API接口的可靠性,以保证最终数据入库的正确性,后端进行参数校验不可忽视。 Hibernate Validator 提供了一种统一方便的方式,让我们快速的实现参数校验。
Hibernate Validator 使用注解,实现声明式校验。而在实现原理上,也是基于 Spring AOP 拦截,实现校验相关的操作。 javax.validation.constraints 包下,定义了一系列的约束( constraint )注解。文末会贴上一些常用的注解。 如果项目的框架是 spring boot 的话,在 spring-boot-starter-web 中已经包含了 Hibernate-validator 的依赖( 版本<2.3 )。 2.3 以后的版本中 spring-boot-starter-web 已经去除了这个依赖,需要手动引入 Hibernate-validator 依赖,并且有一些变化,因此 2.3.x 的版本暂不研究。本文使用的版本是 2.2.8 。
实战
1、创建实体类
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
package com.yese.pojo;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.*;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User {
/**
* 用户ID
*/
@NotNull(message = "用户id不能为空")
private Long userId;
/**
* 用户名
*/
@NotBlank(message = "用户名不能为空")
@Length(max = 20, message = "用户名不能超过10个字符")
@Pattern(regexp = "^[\\\\u4E00-\\\\u9FA5A-Za-z0-9\\\\*]*$", message = "用户名限制:最多10字符,包含文字、字母和数字")
private String username;
/**
* 密码
*/
@NotBlank(message = "密码不能为空")
private String password;
/**
* 手机号
*/
@NotBlank(message = "手机号不能为空")
@Pattern(regexp = "^[1][3,4,5,6,7,8,9][0-9]{9}$", message = "手机号格式有误")
private String mobile;
/**
* 性别
*/
@NotNull(message = "性别不能为空")
private Integer sex;
/**
* 年龄
*/
@NotNull(message = "年龄不能为空")
@Min(value = 1, message = "年龄最小为1岁")
@Max(value = 120, message = "年龄最大为120岁")
private Integer age;
/**
* 邮箱
*/
@NotBlank(message = "邮箱不能为空")
@Email(message = "邮箱格式错误")
private String email;
}
|
2、创建controller
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
package com.yese.controller;
import com.yese.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
@RestController
@Slf4j
public class UserController {
/**
* controller方法的入参里面在实体类前面加上@Validated
*/
@PostMapping("/user")
public void add(@RequestBody @Validated User user) {
log.info("user====={}", user);
}
}
|
3、创建全局异常处理器
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
package com.yese.config;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.StringJoiner;
/**
* 全局异常处理器
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* post方式提交json数据,参数校验失败后,会抛出一个MethodArgumentNotValidException
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Map<String, Object> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
// 获取所有的错误
// List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
// 获取错误提示
// System.out.println(fieldErrors.get(0).getDefaultMessage());
// 获取错误字段
// System.out.println(fieldErrors.get(0).getField());
// 将所有的错误提示使用";"拼接起来并返回
StringJoiner sj = new StringJoiner(";");
e.getBindingResult().getFieldErrors().forEach(x -> sj.add(x.getDefaultMessage()));
// 此处通常定义一个全局相应对象返回
Map<String, Object> map = new HashMap<>();
// 此处状态码可以通过枚举或者常量定义
map.put("code", 1001);
map.put("msg", sj.toString());
return map;
}
/**
* get方式提交参数,参数校验失败后,会抛出一个ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
public Map<String, Object> handleConstraintViolationException(ConstraintViolationException e) {
StringJoiner sj = new StringJoiner(";");
e.getConstraintViolations().forEach(x -> sj.add(x.getMessage()));
Map<String, Object> map = new HashMap<>();
map.put("code", 1001);
map.put("msg", sj.toString());
return map;
}
}
|
4、测试
效果符合预期!
@Valid和@Validated
绝大多数场景下,我们使用 @Validated 注解即可。
而在有嵌套校验的场景,我们使用 @Valid 注解添加到成员属性上。
附常用注解
javax.validation.constraints 包下
| 注解 | 验证的数据类型 | 说明 |
|---|---|---|
| @Null | 任意类型 | 验证注解的元素值必须是null |
| @NotNull | 任意类型 | 验证注解的元素值不是null |
| @NotBlank | 字符串 | 验证注解的元素值不为空(不为null、去除首位空格后长度大于0) |
| @NotEmpty | CharSequence子类型、Collection、Map、数组 | 验证注解的元素值不为null且不为空(字符串长度不为0、集合大小不为0) |
| @Min(value=值) | 数值类型 | 验证注解的元素值大于等于@Min指定的value值 |
| @Max(value=值) | 和@Min要求一样 | 验证注解的元素值小于等于@Max指定的value值 |
| @DecimalMin(value=值) | 和@Min要求一样 | 验证注解的元素值大于等于@ DecimalMin指定的value值 |
| @DecimalMax(value=值) | 和@Min要求一样 | 验证注解的元素值小于等于@ DecimalMax指定的value值 |
| @Digits(integer=整数位数, fraction=小数位数) | 和@Min要求一样 | 验证注解的元素值的整数位数和小数位数上限 |
| @Size(min=下限, max=上限) | 字符串、Collection、Map、数组等 | 验证注解的元素值的在min和max(包含)指定区间之内,如字符长度、集合大小 |
| @Positive | 判断正数 | |
| @PositiveOrZero | 判断正数或 0 。 | |
| @Negative | 判断负数。 | |
| @NegativeOrZero | 判断负数或 0 。 | |
| @Past | 日期类型 | 验证注解的元素值(日期类型)比当前时间早 |
| @Future | 与@Past要求一样 | 验证注解的元素值(日期类型)比当前时间晚 |
| @AssertFalse | Boolean | 验证注解的元素值是false |
| @AssertTrue | Boolean | 验证注解的元素值是true |
| @Range(min=最小值, max=最大值) | BigDecimal,BigInteger,CharSequence, byte, short, int, long等原子类型和包装类型 | 验证注解的元素值在最小值和最大值之间 |
| 字符串 | 验证注解的元素值是Email,也可以通过regexp和flag指定自定义的email格式 | |
| @Pattern(regexp=正则表达式,flag=标志的模式) | 字符串 | 验证注解的元素值与指定的正则表达式匹配 |
| @Valid | 任何非原子类型 | 指定递归验证关联的对象如用户对象中有个地址对象属性,如果想在验证用户对象时一起验证地址对象的话,在地址对象上加@Valid注解即可级联验证 |
org.hibernate.validator.constraints 包下,定义了一系列的约束( constraint )注解。如下:
@Range(min=, max=) :被注释的元素必须在合适的范围内。
@Length(min=, max=) :被注释的字符串的大小必须在指定的范围内。
@URL(protocol=,host=,port=,regexp=,flags=) :被注释的字符串必须是一个有效的 URL 。
@SafeHtml :判断提交的 HTML 是否安全。例如说,不能包含 javascript 脚本等等。
到此这篇关于详解SpringBoot中的参数校验(项目实战)的文章就介绍到这了,更多相关SpringBoot 参数校验内容请搜索快网idc以前的文章或继续浏览下面的相关文章希望大家以后多多支持快网idc!
原文链接:https://juejin.im/post/5f1fc126e51d4534942e0415
相关文章
- 64M VPS建站:能否支持高流量网站运行? 2025-06-10
- 64M VPS建站:怎样选择合适的域名和SSL证书? 2025-06-10
- 64M VPS建站:怎样优化以提高网站加载速度? 2025-06-10
- 64M VPS建站:是否适合初学者操作和管理? 2025-06-10
- ASP.NET自助建站系统中的用户注册和登录功能定制方法 2025-06-10
- 2025-07-10 怎样使用阿里云的安全工具进行服务器漏洞扫描和修复?
- 2025-07-10 怎样使用命令行工具优化Linux云服务器的Ping性能?
- 2025-07-10 怎样使用Xshell连接华为云服务器,实现高效远程管理?
- 2025-07-10 怎样利用云服务器D盘搭建稳定、高效的网站托管环境?
- 2025-07-10 怎样使用阿里云的安全组功能来增强服务器防火墙的安全性?
快网idc优惠网
QQ交流群
-
2025-06-04 100
-
2025-06-04 93
-
2025-06-04 104
-
2025-06-04 65
-
2025-05-29 49


