【SpringBoot】Validator组件+自定义约束注解实现手机号码校验和密码格式限制

news2025/1/20 16:24:43

在这里插入图片描述

🏡浩泽学编程:个人主页

 🔥 推荐专栏:《深入浅出SpringBoot》《java对AI的调用开发》
              《RabbitMQ》《Spring》《SpringMVC》

🛸学无止境,不骄不躁,知行合一

文章目录

  • 前言
  • 一、@Constraint介绍
    • 用法
  • 二、具体实现
  • 总结


前言

SpringBoot项目实现Validator组件+自定义约束注解(自定义校验规则)@IsMobile校验手机号码以及密码格式限制。


一、@Constraint介绍

  • @Constraint注解是Java Bean Validation框架中的一个注解,用于自定义约束注解,即自定义校验规则。
  • 通过在自定义注解上添加@Constraint注解,可以将该注解标记为一个自定义约束注解。同时,需要指定一个实现了ConstraintValidator接口的验证器类,用于验证该注解所标记的字段或参数是否符合自定义的校验规则。

用法

@Constraint注解的属性:

  • validatedBy:用于指定实现了ConstraintValidator接口的验证器类。该属性的值是一个Class对象数组,可以指定多个验证器类。
  • message:用于指定当校验失败时,所返回的错误信息。可以使用占位符{},在校验器中使用具体的参数替换。
  • groups:用于指定分组,即根据不同的分组应用不同的校验规则。
  • payload:用于指定元数据,即可以通过该属性传递一些额外的验证信息。

使用@Constraint注解,可以通过自定义注解的方式,为字段或参数添加自定义的校验规则,并实现校验逻辑。这样,在进行参数校验时,可以方便地通过注解的方式来调用自定义的校验规则。

ConstraintValidator接口,它有两个泛型第一个是自定义的注解类,第二个就是要验证的数据的类型,有两个方法,分别是initialize(初始化方法)和isValid(验证逻辑方法)返回true,则验证通过,否则是不通过。

二、具体实现

  • 在做项目登录时,我采用的是手机号+密码登录,这时就需要手机号校验和密码格式限制,这些正确后再去数据库验证手机号密码是否正确。
  • 手机号:11位且符合手机号格式规定,不为空;密码:最短为6位,不为空。

引入组件依赖(SpringBoot版本选择的是2.6.3):

<!-- validation组件-->
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

封装一个登录参数类LoginVo:

import com.example.seckill.validator.IsMobile;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;


/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: LoginVo
 * @Description: 登录参数
 * @Date: 2024/1/23 17:18
 */
@Data
public class LoginVo {
    @NotNull
    @IsMobile
    private String mobile;
    @NotNull
    @Length(min = 6)
    private String password;
}

其中@IsMobile是自定义的校验手机号的注解。其他注解是validation组件中的。可以看到实现了不为空以及密码格式限制(最少六位),组件内还有许多注解,自己查询使用。下面看一下手机号校验的具体实现。

创建手机号校验工具类:

import org.springframework.util.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: ValidatorUtil
 * @Description: 手机号码校验
 * @Date: 2024/1/23 17:48
 */
public class ValidatorUtil {
    private static final Pattern mobile_pattern = Pattern.compile("^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\d{8}$");
    public static boolean isMobile(String mobile){
        if (StringUtils.isEmpty(mobile)){
            return false;
        }
        Matcher matcher = mobile_pattern.matcher(mobile);
        return matcher.matches();
    }
}

创建自定义注解@IsMobile:

import com.example.seckill.vo.IsMobileValidator;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: isMobile
 * @Description: 验证是否是手机号
 * @Date: 2024/1/24 13:47
 */
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = { IsMobileValidator.class }
)
public @interface IsMobile {
    boolean required() default true;

    String message() default "手机号码格式错误";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

按照前面的介绍:

  • validatedBy是指定验证器,即具体验证逻辑类:IsMobileValidator。
  • message:用于指定当校验失败时,所返回的错误信息
  • 这里的required是代表当前校验数据为必填:在具体验证逻辑类有实现。
  • 其他是默认的。

具体验证逻辑类IsMobileValidator:

import com.example.seckill.utils.ValidatorUtil;
import com.example.seckill.validator.IsMobile;
import org.springframework.util.StringUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @Version: 1.0.0
 * @Author: Dragon_王
 * @ClassName: IsMobileValidator
 * @Description: 手机号校验
 * @Date: 2024/1/24 13:52
 */
public class IsMobileValidator implements ConstraintValidator<IsMobile,String> {
    //必填
    private boolean required = false;

    @Override
    public void initialize(IsMobile constraintAnnotation) {
        required = constraintAnnotation.required();
    }

    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        if (required) {
            return ValidatorUtil.isMobile(s);
        }else {
            if (StringUtils.isEmpty(s)){
                return true;
            }else {
                return ValidatorUtil.isMobile(s);
            }
        }
    }
}
  • 该类继承ConstraintValidator,且泛型IsMobile指自定义注解类,String指是校验数据类型。
  • initialize初始化方法:这里初始化获得注解类的默认值。
  • isValid是校验逻辑,参数s是校验字符串。如果required为true则调用工具类校验手机号;如果不是true,则判断校验字符串是否为空,为空则通过,因为有@NotNull,所以这里无需校验空白,若字符串不为空,调用工具类校验手机号。

综上,以后在登录时,登录信息用LoginVo接收封装,自动校验手机号和密码,如下:

/***
     * @Description: 登录功能,这里会将登录信息手机号和密码自动封装为LoginVo接收,不知道的大家可以回顾一下SpringMVC。
     * @param loginVo
     * @methodName: doLogin
     * @return: com.example.seckill.vo.RespBean
     * @Author: dragon_王
     * @Date: 2024-01-23 17:23:02
     */
    @RequestMapping("/doLogin")
    @ResponseBody
    public RespBean doLogin(LoginVo loginVo){
        return userService.doLogin(loginVo);
    }

总结

以上就是Validator组件+自定义约束注解实现手机号码校验和密码格式限制的讲解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1447115.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux防火墙开放

记录一次问题 写的网络服务无法通信 代码没问题&#xff0c;IP绑定、端口绑定没问题&#xff0c;就是无法进行通信&#xff0c;这里要分2步走。 服务器控制台开放 进入防火墙 添加规则&#xff0c;这里以开放udp的8899端口为例 这里在服务器后台就已经开放了&#xff0c;但此时…

Redis相关介绍

概念 Redis&#xff1a;非关系型数据库&#xff08;non-relational)&#xff0c;Mysql是关系型数据库(RDBMS) Redis是当今非常流行的基于KV结构的作为Cache使用的NoSQL数据库 为什么使用NoSQL 关系型 数据库无法应对每秒上万次 的读写请求 表中的存储记录 数量有限 无法简单…

9.【CPP】List (迭代器的模拟实现||list迭代器失效||list的模拟实现)

介绍 list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前一个元素和后一个元素。list与forward_…

QGIS打开shp地图

地图shp文件如何打开查看 提示 open sans字体没有安装 字体天下-提供各类字体的免费下载和在线预览服务 这里搜索open sans下载 但是 还是不显示 省份名称。

数据结构——lesson2线性表和顺序表

目录 前言 一、顺序表是什么&#xff1f; 1. 静态顺序表&#xff1a;使用定长数组存储元素 2. 动态顺序表&#xff1a;使用动态开辟的数组存储。 二、接口实现 1.动态顺序表存储 2.基本增删查改接口 (1)初始化顺序表 (2)顺序表摧毁 (3)检查空间 (4)顺序表打印 (5)顺…

【JVM篇】什么是jvm

文章目录 &#x1f354;什么是Java虚拟机&#x1f6f8;Java虚拟机有什么用&#x1f339;Java虚拟机的功能&#x1f388;Java虚拟机的组成 &#x1f354;什么是Java虚拟机 JVM指的是Java虚拟机&#xff0c;本质上是一个运行在计算机上的程序&#xff0c;可以运行 Java字节码文件…

pytorch花式索引提取topk的张量

文章目录 pytorch花式索引提取topk的张量问题设定代码实现索引方法gather方法验证 补充知识expand方法gather方法randint pytorch花式索引提取topk的张量 问题设定 或者说&#xff0c;有一个(bs, dim, L)的大张量&#xff0c;索引的index形状为(bs, X)&#xff0c;想得到一个(…

位运算+leetcode ( 2 )

题一&#xff1a;只出现一次的数字&#xff08;1&#xff09; 1.链接 136. 只出现一次的数字 - 力扣&#xff08;LeetCode&#xff09; 2.思想 借用位运算中异或操作符的特点&#xff0c;a^a0&#xff0c;0^aa先定义一个sum0就用一个循环来遍历这个数组&#xff0c;每次都进行…

lv15 平台总线框架及案例 2

一、总线、设备、驱动 硬编码式的驱动开发带来的问题&#xff1a; 垃圾代码太多 结构不清晰 一些统一设备功能难以支持 开发效率低下 1.1 初期解决思路&#xff1a;设备和驱动分离 struct device来表示一个具体设备&#xff0c;主要提供具体设备相关的资源&#xff08;如…

小游戏和GUI编程(7) | SimpleNN 界面源码解析

小游戏和GUI编程(7) | SimpleNN 界面源码解析 0. 简介 SimpleNN 是 AdamYuan 在高中一年级时用 1 天时间写出来的简易 CNN, 使用 SFML 做 UI, 用于交互式输入手写数字&#xff0c;这个数字被训练好的 CNN 网络执行推理得到识别结果, 它的运行效果如下&#xff1a; 这一篇我们…

C语言——oj刷题——调整数组使奇数全部都位于偶数前面

题目&#xff1a; 输入一个整数数组&#xff0c;实现一个函数&#xff0c;来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分&#xff0c;所有偶数位于数组的后半部分。 一、实现方法&#xff1a; 当我们需要对一个整数数组进行调整&#xff0c;使得奇数位于数…

Solidworks:挑战新问题,不知道如何画出斜视图?

如果图形都是基于XYZ三个方向构造&#xff0c;没什么难度。如果有其他倾斜方向的&#xff0c;问题就难了。今天试了一下&#xff0c;看看我的3D模型。 出图纸的时候&#xff0c;不知道如何才能投影出斜视图&#xff0c;一边准确描述下面的那个小局部孔位。 补充&#xff1a;查了…

C++ Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统(3) 保存表格数据

对上两篇篇的工作C Qt框架开发| 基于Qt框架开发实时成绩显示排序系统&#xff08;1&#xff09;-CSDN博客和C Qt框架开发 | 基于Qt框架开发实时成绩显示排序系统&#xff08;2&#xff09;折线图显示-CSDN博客继续优化&#xff0c;增加一个保存按钮&#xff0c;用于保存成绩数据…

八、克服冲动(Overcoming Impulses)

6.Overcoming Impulses 六、克服冲动 The skill of focus basically boils down to a tension between two different forces: the desire to work and the desire to quit. 专注的技巧基本上可以归结为两种力量之间的张力&#xff1a;工作的欲望和停止工作的欲望。 What makes…

猫头虎分享已解决Bug || Uncaught SyntaxError: Unexpected token

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …

解锁未来:探秘Zxing二维码技术的神奇世界

解锁未来&#xff1a;探秘Zxing二维码技术的神奇世界 1. 引言 在当今数字化和智能化的社会中&#xff0c;二维码技术已经成为人们生活中不可或缺的一部分。从商品购物、支付结算到健康码、门票核销&#xff0c;二维码无处不在&#xff0c;极大地方便了人们的生活和工作。而Zx…

Vue3快速上手(三)Composition组合式API及setup用法

一、Vue2的API风格 Vue2的API风格是Options API,也叫配置式API。一个功能的数据&#xff0c;交互&#xff0c;计算&#xff0c;监听等都是分别配置在data, methods&#xff0c;computed, watch等模块里的。如下&#xff1a; <template><div class"person"…

[C++]17:二叉树进阶

二叉树进阶 一.二叉搜索树&#xff1a;1.二叉搜索树的概念&#xff1a;2.二叉搜索树的实现---循环版本&#xff1a;1.二叉搜索树的基本结构&#xff1a;2.查找&#xff1a;3.插入&#xff1a;4.中序遍历&#xff1a;5.删除&#xff1a; 3.二叉搜索树的实现---递归版本&#xff…

用代码视角揭秘刘谦扑克牌魔术

近日&#xff0c;刘谦回归春晚引发了热烈的讨论&#xff0c;尤其是刘谦表演的魔术《守岁共此时》中扑克牌登上了热搜。 如果要评选龙年春晚最好笑的节目&#xff0c;还得是尼格买提现场表演的翻车~ 除了台下的观众&#xff0c;相信很多电视机前的小伙伴也纷纷拿起扑克牌开始尝…

js中正则表达式的详解(应用场景)

文章目录 一、是什么二、匹配规则正则表达式标记贪婪模式懒惰模式分组 三、匹配方法str.match(regexp)str.matchAll(regexp)str.search(regexp)str.replace(regexp)str.split(regexp)regexp.exec(str)regexp.test(str) 四、应用场景参考文献 一、是什么 正则表达式是一种用来匹…