Spring Validation 参数校验框架

Spring Validation 参数校验框架

步骤

  1. 引入Spring Validation 的起步依赖

  2. 在阐述前面添加@Pattern注解

  3. 在 Controller 类上添加 @Validated 注解

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
</dependency>
@RestController
@Validated
@RequestMapping("/user")
public class UserController {
@PostMapping("/register")
    public Result UserRegister(@Pattern(regexp = "^\\S{5,16}$") String username, @Pattern(regexp = "^\\S{5,16}$")String password) {
        //查询用户
        User user = userService.findByUserName(username);
        if (user == null) {
            //注册
            userService.register(username, password);
            return Result.success();
        } else {
            return Result.error("用户已存在!");
        }
    }
}

校验规则

@Pattern(regexp=“正则表达式”)

下面是常用的正则表达式:

  1 匹配首尾空格的正则表达式:(^\s*)|(\s*$)
  2 整数或者小数:^[0-9]+\.{0,1}[0-9]{0,2}$
  3 只能输入数字:"^[0-9]*$"。
  4 只能输入n位的数字:"^\d{n}$"。
  5 只能输入至少n位的数字:"^\d{n,}$"。
  6 只能输入m~n位的数字:。"^\d{m,n}$"
  7 只能输入零和非零开头的数字:"^(0|[1-9][0-9]*)$"。
  8 只能输入有两位小数的正实数:"^[0-9]+(.[0-9]{2})?$"。
  9 只能输入有1~3位小数的正实数:"^[0-9]+(.[0-9]{1,3})?$"。
 10 只能输入非零的正整数:"^\+?[1-9][0-9]*$"。
 11 只能输入非零的负整数:"^\-[1-9][]0-9"*$。
 12 只能输入长度为3的字符:"^.{3}$"。
 13 只能输入由26个英文字母组成的字符串:"^[A-Za-z]+$"。
 14 只能输入由26个大写英文字母组成的字符串:"^[A-Z]+$"。
 15 只能输入由26个小写英文字母组成的字符串:"^[a-z]+$"。
 16 只能输入由数字和26个英文字母组成的字符串:"^[A-Za-z0-9]+$"。
 17 只能输入由数字、26个英文字母或者下划线组成的字符串:"^\w+$"。
 18 验证用户密码:"^[a-zA-Z]\w{5,17}$"正确格式为:以字母开头,长度在6~18之间,只能包含字符、数字和下划线。
 19 验证是否含有^%&',;=?$\"等字符:"[^%&',;=?$\x22]+"。
 20 只能输入汉字:"^[\u4e00-\u9fa5]{0,}$"
 21 验证Email地址:"^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$"。
 22 验证InternetURL:"^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$"。
 23 验证电话号码:"^(\(\d{3,4}-)|\d{3.4}-)?\d{7,8}$"正确格式为:"XXX-XXXXXXX"、"XXXX-XXXXXXXX"、"XXX-XXXXXXX"、"XXX-XXXXXXXX"、"XXXXXXX"和"XXXXXXXX"。
 24 验证身份证号(15位或18位数字):"^\d{15}|\d{18}$"。
 25 验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:"01"~"09"和"1"~"12"。
 26 验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;"01"~"09"和"1"~"31"。
 27 匹配中文字符的正则表达式: [\u4e00-\u9fa5]
 28 匹配双字节字符(包括汉字在内):[^\x00-\xff]
 29 应用:计算字符串的长度(一个双字节字符长度计2,ASCII字符计1)
 30 String.prototype.len=function(){return this.replace(/[^\x00-\xff]/g,"aa").length;}
 31 匹配空行的正则表达式:\n[\s| ]*\r
 32 匹配html标签的正则表达式:<(.*)>(.*)<\/(.*)>|<(.*)\/>

参数校验失败异常处理

  • 导入 validation 坐标

  • 在参数上添加 @Pattern 注解,指定校验规则

  • 在 Controller 类上添加 @Validated 注解

  • 在全局异常处理器中处理参数校验失败的异常

    /**
     * 全局异常处理器
     */
    @RestControllerAdvice
    public class GlobalExceptionHandler {
        @ExceptionHandler(Exception.class)
        public Result handlerException(Exception e){
            e.printStackTrace();
            return Result.error(StringUtils.hasLength(e.getMessage())?e.getMessage():"操作失败!");
        }
    }
    

对实体类参数进行校验

  • @NotNull 值不能为空

  • @NotEmpty 值不能为空,并且内容不为空

  • @Email 满足邮箱格式

  • 此外在引入实体类时只有加上 @Validared 注解才会生效

    //lombok 编译阶段西东为实体类生成setter getter toString
    //使用方法:引入pom依赖,在实体类上添加注解
    @Data
    public class User {
    
        @NotNull//值不能为空
        private Integer id;//主键ID
        private String username;//用户名
    
        @JsonIgnore//让 springmvc 把当前对象转化为 json 字符串的时候,忽略 password,最终 json 字符串中就没有 password 这个属性了
        private String password;//密码
    
        @NotEmpty//值不能为空,并且内容不为空
        @Pattern(regexp = "^\\S{1,10}")
        private String nickname;//昵称
    
        @Email//满足邮箱格式
        private String email;//邮箱
        
        private String userPic;//用户头像地址
        private LocalDateTime createTime;//创建时间
        private LocalDateTime updateTime;//更新时间
    }
    

分组校验

方法一:

把校验项进行归类分组,在完成不同的功能的时候,校验指定组中的校验项

  1. 定义分组
  2. 定义校验项时指定归属的分组
  3. 校验是指定要校验的分组
实体类代码
	实体类建立分组,使用groups属性进行分组
//实体类代码
@Data
public class Category {
    //分组校验
    public interface Add{//添加组
        
    }
    
    public interface update{//更新组
        
    }
    
    @NotNull(groups =update.class)
    private Integer id;//主键ID
    @NotEmpty(groups ={update.class,Add.class})//非空
    private String categoryName;//分类名称
    @NotEmpty(groups ={update.class,Add.class})//非空
    private String categoryAlias;//分类别名
    private Integer createUser;//创建人ID
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")//限定时间格式为 2024年3月4日 14:45:00
    private LocalDateTime createTime;//创建时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;//更新时间
}
conlltroller 层代码
	Controller中进行绑定需要校验的数据采用哪种组别进行校验
@PostMapping
public Result add(@RequestBody @Validated(Category.Add.class) Category category){
        categoryService.add(category);
        return Result.success();
}
    
@PutMapping
public Result update(@RequestBody @Validated(Category.update.class) Category category){
    categoryService.update(category);
    return Result.success();
}
方法二:

借助于 groups 属性

  • 如果说校验项没有分组,默认属于 default 分组
  • 分组之间可以继承,a extends b那么 a 中拥有 b 中所有校验项
@Data
public class Category {
    //分组校验
    //如果说校验项没有分组,默认属于 `default` 分组
    //分组之间可以继承,a extends b	那么 a 中拥有 b 中所有校验项
    public interface Add extends Default {//添加组

    }

    public interface update extends Default{//更新组

    }

    @NotNull(groups =update.class)
    private Integer id;//主键ID
    @NotEmpty//非空
    private String categoryName;//分类名称
    @NotEmpty//非空
    private String categoryAlias;//分类别名
    private Integer createUser;//创建人ID
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")//限定时间格式为 2024年3月4日 14:45:00
    private LocalDateTime createTime;//创建时间
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;//更新时间
}

自定义校验

已有的注解不能满足所有的校验要求,特殊的情况需要自定义校验(自定义校验注解)

  1. 自定义注解State
  2. 自定义校验数据的类 StateValidation 实现 ConstraintValidator 接口
  3. 在需要校验的地方使用自定义注解
自定义校验接口
@Documented//元注解
//元注解 标明注解可以用在哪里,属性,方法,类....
//我们这里用到属性上,只需有field即可
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)//标明我们的注解会在哪个阶段保留,源码,编译,运行,
@Constraint(
        validatedBy = {StateValidation.class}//指定提供校验规则的类
)//用来指定谁给注解提供校验规则
public @interface State {//自定义注解
    String message() default "state 参数的值只能是已发布或草稿";//提供校验失败后的提示信息
    //制定分组
    Class<?>[] groups() default {};
    //负载    获取到State注解的附加信息
    Class<? extends Payload>[] payload() default {};
}
自定义规则类
/**
 * ConstraintValidator<给那个注解提供校验,校验的数据类型>
 */
public class StateValidation implements ConstraintValidator<State,String> {

    /**
     *
     * @param value 需要校验的数据
     * @param constraintValidatorContext
     * @return true:校验通过  false:校验不通过
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) {
        //提供校验规则
        if(value==null){
            return false;//校验不通过
        }
        if(value.equals("已发布")||value.equals("草稿")){
            return true;
        }
        return false;
    }
}
  • 17
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ldealing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值