Spring MVC中参数校验器的使用和自定义参数校验器

Spring MVC中参数校验器的使用和自定义参数校验器

项目案例代码:https://github.com/IndustriousSnail/learning-notes/tree/master/springboot/SpringMvc自定义参数校验器/validator

目录

一、参数校验器简介

在Http请求中会传递一些参数,对于这些参数,后台需要经过一些校验,如果校验不通过,就没有必要进行接下来的处理。
比如,验证账号密码是否为空等等。

Spring为我们提供了一些默认的参数校验器,比如@NotNull, @Length 等。
但是这些并不能满足所有需求,所以需要自定义参数校验器。

二、自定义参数校验器案例

2.1 场景介绍

假设我们现在需要对登录的“用户名”和“密码进行校验”。 我们现在有如下Controller:
@RestController
public class LoginController {

    @GetMapping("/login")
    public Boolean login(LoginVO loginVO){
        //todo 登录处理 ....
        return true;
    }
}

// public class LoginVO {
//     private String username;
//     private String password;
// }

我们需要对 loginVO 中的 username 和 password 字段进行校验。
如果在login()方法中进行该逻辑的编写,也可以,但是如果还存在其他的方法(如修改密码)需要对loginVO进行校验,那么就又要再写一遍。
这样就出现了重复逻辑。所以需要对参数进行统一校验。

该案例,以判断password是否同时包含大小写为例。进行自定义参数校验器的实现。

2.2 参数校验具体实现

2.2.1 为LoginVO增加注解
@NotNull  //参数校验,不能为空
private String username;

@NotNull
@Length(min = 6)  //长度不小于6
@IsComplex //增加自定义的验证器
private String password;
2.2.2 在需要校验的VO类型增加@Valid注解
//增加@Valid注解,校验loginVO对象
public Boolean login(@Valid LoginVO loginVO){}

此时重启程序,发现如果传递的参数不对,会返回400错误。说明参数校验已经生效。

2.2.3 自定义校验注解
@Target({ElementType.FIELD})  //Target注解描述了该注解需要可以修饰哪些内容。 这里指明只能修饰字段。
@Retention(RetentionPolicy.RUNTIME)  //Retention注解描述了该注解是在什么期间生效的。 这里指明是运行期生效。
@Documented   //表明这个注解应该被 javadoc工具记录
@Constraint(validatedBy = {IsComplexValidator.class})  //@Constraint注解就说明这个字段是要被经过验证的。 validateBy参数填入需要经过的验证器类。
public @interface IsComplex {

    String message() default "密码不够复杂"; //当校验不通过时的提示信息。 必须有

    Class<?>[] groups() default { };  //必须有

    Class<? extends Payload>[] payload() default { }; //必须有
}

定义该校验注解,使用该注解修饰字段。

2.2.4 校验器的具体实现
/**
 * @Description: IsComplex校验器的具体实现。
 * @implSpec ConstraintValidator<A extends Annotation, T>: A:注解, T:A注解修改的类型
 */
public class IsComplexValidator implements ConstraintValidator<IsComplex, String> {

    /**
     * 初始化, 整个生命周期只会执行一次,在第一次验证时执行。
     * @param constraintAnnotation
     */
    @Override
    public void initialize(IsComplex constraintAnnotation) {
        System.out.println("initialize");
    }

    /**
     * 通过该方法,对参数进行验证,看是否通过。
     * @param value 修饰字段的值。
     * @param context 上下文
     * @return true:验证通过。 false:验证不通过。
     */
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        //判断密码是否同时包含大小写
        boolean hasUpper=false,hasLower=false;
        for(byte b: value.getBytes()){
            if('A'<=b&&b<='Z') hasUpper=true;
            if('a'<=b&&b<='z') hasLower=true;
        }
        return hasUpper&&hasLower;  //如果同时包含大小写,则验证通过。
    }
} 
  1. 实现ConstraintValidator接口,重写其方法。
  2. 在isValid写具体校验逻辑。通过返回true,不通过返回false
2.2.5 校验失败统一异常处理
当校验失败时,会抛出BindException异常,http会响应400。 如果要做统一异常处理,可以使用ControllerAdvice捕获异常。
@ControllerAdvice
@ResponseBody
public class ValidatorExceptionHandler{

    /**
     * 使用@ExceptionHandler注解,处理BindException异常。该异常是spring提供的参数校验失败时抛出的异常。
     * @param e 异常对象
     * @return 返回的http内容
     */
    @ExceptionHandler(value = BindException.class)
    public String exceptionHandler(BindException e){
        return e.getAllErrors().get(0).getDefaultMessage();  //参数校验会抛出多个异常,这里取第一个。而它的默认信息就是IsComplex注解中定义的message的默认值。
    }
}
2.2.6 验证结果
此时在浏览器中输入
http://localhost:8080/login?username=1111&password=AAAAA

可以看到浏览器打印的是“长度需要在6和2147483647之间”。
这个信息是@Length注解的message信息。

输入:

http://localhost:8080/login?username=1111&password=AAAAAAA

浏览器打印“密码不够复杂”

输入

http://localhost:8080/login?username=1111&password=AAAAAAAaaa

浏览器打印“true”

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

iioSnail

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

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

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

打赏作者

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

抵扣说明:

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

余额充值