java自定义注解验证手机格式的实现示例
作者:菜-菜-菜 发布时间:2023-06-24 10:42:44
1、@Valid与@Validated的区别
1.1 基本区别
@Valid:Hibernate validation校验机制
@Validated:Spring Validator校验机制,这个也是最常用的
@Validation只是对@Valid进行了二次封装,在使用上并没有太大区别,但在分组、注解位置、嵌套验证等功能上有所不同
1.2 作用范围
@Validated:用在类型、方法和方法参数上。但不能用于成员属性(field)
@Valid:可以用在方法、构造函数、方法参数和成员属性(field)上
1.3 分组校验
@Validated:提供分组功能,可以在参数验证时,根据不同的分组采用不同的验证机制,注解中必须提供groups属性,该属性就是做分组的必要参数
@Valid:没有分组功能
2、未使用分组校验的示例
注解:
/**
* 手机号验证正则
*/
@Target({ElementType.FIELD,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = {PhoneValidator.class})// 指定约束处理器,也就是手机号格式验证是哪个类来做校验
public @interface Phone {
String pattern() default "^(?:(?:\\+|00)86)?1\\d{10}$";
String message() default "手机号格式非法";
Class<?>[] groups() default { }; // groups用来指定分组,可以让校验采取不同的机制,当前默认未指定任何分组机制,默认每次都要进行校验
Class<? extends Payload>[] payload() default { };
// 默认分组
interface Default{
}
// 分组A
interface A{
}
}
格式校验处理器:
/**
* 校验处理器:做手机号码格式验证的核心类
*/
public class PhoneValidator implements ConstraintValidator<Phone, String> {
// 注解对象
private Phone phone;
// 初始化【Phone】对象
@Override
public void initialize(Phone constraintAnnotation) {
phone = constraintAnnotation;
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 获取【Phone】对象的手机格式验证表达式
String pattern = phone.pattern();
Pattern compile = Pattern.compile(pattern);
Matcher matcher = compile.matcher(value);
return matcher.matches();
}
作用类:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Person implements Serializable {
@Phone
private String phone;
}
注意:只有在spring或者springboot项目中才能使用,直接调用方法不会有任何效果,使用注解进行对象的属性格式校验时,必须配合@Validated一起使用(不一起使用,格式校验注解将会无效),正确操作如下:
@RestController
@RequestMapping("/admin/")
public class PersonController {
@Autowired
private PersonService personService;
@PostMapping("/query")
public Person query(@RequestBody @Validated Person params) {
return JsonResult.success(personService.queryByPhone(params));
}
}
以上示例未使用分组功能,因此每次都会校验。
3、分组校验的示例
使用分组校验示示例时,先要看看@Validated注解,因为分组校验就是配合该注解一起使用的,通过阅读注释就能理解到value属性就是用来指定分组的:
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Validated {
/**
* Specify one or more validation groups to apply to the validation step
* kicked off by this annotation.
* <p>JSR-303 defines validation groups as custom annotations which an application declares
* for the sole purpose of using them as type-safe group arguments, as implemented in
* {@link org.springframework.validation.beanvalidation.SpringValidatorAdapter}.
* <p>Other {@link org.springframework.validation.SmartValidator} implementations may
* support class arguments in other ways as well.
*/
Class<?>[] value() default {};
}
因此我们需要改动的位置有两处:
首先是注解的作用类,注解上指定groups属性
其次是controller中的请求的形参:在请求中形参的@Validated指定value值,也就是指定校验生效的分组,如果请求中的分组类型【@Validated的value值】和作用类中注解所指定的分组【@Phone中的groups属性的值】一致时,才会进行校验,否则不会执行校验
作用类:
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class Person implements Serializable {
// 指定groups属性
@Phone(groups = {Phone.A.class})
private String phone;
}
controller层:
@RestController
@RequestMapping("/admin/")
public class PersonController {
@Autowired
private PersonService personService;
@PostMapping("/query")
public Person query(@RequestBody @Validated(Phone.A.class) Person params) {
return JsonResult.success(personService.queryByPhone(params));
}
}
此时请求中的校验分组Phone.A.class和作用类中的校验分组Phone.A.class一致,所以校验会被执行
来源:https://blog.csdn.net/qq_44309181/article/details/114300078


猜你喜欢
- 本文通过介绍了Asp.Net中MVC缓存的种类,以及他们之间的区别等内容,让学习者能够深入的了解MVC缓存的原理机制,以下是具体内容:缓存是
- 下面是我的实现经历:1.首先,我是直接使用AlertDialog来实现,确定是,形状有点难看,而且获得Dialog里面的控件略显麻烦(因为我
- #define只加一个参数 的解释<stdio.h> 里有:#ifndef __STDIO_H #define &n
- 本文实例总结了java判断字符串是否为数字的方法。分享给大家供大家参考,具体如下:方法一:用JAVA自带的函数public static b
- OleDbConnection,OracleConnection 或者SqlConnection这种连接,直接执行sql语句。现在的连接方式
- 按官方修改的示例:#MidServerClient.javaimport feign.Param;import org.springfram
- 步骤,如图所示:1.添加异步任务业务类package top.ytheng.demo.task;import java.util.concu
- Android Studio卡很久(loading)的问题关于Android Studio卡在某个地方很久(更准确说应该是Loading很久
- 一、Hadoop的安装1. 下载地址:https://archive.apache.org/dist/hadoop/common/我下载的是
- 本文实例为大家分享了Android自定义View实现拖动自动吸边的具体代码,供大家参考,具体内容如下自定义View,一是为了满足设计需求,二
- 一、使用注解实现自定义映射关系当POJO属性名与数据库列名不一致时,需要自定义实体类和结果集的映射关系,在MyBatis注解开发中,使用 @
- 1、悲观锁和乐观锁我们可以将锁大体分为两类:悲观锁乐观锁顾名思义,悲观锁总是假设最坏的情况,每次获取数据的时候都认为别的线程会修改,所以每次
- 本文实例讲述了C# linq查询之动态OrderBy用法。分享给大家供大家参考。具体分析如下:groupList是原始数据集合,List&l
- 前言:项目开发中日志是不可缺少的一部分,通过日志能够定位和分析事故原因。目前流行日志框架包含了log4j、log4j2、logback等,另
- 本文实例为大家分享了Java实现斗地主的具体代码,供大家参考,具体内容如下import java.util.ArrayList;import
- 前言记录下Mybatis-Plus中条件构造器Wrapper 的一些基本用法。查询示例表结构CREATE TABLE `product` (
- 本文实例为大家分享了Unity实现俄罗斯方块的具体代码,供大家参考,具体内容如下一、使用SpriteRenderer作为小方块图片,创建7种
- 1. 并行和并发有什么区别?并行:多个处理器或多核处理器同时处理多个任务。并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执
- 预览效果图:需要权限:<uses-permission android:name="com.android.launcher
- 本文实例为大家分享了C#生成唯一订单号的具体代码,供大家参考,具体内容如下根据GUID+DateTime.Now.Ticks生产唯一订单号/