- A+
所属分类:Java springboot
前言
web项目中,用户的输入总是被假定不安全不正确的,在被处理前需要做校验。
数据校验是一个项目的基础模块,也许我们一些入门编码没有多久,了解前端的同学会说,我们已经在前端对数据进行了基础的校验了,还需要在后台对数据进行校验?答案是肯定的,因为前端传递给后台的数据没有百分百值得信任的,这是因为一些别有用心的人,可以模拟前端对后台进行数据发送,可能会发送一些操作后台的指令等非法数据,如果这些数据一旦发送到后台那么后果是很严重的。因此后端校验也是必须的,本章节我们介绍SpringBoot的后端数据校验。
SpringBoot2.3以前spring-boot-starter-web自带了validation,并且该模块也提供了相对应的数据绑定功能,但是到了springboot2.3以后就变成了以下依赖进行数据校验
1、添加validate依赖
<!-- 校验 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency>
2、在实体类上添加校验注解,以用户名字和年龄为例子
/** * 用户实体类 */ @Data @TableName("user") public class User implements Serializable { /** * 用户ID */ @TableId("user_id") private Integer userId; /** * 用户名 */ @TableField("user_name") @NotEmpty(message = "用户名信息不能为空") private String userName; /** * 用户年龄 */ @TableField("user_age") @Range(min = 0,max = 200,message = "年龄在0-200岁之间") @NotNull(message = "年龄不能为空") private Integer userAge; /** * 用户邮箱 */ @TableField("email") private String email; }
3、在controller上添加测试方法
其中 @Valid 注解标记对校验注解生效
@PostMapping("addUser") public Result addUser(@Valid @RequestBody User user){ //todo 处理其他的业务逻辑 return Result.success(); }
4、全局异常处理类
重点是 Result methodArgumentNotValidException(MethodArgumentNotValidException e) 方法
@ControllerAdvice @Slf4j public class GlobalExceptionHandler { @ExceptionHandler(value =java.lang.ArithmeticException.class) @ResponseBody public Result exceptionHandler1(ArithmeticException e){ return Result.error("分母不能为0"); } @ExceptionHandler(value = MethodArgumentNotValidException.class) @ResponseBody public Result methodArgumentNotValidException(MethodArgumentNotValidException e){ List<ObjectError> objectErrors = e.getBindingResult().getAllErrors(); List<String> resultErrors = new ArrayList<>(); objectErrors.forEach(objectError -> { resultErrors.add(objectError.getDefaultMessage()); }); return Result.error(resultErrors); } @ExceptionHandler(value =Exception.class) @ResponseBody public Result exceptionHandler(Exception e){ log.error("未知异常!原因是:",e); return Result.error(e.getMessage()); } }
5、postman 请求测试,如图所示
6、分组校验
6.1、@Validated的分组特性
介绍一下这样的场景:在对用户的姓名年龄进行编辑保存以及新增是两种不一样的情况。
新增:只需要验证userName与userAge是否符合条件即可,不需要验证id(因为在数据库中id已经存在)。
编辑修改:新增需要验证userName与userAge是否符合条件,还要验证id。
这时候就用到groups分组分情况对Bean属性变量进行验证,也可以满足多验证。具体的需要一下两个步骤
6.2、创建分组接口类
public interface AddUserValidate { } public interface UpdateUserValidate { }
6.3、修改实体校验的group
@Data @TableName("user") public class User implements Serializable { /** * 用户ID */ @TableId("user_id") @NotNull(message = "用户ID不能为空",groups = UpdateUserValidate.class) private Integer userId; /** * 用户名 */ @TableField("user_name") @NotEmpty(message = "用户名信息不能为空",groups = {UpdateUserValidate.class, AddUserValidate.class}) private String userName; /** * 用户年龄 */ @TableField("user_age") @Range(min = 0,max = 200,message = "年龄在0-200岁之间",groups = {UpdateUserValidate.class, AddUserValidate.class}) @NotNull(message = "年龄不能为空",groups = {UpdateUserValidate.class, AddUserValidate.class}) private Integer userAge; /** * 用户邮箱 */ @TableField("email") private String email; }
6.4、增加controller 测试update方法
@PostMapping("updateUser") public Result updateUser(@Validated({UpdateUserValidate.class}) @RequestBody User user){ //todo 处理其他的业务逻辑 return Result.success(); }
6.5、校验update方法
7、常用validate校验集合
@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=) 被注释的元素必须符合指定的正则表达式 @NotBlank(message =) 验证字符串非null,且长度必须大于0 @Email 被注释的元素必须是电子邮箱地址 @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内 @NotEmpty 被注释的字符串的必须非空 @Range(min=,max=,message=) 被注释的元素必须在合适的范围内