• Java参数校验详解:使用@Valid注解和自定义注解进行参数验证


      很多时候我们需要使用不少if、else等等逻辑判断及验证,这样在进行一些重复的参数校验会很麻烦,且以后要维护也会吃力。

      而这样就可以使用javax.validation验证(Validation)常见的验证操作包括验证数据的类型、格式、长度、范围、唯一性等

    javax.validation 包:Java SE 6+ 中引入了 javax.validation 包,作为 Bean Validation 规范的一部分。这个包提供了一组注解和接口,可以方便地进行数据验证。

    1. <dependency>
    2.    <groupId>org.springframework.bootgroupId>
    3.    <artifactId>spring-boot-starter-validationartifactId>
    4. dependency>

      而对于一般写在业务逻辑类中的参数校验语句,可以省略。如将@Valid注解填写在登录接口的方法参数中:

    1. @PostMapping("/login")
    2. public RespBean login(@Valid @RequestBody User user) {
    3.    log.info("{}", user);
    4.    return userService.login(user);
    5. }
    • @Valid 注解对入参进行相应的校验:

    注解使用在方法参数上,然后对于参数的校验要求可去参数的实体类进行校验条件的填写。

    1. /**
    2. * @author Z
    3. * @date 2023/9/27 21:25
    4. */
    5. @Data
    6. public class User {
    7.    @NotNull //账号非空
    8.    //这个@Mobile是自定义判断注解,下面有对其的创建进行详细的讲解
    9.    @Mobile(required = true)
    10.    private String mobile;
    11.    @NotNull //密码非空
    12.    @Length(min = 32)  //长度的限制
    13.    private String password;
    14. }

    以及如: @Size(min=1, max=12) 代表:长度在 1 ~ 12 字符之间。其他一些判断的注解可以去该导入的外部库查看。

    也可以自定判断条件注解:如@Mobile这个自定义的注解:

    1.创建软件包:Validation

    2.创建需要的注解:Mobile

    3.而对于这个注解的写法,直接去拷贝javax.validation 包中已经写好的注解,如:@Notnull注解进行修改:(有报错的地方就删除不用即可)

    @Notnull注解如下:
    1. @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
    2. @Retention(RetentionPolicy.RUNTIME)
    3. @Repeatable(NotNull.List.class)  //爆红了删除
    4. @Documented
    5. @Constraint(validatedBy = {}) //校验规则的定义
    6. public @interface NotNull {
    7.    String message() default "{javax.validation.constraints.NotNull.message}";
    8.    //修改校验的消息
    9.    Class[] groups() default {};
    10.    Classextends Payload>[] payload() default {};
    11. }

    而在这里在添加一条属性:(代表必填)

     boolean required() default true;

    • 自定义的@Mobile如下:

    1. /**
    2. * @author Z
    3. * @date 2023/9/28 8:53
    4. */
    5. @Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
    6. @Retention(RetentionPolicy.RUNTIME)
    7. @Documented
    8. //自己定义校验规则的一个类:MobileValidator.class (手机号码校验规则类)
    9. //将自定义规则类放进@Constraint(validatedBy={}) 中
    10. @Constraint(validatedBy = {MobileValidator.class})
    11. public @interface Mobile {
    12.    boolean required() default true;
    13.    //信息,抛出的是BindException,前端页面接收的话,我们要进行异常的捕获
    14.    String message() default "手机号码格式错误";
    15.    Class[] groups() default {};
    16.    Classextends Payload>[] payload() default {};
    17. }

    而我们需要进行自己定义检验规则,创建一个校验规则类,并将其放进@Constraint(validatedBy={}) 中

    • 自定义校验规则类:

    1. /**
    2. * 手机号码校验规则
    3. *
    4. * @author Z
    5. * @date 2023/9/28 8:56
    6. */
    7. public class MobileValidator implements ConstraintValidator {
    8.    private boolean required = false;
    9.    //初始化:获取是否需要是必填的
    10.    @Override
    11.    public void initialize(Mobile constraintAnnotation) {
    12.        //获取到填的值:true或者false
    13.        required = constraintAnnotation.required();
    14.   }
    15.    @Override
    16.    public boolean isValid(String value, ConstraintValidatorContext context) {
    17.        //必填:则使用手机号码校验工具类去校验
    18.        if (required){
    19.            return ValidatorUtil.Mobile(value);
    20.        //非必填:
    21.       }else {
    22.            if (StringUtils.isEmpty(value)){ //传的号码为空
    23.                return true;
    24.           }else {
    25.                //传的号码非空,则使用手机号码校验工具类去校验
    26.                return ValidatorUtil.isMobile(value);
    27.           }
    28.       }
    29.   }
    30. }
    • 而对于手机号码的校验工具类:

    添加依赖:

    1. <dependency>
    2.    <groupId>org.apache.commonsgroupId>
    3.    <artifactId>commons-lang3artifactId>
    4. dependency>

    使用正则表达进行手机号码的校验:

    1. import org.apache.commons.lang3.StringUtils;
    2. import java.util.regex.Matcher;
    3. import java.util.regex.Pattern;
    4. /**
    5. * 手机号码校验类 (使用正则表达式)
    6. *
    7. * @author Z
    8. * @date 2023/9/27 21:45
    9. */
    10. public class ValidatorUtil {
    11.    private static final Pattern mobile_pattern = Pattern.compile("[1]([3-9])[0-9]{9}$");
    12.    public static boolean Mobile(String mobile) {
    13.        if (StringUtils.isEmpty(mobile)){
    14.            return false;
    15.       }
    16.        Matcher matcher = mobile_pattern.matcher(mobile);
    17.        return matcher.matches();
    18.   }
    19. }

  • 相关阅读:
    win11一直弹出用户账户控制怎么解决
    【云开发】- 在小程序端操作云存储
    [2020 新春红包题]3(libc2.29 tcache tashing unlink )
    瑞吉外卖之移动端菜品数据的展示
    如何一次性解压多个文件
    分布式存储系统之Ceph集群存储池操作
    计算机毕业设计Java酒店信息管理(源码+系统+mysql数据库+lw文档)
    银行招聘问题集锦
    转行自学软件测试没后悔,我的经历证明,改变永远没有错
    忆联消费级SSD AH660:将用户体验推向新高度
  • 原文地址:https://blog.csdn.net/weixin_72926030/article/details/133842350