手机号码格式校验:@Phone(自定义参数校验注解)

news2024/11/29 0:45:13

需求

新增接口修改接口 中,手机号码的格式校验是普遍需要的。

在每个手机号码字段上添加正则表达式校验注解来实现校验,重复书写,容易出错;在不同的手机号码字段上,可能使用了不同的校验规则,无法有效统一校验规则。

目标

自定义一个用于校验手机号码格式的注解@Phone,能够和现有的 Validation 兼容,使用方式和其他校验注解保持一致。

校验逻辑

有效格式

  1. 不能包含空格;
  2. 应为11位数字;

不校验非空

手机号码,校验的是格式;不校验是否为空(null 或 空字符串)。如果手机号码为空,直接通过校验;

这样设计是为了,将手机号码是否允许为空,交给接口(业务逻辑)来决定;因为在不同的业务逻辑中,有时手机号码字段可以为空,有时不能为空。

但是,无论手机号码字段是否可以为空,只要客户端传递了手机号码,就应该保证格式是正确的。

Validation本身提供的@Email注解,也是这样的处理逻辑。

注:手机号码,使用字符串类型(Integer类型装不下11位的数值)。

核心代码

注解:@Phone

package com.example.core.validation.phone;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

/**
 * 字符串必须是格式正确的手机号码。正确格式为:11位数字。
 * <p>
 * {@code null} 或 空字符串,是有效的(能够通过校验)。
 * <p>
 * 支持的类型:字符串
 *
 * @author songguanxun
 * @since 1.0
 */
@Target({FIELD})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {

    /**
     * @return the error message template
     */
    String message() default "手机号码,格式错误";

    /**
     * @return the groups the constraint belongs to
     */
    Class<?>[] groups() default {};

    /**
     * @return the payload associated to the constraint
     */
    Class<? extends Payload>[] payload() default {};

    /**
     * 手机号码的详细描述。
     * <p>
     * 用于用户提示中,当页面中存在多个手机号码时,帮助用户更好的区分是哪个手机号码填错了。
     */
    String description() default "手机号码";
}

校验器:PhoneValidator

package com.example.core.validation.phone;

import org.springframework.util.ObjectUtils;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;

/**
 * 手机号码格式校验器
 */
public class PhoneValidator implements ConstraintValidator<Phone, String> {

    // 手机号码的详细描述。
    private String description;


    @Override
    public void initialize(Phone constraintAnnotation) {
        ConstraintValidator.super.initialize(constraintAnnotation);
        description = constraintAnnotation.description();
    }


    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (ObjectUtils.isEmpty(value)) {
            return true;
        }

        if (value.contains(" ")) {
            String message = String.format("%s,格式错误:不能包含空格", description);
            resetMessage(context, message);
            return false;
        }

        if (!isPhone(value)) {
            String message = String.format("%s,格式错误", description);
            resetMessage(context, message);
            return false;
        }

        return true;
    }


    // 格式为:11位数字
    private static final Pattern PATTERN = Pattern.compile("^\\d{11}$");


    /**
     * 是手机号码
     */
    private boolean isPhone(CharSequence input) {
        return PATTERN.matcher(input).matches();
    }


    /**
     * 重置提示信息
     */
    private void resetMessage(ConstraintValidatorContext context, String messageTemplate) {
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(messageTemplate).addConstraintViolation();
    }

}

使用

@Phone 放在需要校验格式的 手机号码 字段上。

新增用户Param

package com.example.web.response.model.param;

import com.example.core.validation.phone.Phone;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;

@Data
@Schema(name = "新增用户Param")
public class UserAddParam {

    @NotBlank(message = "姓名,不能为空")
    @Schema(description = "姓名", example = "张三")
    private String name;

    @Phone
    @NotEmpty(message = "手机号码,不能为空")
    @Schema(description = "手机号码", example = "18612345678")
    private String phone;

    @Email
    @Schema(description = "电子邮箱", example = "zhangsan@example.com")
    private String email;

}

编辑用户Param

package com.example.web.response.model.param;

import com.example.core.validation.phone.Phone;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;

@Data
@Schema(name = "编辑用户Param")
public class UserEditParam {

    @NotBlank(message = "姓名,不能为空")
    @Schema(description = "姓名", example = "张三")
    private String name;

    @Phone(description = "编辑用户-手机号码")
    @NotEmpty(message = "手机号码,不能为空")
    @Schema(description = "手机号码", example = "18612345678")
    private String phone;

    @Email
    @Schema(description = "电子邮箱", example = "zhangsan@example.com")
    private String email;

}

校验效果

输入包含空格

在这里插入图片描述

输入非数字

在这里插入图片描述

输入超过11位

在这里插入图片描述

指定 手机号码的详细描述

在这里插入图片描述

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

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

相关文章

2023年9月文章一览

2023年9月编程人总共更新了4篇文章&#xff1a; 1.2023年8月文章一览 2.Programming abstractions in C阅读笔记&#xff1a;p144-p160 3.Programming abstractions in C阅读笔记&#xff1a;p161-p165 4.我为什么选择这样一份经常出差的工作 9月份大部分时间在出差&#…

【论文阅读】Prototypical Networks for Few-shot Learning

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、论文摘要方法 二、视频总结 前言 本文结合论文和youtube上的视频[Few-shot learning][2.2] Prototypical Networks: intuition, algorithm, pytorch code来…

Spring Boot中的@Controller使用教程

一 Controller使用方法&#xff0c;如下所示&#xff1a; Controller是SpringBoot里最基本的组件&#xff0c;他的作用是把用户提交来的请求通过对URL的匹配&#xff0c;分配个不同的接收器&#xff0c;再进行处理&#xff0c;然后向用户返回结果。下面通过本文给大家介绍Spr…

Linux shell编程学习笔记5:变量命名规则、变量类型、使用变量时要注意的事项

跟其他的高级开发语言一样&#xff0c;Linux Shell编程中使用的数据也需要保存在变量中。 Shell使用变量来控制其行为&#xff0c;并且可以通过更改变量值来更改Shell和其他程序的行为。 我们先来了解一下变量命令的规则、变量类型和使用变量时要注意的事项。 一、变量命名规…

Redis学习笔记(常用数据类型,发布订阅,事务和锁机制,持久化,集群,雪崩,缓存击穿,分布式锁)

一、NoSQL数据库简介 解决扩展性问题&#xff0c;如果需要对功能进行改变&#xff08;比如增删功能&#xff09;&#xff0c;用框架有一定的规范要求&#xff0c;无形中解决了扩展性问题。 Redis是一种典型的NoSQL数据库。 NoSQL的基础作用&#xff1a; 1. nginx负载均衡反向…

3. 文档操作

1. 创建文档 1.1 创建一个文档 在相应的索引下面使用_doc创建文档&#xff0c;地址为&#xff1a;http://127.0.0.1:9200/students/_doc&#xff0c;创建一个姓名张三的学生信息&#xff1a; {"姓名":"张三","年级":5,"班级":2,&qu…

MySQL数据库——索引(6)-索引使用(覆盖索引与回表查询,前缀索引,单列索引与联合索引 )、索引设计原则、索引总结

目录 索引使用&#xff08;下&#xff09; 覆盖索引与回表查询 思考题 前缀索引 语法 示例 前缀长度 前缀索引的查询流程 单列索引与联合索引 索引设计原则 索引总结 1.索引概述 2.索引结构 3.索引分类 4.索引语法 5.SQL性能分析 6.索引使用 7.索引设计…

ORACLE Redo Log Buffer 重做日志缓冲区机制的设计

最近和朋友包括一些国产数据库的研发人员交流&#xff0c;很多程序员认为 Oracle 已经过时&#xff0c;开源数据库或者他们研发的国产数据库才代表数据库发展的未来。甚至在很多交流会议上拿出自家产品的某一个功能点和 Oracle 对比就觉得已经遥遥领先。 实际上数据库系统的发展…

Spring Cloud Alibaba Nacos 配置中心 (配置持久化与动态刷新) 实战

文章目录 一、配置持久化到DB1. 找到配置文件2. 修改配置文件3. 执行数据库SQL4. 控制台创建配置文件 二、集成Nacos配置中心客户端1. 引入依赖2. 添加配置信息3. 创建配置信息4. 编写测试类5. 运行测试6. 动态刷新配置 一、配置持久化到DB 1. 找到配置文件 找到 nacos 的安装…

C#,数值计算——Ranlim32的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { /// <summary> /// High-quality random generator using only 32-bit arithmetic.Same conventions /// as Ran.Period is 3.11E37 . Recommended only when 64-bit arithmetic is not /// a…

中国1km土壤特征数据集(2010年)

简介&#xff1a; 中国1km土壤特征数据集&#xff08;2010&#xff09;是基于第二次全国土壤调查的中国1:1000000比例尺土壤图和8595个土壤剖面图&#xff0c;以及美国农业部&#xff08;USDA&#xff09;中国区域土地和气候模拟标准&#xff0c;开发了一个多层土壤粒度分布数…

开源layui前端框架 收款码生成系统源码 多合一收款码生成源码 带50多套UI模板

Layui前端的多合一收款码在线生成系统源码_附多套前端UI模板。 卡特三合一收款码生成系统源码&#xff0c;和收款啦采用一样的原理。 内部多达50多套模板&#xff0c;前端跟付款界面都特别好看。 识别收款码之后会自动加密&#xff0c;非常安全。 一样没有后台&#xff0c;一样…

2023年全球接口IP市场发展趋势分析:市占率第二IP品类,受大数据及计算需求推动高速增长[图]

接口IP是基于标准接口协议&#xff0c;实现芯片与内外部设备进行通信、传输数据的电路模块&#xff0c;分为有线接口IP与无线接口IP&#xff0c;主要用于数字信号处理和嵌入式系统中的接口设计。 接口IP分类 资料来源&#xff1a;共研产业咨询&#xff08;共研网&#xff09; …

深度学习:基于长短时记忆网络LSTM实现情感分析

目录 1 LSTM网络介绍 1.1 LSTM概述 1.2 LSTM网络结构 1.3 LSTM门机制 1.4 双向LSTM 2 Pytorch LSTM输入输出 2.1 LSTM参数 2.2 LSTM输入 2.3 LSTM输出 2.4 隐藏层状态初始化 3 基于LSTM实现情感分析 3.1 情感分析介绍 3.2 数据集介绍 3.3 基于pytorch的代码实现 3…

在Windows11家庭中文版中启用Copilot(预览版)

1、下载ViveTool-vx.x.x.zip 2、解压下载的压缩包ViveTool-vx.x.x.zip 3、复制ViveTool文件夹的路径 4、按下wins&#xff0c;打开搜索 5、输入cmd&#xff0c;并选择“以管理员身份运行” 6、在cmd中输入以下命令&#xff0c;进入ViveTool文件夹&#xff1a; cd ViveTool…

【最新版配置conda环境】新版pycharm导入新版anaconda环境

最近下载了新版pycharm和新版anaconda&#xff0c;并且在命令行创建了环境&#xff0c;想着在pycharm里面导入环境。结果现在的导入方式发生了变化。 之前是通过导入Python.exe进行的。 现在&#xff1a; 当我们点击进去之后&#xff0c;会发现找不到python.exe了。 具体什么…

网络安全复习大纲wcf

单选10判断10填空30简答25分析25 选择 &#xff08;1&#xff09;计算机网络安全是指利用计算机网络管理控制和技术措施&#xff0c;保证在网络环境中数据的&#xff08; &#xff09;、完整性、网络服务可用性和可审查性受到保护。 A、保密性 B、抗攻击性 C、网络服务管理性 …

mysql服务器时间(时区问题)

本地能查询出来数据&#xff0c;而服务端查询不出来 这是sql代码 在studentId没问题的情况我首先怀疑的就是NOW&#xff08;&#xff09;获取的时间出了问题&#xff0c;后来我想到我的数据库是上海的&#xff0c;时间应该没问题啊&#xff0c;百思不得其解。date去查了系统的…

如何将超大文件压缩到最小

1、一个文件目录&#xff0c;查看属性发现这个文件达到了2.50GB&#xff1b; 2、右键此目录选择添加到压缩文件&#xff1b; 3、在弹出的窗口中将压缩文件格式选择为RAR4&#xff0c;压缩方式选择为最好&#xff0c;选择字典大小最大&#xff0c;勾选压缩选项中的创建固实压缩&…

svn下载安装与使用教程/方法

1、官网下载SVN服务器 官网网址&#xff1a;Subversion Server for Windows | VisualSVN Server 本地新建空文件夹 桌面右击选择如下图所示&#xff1a; 填入刚刚拷贝的仓库地址&#xff0c;与所建立文件要放得地方&#xff0c;点击ok即可。 2、提交代码 新建文件&#xf…