当前位置: 首页 > news >正文

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

需求

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

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

目标

自定义一个用于校验手机号码格式的注解@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;@Overridepublic void initialize(Phone constraintAnnotation) {ConstraintValidator.super.initialize(constraintAnnotation);description = constraintAnnotation.description();}@Overridepublic 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位

在这里插入图片描述

指定 手机号码的详细描述

在这里插入图片描述

相关文章:

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

需求 新增接口 和 修改接口 中&#xff0c;手机号码的格式校验是普遍需要的。 在每个手机号码字段上添加正则表达式校验注解来实现校验&#xff0c;重复书写&#xff0c;容易出错&#xff1b;在不同的手机号码字段上&#xff0c;可能使用了不同的校验规则&#xff0c;无法有效…...

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

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

PWN Test_your_nc Write UP

目录 PWN 00 解题过程 总结归纳 PWN 01 解题过程 总结归纳 PWN 02 解题过程 总结归纳 PWN 03 解题过程 总结归纳 PWN 04 解题过程 总结归纳 CTF PWN 开始&#xff01; 冲就完了 PWN 00 解题过程 ssh远程链连接 ssh ctfshowpwn.challenge.ctf.show -p28151 输…...

Centos7配置firewalld防火墙规则

这里写自定义目录标题 欢迎使用Markdown编辑器一、简单介绍二、特点和功能2.1、区域&#xff08;Zone&#xff09;2.2、运行时和永久配置2.3、服务和端口2.4、动态更新2.5、连接跟踪2.6、D-Bus接口 三、设置规则3.1、启动防火墙服务3.2、新建防火墙规则的服务&#xff0c;添加端…...

【新版】系统架构设计师 - 未来信息综合技术

个人总结&#xff0c;仅供参考&#xff0c;欢迎加好友一起讨论 文章目录 架构 - 未来信息综合技术考点摘要信息物理系统CPS的体系架构CPS 的技术体系CPS应用场景 人工智能分类关键技术机器学习 机器人发展分类机器人4.0 边缘计算概念与特点边云协同安全应用场景 数字孪生关键技…...

CAD二次开发LineSegment2d

在C#的CAD二次开发中&#xff0c;LineSegment2d 是AutoCAD的.NET API中的一个类&#xff0c;用于表示二维空间中的线段。它包含了起点和终点的坐标信息&#xff0c;并提供了一些方法用于进行线段之间的计算和判断。 LineSegment2d 类具有以下常用属性和方法&#xff1a; Star…...

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

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

如何把word的页眉页脚改为图片

前言 亲戚A&#xff1a; 听说你是计算机专业&#xff1f; 沐风晓月&#xff1a; 是啊 亲戚A&#xff1a; 那正好&#xff0c;来看看我这个页眉怎么改成图片 沐风晓月&#xff1a; 一万匹马奔腾而过 亲戚B&#xff1a; 听说你是英语专业&#xff1f; 沐风晓月&#xff1a; 是啊…...

spring6-实现简易版IOC容器

手写简易版IOC容器 1、回顾Java反射2、实现Spring的IoC 我们都知道&#xff0c;Spring框架的IOC是基于Java反射机制实现的&#xff0c;下面我们先回顾一下java反射。 1、回顾Java反射 Java反射机制是在运行状态中&#xff0c;对于任意一个类&#xff0c;都能够知道这个类的所…...

Feign接口调用GET请求@RequestParam传参丢失

文章目录 问题现象排查解决GET加注解解决使用POST方式解决 时间戳传参失败 问题现象 项目使用的是Spring Cloud微服务&#xff0c;服务间调用使用的是Feign在一次服务调用时&#xff0c;发现GET传参丢失&#xff0c;没有传递过去任何参数加了RequestParam注解&#xff0c;发现…...

LeetCode每日一题 | 309.买卖股票的最佳时机含冷冻期

题目链接&#xff1a; 309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 算法图解&#xff1a; 解题代码&#xff1a; class Solution { public:int maxProfit(vector<int>& prices) {int n prices.size();vector&…...

HTML的学习 Day02(列表、表格、表单)

文章目录 一、列表列表主要分为以下三种类型&#xff1a;1. 无序列表&#xff08;Unordered List&#xff09;&#xff1a;2. 有序列表&#xff08;Ordered List&#xff09;&#xff1a;将有序列表的数字改为字母或自定义内容li.../li 列表项标签中value属性&#xff0c;制定列…...

Android shape记录

之前一直觉得dataPath很好用&#xff0c;可以画各种矢量图。今天发现用shape画图也不错&#xff0c;记录一下自己用shape画的图。 一般使用shape就是定义形状、stroke边、solid内部、corners圆角等&#xff0c;代码 <?xml version "1.0" encoding "utf-8&q…...

WSL2和ubuntu的安装过程

目录 1.WSL2的安装 2.Ubuntu的安装 3.安装完成后的打开方式 1.WSL2的安装 按下WINX键&#xff0c;选择Windows PowerShell (管理员) 1.1执行以下命令&#xff0c;该命令的作用是&#xff1a;启用适用于 Linux 的 Windows 子系统 dism.exe /online /enable-feature /featur…...

力扣第150题 逆波兰表达式求值 stack c++

题目 150. 逆波兰表达式求值 中等 给你一个字符串数组 tokens &#xff0c;表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意&#xff1a; 有效的算符为 、-、* 和 / 。每个操作数&#xff08;运算对象&#xff09;都…...

三、飞行和射击

目录 1.飞行的实现 2.限制玩家视角 3.射击的实现 4.附录 1.飞行的实现 &#xff08;1&#xff09;在Player预制体上挂载Configuration Joint组件&#xff0c;并修改其Y Drive属性 &#xff08;2&#xff09; 修改PlayerInput.cs和PlayerController.cs以实现飞行 PlayerIn…...

GitHub与GitHubDesktop的使用

1、介绍 见天来学习使用GitHub与GitHubDesktop。 学习前先来介绍一下什么是GitHub。 GitHub是一个基于Git的代码托管平台和开发者社区。它提供了一个Web界面&#xff0c;让开发者能够轻松地托管、共享和管理他们的软件项目。 在GitHub上&#xff0c;开发者可以创建自己的代…...

AIGC 微调的方法

AIGC 的微调方法可以分为以下步骤&#xff1a; 数据准备&#xff1a;收集尽可能多的数据&#xff0c;包括输入和输出数据&#xff0c;并将其划分为训练集、验证集和测试集。 模型选择&#xff1a;选择合适的模型结构&#xff0c;例如多层感知器&#xff08;MLP&#xff09;、卷…...

gcc编译webrtc x64

gcc使用Ubuntu系统已经有的gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) 1、下载离线版webrtc&#xff08;也可以翻墙下载webrtc&#xff09; 百度云链接: 链接: https://pan.baidu.com/s/1oHVz9bxXlW3Q6uO996c5XA 提取码: ojbs 2、下载gn https://github.com/timnieder…...

uni-app 实现凸起的 tabbar 底部导航栏

效果图 在 pages.json 中设置隐藏自带的 tabbar 导航栏 "custom": true, // 开启自定义tabBar(不填每次原来的tabbar在重新加载时都回闪现) 新建一个 custom-tabbar.vue 自定义组件页面 custom-tabbar.vue <!-- 自定义底部导航栏 --> <template><v…...

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

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

计算机网络笔记 第二章 物理层

2.1 物理层概述 物理层要实现的功能 物理层接口特性 机械特性 形状和尺寸引脚数目和排列固定和锁定装置 电气特性 信号电压的范围阻抗匹配的情况传输速率距离限制 功能特性 -规定接口电缆的各条信号线的作用 过程特性 规定在信号线上传输比特流的一组操作过程&#xff0…...

使用CreateProcess崩溃:处未处理的异常: 0xC0000005: 写入位置 0x00415652 时发生访问冲突

问题代码 if (!CreateProcess(NULL,L"pela.exe",NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi)){return 0;}如果CreateProcess的第二个参数字符串是常量或者是储存在堆中的就会被写保护&#xff0c;崩溃。如果字符串定义到栈或者全局变量就不存在此问题了。 正确的…...

Java 华为真题-出租车计费

需求 程序员小明打了一辆出租车去上班。出于职业敏感&#xff0c;他注意到这辆出租车的计费表有点问题&#xff0c;总是偏大。 出租车司机解释说他不喜欢数字4&#xff0c;所以改装了计费表&#xff0c;任何数字位置遇到数字4就直接跳过&#xff0c;其余功能都正常。 比如&…...

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

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

微服务moleculer01

1.官网地址&#xff1a; Moleculer - Progressive microservices framework for Node.js 2. github代码地址&#xff1a; GitHub - moleculerjs/moleculer: :rocket: Progressive microservices framework for Node.js Moleculer是基于Node.js的一款快速、多功能的微服务框…...

C++中将指针传递给函数

C中将指针传递给函数 指针是一种将内存空间传递给函数的有效方式&#xff0c;其中可包含函数完成其工作所需的数据&#xff0c;也可包含操作结果。将指针作为函数参数时&#xff0c;确保函数只能修改您希望它修改的参数很重要。例如&#xff0c;如果函数根据以指针方式传入的半…...

【51单片机编写占空比按秒渐亮与渐暗】2023-10-2

昨天刚在W10上安装CH340驱动&#xff0c;又下载到板子上LCD1602定时器时钟程序&#xff0c;为了调试&#xff0c;调用了一个LED观察控制蜂鸣器按秒响的变量&#xff0c;几经调试才发觉该开发板用的是有源蜂鸣器&#xff0c;不用IO取反操作&#xff0c;直接控制IO的高低电平即可…...

OCI 发布了容器运行时和镜像规范!

7 月 19 日是开放容器计划Open Container Initiative&#xff08;OCI&#xff09;的一个重要里程碑&#xff0c;OCI 发布了容器运行时和镜像规范的 1.0 版本&#xff0c;而 Docker 在这过去两年中一直充当着推动和引领的核心角色。 我们的目标是为社区、客户以及更广泛的容器行…...

C++学习笔记一: 变量和基本类型

本章讲解C内置的数据类型&#xff08;如&#xff1a;字符、整型、浮点数等&#xff09;和自定义数据类型的机制。下一章讲解C标准库里面定义的更加复杂的数据类型&#xff0c;比如可变长字符串和向量等。 1.基本内置类型 C内置的基本类型包括&#xff1a;算术类型和空类型。算…...

企业的建站方式/广告营销是做什么的

建立多任务模型&#xff0c;并用线程来实现符合POSIX标准的UNIX操作系统提供了线程的控制函数&#xff0c;如&#xff1a;线程的创建和终止、线程之间的互斥、线程之间的同步等。利用这些系统函数可以成功地模拟消息队列&#xff0c;来实现线程间数据共享和同步&#xff0c;以完…...

网站建设我们的优势/seo怎么发布外链

Java程序的运行包括两个非常重要的阶段&#xff1a;一.编译阶段第一步&#xff1a;程序员需要在计算机硬盘中任意位置创建一个.java扩展名的文件&#xff0c;该文件被称为 java源文件&#xff0c;源文件当中编写的是java源代码/源程序。java源代码必须符合java的语法规则。第二…...

12306网站是学生做的/品牌推广案例

10月12日消息&#xff0c;美股周三平开&#xff0c;股市努力从昨日的大跌中收复失地。投资者在等待美联储最新会议纪要发布。 截止发稿&#xff0c;道琼斯工业平均指数报18,114.35点&#xff0c;下跌14.31点&#xff0c;跌幅为0.08%。标准普尔500指数报2,137.06点&#xff0c;上…...

天津建设工程信息网网/湖南企业竞价优化服务

代  码 #输出元组变量 tuple (1,2,3,4,5,a,b,c) print(tuple) 运行结果 (1, 2, 3, 4, 5, a, b, c) 代  码 #输出字典变量 dict {a:1, b:2,c:3} print(dict) 运行结果 {a: 1, b: 2, c: 3...

东营做网站的公司/国际羽联最新排名

本节主要总结以下几个内容&#xff1a; 对model泛化能力进行评估的实验方法model性能的度量指标用统计检验的方法 比较不同model之间性能的差异解析 model 的 bias and variance 一、对model泛化能力进行评估的实验方法 当我们训练好一个模型时&#xff0c;往往希望知道的并…...

福永网站建设/直接进网站的浏览器

版权声明&#xff1a;可以任意转载&#xff0c;转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明 (http://blog.csdn.net/quqi99) 问题 今天在处理一个AppArmor的问题时&#xff0c;遇到一个奇怪的问题&#xff0c;在/etc/apparmor.d/usr.bin.nova-compute文…...