java的validation框架(参数校验)

news/2024/4/20 11:07:02/文章来源:https://blog.csdn.net/weixin_45703155/article/details/130001434

一.bean validation和hibernate validator参数校验常用约束注解:

空值校验类:@Null,@NotNull,@NotEmpty,@NotBlank等
范围校验类:@Min,@Size,@Digits,@Future,@Negative等
其它校验类:@Email,@URL,@AssertTrue,@Pattern等

二.初级约束注解:

1. @NotNull(message = “用户id不能为空”)

  • 没有设置值时会返回
  • 设置为userInfo.setUserId(“”);时不会返回
  • userInfo.setUserId(" ");时不会返回

2.@NotEmpty(message = “用户名不能为空”)

  • 不会自动去掉字符串前后的空格再判断是否为空
  • 没有设置值时会返回
  • userInfo.setUserName(“”);时返回
  • userInfo.setUserName(" ");时不返回

3.@NotBlank(message = “密码不能为空”)

  • 自动去掉字符串前后的空格再判断是否为空
  • 没有设置值时会返回
  • userInfo.setPassWord(“”);时返回
  • userInfo.setPassWord(" ");时返回

4.@Length(min = 6,max = 20,message = “密码不能少于6位,也不能多于20位”)

  • 即数量必须在6到20之间(包含6和20)

5.@Email(message = “邮箱不正确”)

  • 可以直接不设置值
  • 必须是正确的邮箱格式

6. @Min(value = 18, message = “年龄不能小于18岁”)

  • 可以直接不设置值
  • 即年龄必须大于或者等于18岁

7. @Max(value = 60, message = “年龄不能大于60岁”)

  • 可以直接不设置值
  • 即年龄必须等于小于60岁

8.@Past(message = “生日只能是过去的时间或者现在的时间”)

  • 可以直接不设置值
  • 传来的时间只能是过去的时间或者现在的时间,不能是未来时间

9.@Size(min = 1,message = “不能少于一个好友”)

  • 可以直接不设置值
  • 集合里面的内容不能少于1

三.中级约束注解:

1.@Valid

  • private List<@Valid UserInfo> friends;表示对UserInfo类中里面的每个属性进行验证

2.@NotNull(message = “注册时邮箱不能为空”,groups = RegisterGroup.class)

  • //注册场景 public interface RegisterGroup{}
    //登录场景 public interface LoginGroup{}
  • 注册时邮箱不能为空,登录时可以为空
  • set = validator.validate(userInfo,UserInfo.RegisterGroup.class);

3.//组排序场景
@GroupSequence({
LoginGroup.class,
RegisterGroup.class,
Default.class
})
public interface Group{}

  • set = validator.validate(userInfo,UserInfo.Group.class);
  • 先验证 LoginGroup组的,都通过才验证下面的,不通过直接返回验证错误信息,验证顺序按照上面的顺序进行验证

四.高级约束注解:

1.public void setUserInfo(@Valid UserInfo userInfo){ }
set1 = executableValidator.validateParameters(service,method1,paramObject);

  • @Valid对方法输入参数进行约束注解校验

2.public @Valid UserInfo getUserInfo(){return new UserInfo();}
set1 = executableValidator.validateReturnValue(userInfoService,method,returnValue);

  • @Valid对方法返回值进行约束校验

3.public UserInfoService(@Valid UserInfo userInfo){}
set1 = executableValidator.validateConstructorParameters(constructor,paramObject);

  • @Valid对构造函数输入参数进行校验

五.上面初,中,高级注解示例:

pom.xml

<!-- Validation 相关依赖 --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><version>2.0.1.Final</version></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>6.0.16.Final</version></dependency><dependency><groupId>javax.el</groupId><artifactId>javax.el-api</artifactId><version>3.0.0</version></dependency><dependency><groupId>org.glassfish.web</groupId><artifactId>javax.el</artifactId><version>2.2.6</version></dependency>

待验证对象实体类UserInfo.java:

package com.mystudy.elastic.job.springboot.validation;import org.hibernate.validator.constraints.Length;import javax.validation.GroupSequence;
import javax.validation.Valid;
import javax.validation.constraints.*;
import javax.validation.groups.Default;
import java.util.Date;
import java.util.List;/*** 待验证对象实体类* 用户信息类*/
public class UserInfo {//登录场景public interface LoginGroup{}//注册场景public interface RegisterGroup{}//组排序场景@GroupSequence({LoginGroup.class,RegisterGroup.class,Default.class})public interface Group{}/*** 用户id*/@NotNull(message = "用户id不能为空")private String userId;/*** 用户名*/@NotEmpty(message = "用户名不能为空")private String userName;/*** 密码*/@NotBlank(message = "密码不能为空")@Length(min = 6, max = 20, message = "密码不能少于6位,也不能多于20位")private String passWord;/*** 邮箱*/
//    @NotNull(message = "注册时邮箱不能为空",groups = RegisterGroup.class)@Email(message = "邮箱不正确")private String email;/*** 年龄*/@Min(value = 18, message = "年龄不能小于18岁")@Max(value = 60, message = "年龄不能大于60岁")private Integer age;/*** 手机号*/@Phone(message = "手机号不是158后面随便的手机号")private String phone;/*** 生日*/@Past(message = "生日只能是过去的时间或者现在的时间")private Date birthday;/*** 好友列表*/@Size(min = 1,message = "不能少于一个好友")private List<@Valid UserInfo> friends;public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}public String getUserName() {return userName;}public void setUserName(String userName) {this.userName = userName;}public String getPassWord() {return passWord;}public void setPassWord(String passWord) {this.passWord = passWord;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public List<UserInfo> getFriends() {return friends;}public void setFriends(List<UserInfo> friends) {this.friends = friends;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}
}

用户信息服务类UserInfoService.java:

package com.mystudy.elastic.job.springboot.validation;import javax.validation.Valid;/*** 用户信息服务类*/
public class UserInfoService {/***  userInfo作为输入参数* @param userInfo*/public void setUserInfo(@Valid UserInfo userInfo){}/*** userInfo作为输出参数* @return*/public @Valid UserInfo getUserInfo(){return new UserInfo();}/*** 默认构造函数*/public UserInfoService(){}/*** 接收userInfo作为参数的构造函数* @param userInfo*/public UserInfoService(@Valid UserInfo userInfo){}
}

验证测试类ValidationTest.java:

package com.mystudy.elastic.job.springboot.validation;import org.junit.After;
import org.junit.Before;
import org.junit.Test;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.Set;/*** 验证测试类*/
public class ValidationTest {//验证器对象private Validator validator;//待验证对象private UserInfo userInfo;//验证结果集合private Set<ConstraintViolation<UserInfo>> set;//验证结果集合private Set<ConstraintViolation<UserInfoService>> set1;/*** 初始化操作*/@Beforepublic void init() {//初始化验证器validator = Validation.buildDefaultValidatorFactory().getValidator();//初始化待验证对象 用户信息userInfo = new UserInfo();userInfo.setUserId(" ");userInfo.setUserName("  ");userInfo.setPassWord("  ");userInfo.setPassWord("333333");userInfo.setAge(18);userInfo.setBirthday(new Date());userInfo.setPhone("15987377373");UserInfo friend = new UserInfo();friend.setUserId("wangxiaoxi");friend.setUserName("王小喜");friend.setPassWord("wangxiaoxi");userInfo.setFriends(new ArrayList() {{add(friend);}});}/*** 结果打印*/@Afterpublic void print() {set.forEach(item -> {//输出验证错误信息System.out.println(item.getMessage());});
//        set1.forEach(item -> {
//            //输出验证错误信息
//            System.out.println(item.getMessage());
//        });}@Testpublic void nullValidation() {//使用验证器对对象进行验证set = validator.validate(userInfo);}/*** 级联验证测试方法*/@Testpublic void graphValidation() {set = validator.validate(userInfo);}/*** 验证注册时,邮箱是否为空*/@Testpublic void groupValidation() {set = validator.validate(userInfo, UserInfo.RegisterGroup.class);}/*** 组排序*/@Testpublic void groupSequenceValidate() {set = validator.validate(userInfo, UserInfo.Group.class);}/*** 对方法输入参数进行约束注解校验*/@Testpublic void paramValidation() throws NoSuchMethodException {//获取校验执行器ExecutableValidator executableValidator = validator.forExecutables();//待验证对象UserInfoService service = new UserInfoService();//待验证方法Method method1 = service.getClass().getMethod("setUserInfo", UserInfo.class);//方法的输入参数Object[] paramObject = new Object[]{new UserInfo()};//对方法的输入参数进行校验set1 = executableValidator.validateParameters(service, method1, paramObject);}/*** 对方法返回值进行约束校验*/@Testpublic void returnValueValidation() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {//获取校验执行器ExecutableValidator executableValidator = validator.forExecutables();//构造要验证的方法对象UserInfoService userInfoService = new UserInfoService();Method method = userInfoService.getClass().getMethod("getUserInfo");//调用方法得到返回值Object returnValue = method.invoke(userInfoService);//校验方法返回值是否符合约束set1 = executableValidator.validateReturnValue(userInfoService, method, returnValue);}/*** 对构造函数输入参数进行校验*/@Testpublic void constructorValidation() throws NoSuchMethodException {//获取验证执行器ExecutableValidator executableValidator = validator.forExecutables();//获取构造函数Constructor<UserInfoService> constructor = UserInfoService.class.getConstructor(UserInfo.class);Object[] paramObject = new Object[]{new UserInfo()};//校验构造函数set1 = executableValidator.validateConstructorParameters(constructor, paramObject);}
}

六.自定义注解:

自定义手机号注解@interface Phone:

package com.mystudy.elastic.job.springboot.validation;import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;/*** 自定义手机号注解*/
@Documented
//注解的作用目标(可以设置作用在类,方法等等)
@Target({ElementType.FIELD})
//注解的保留策略(注解的生命周期)
@Retention(RetentionPolicy.RUNTIME)
//不同之处:与注解关联的验证器
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {//注解验证不通过时输出的信息String message() default "手机号验证错误";//约束注解在验证时所属的组别Class<?>[] groups() default {};//约束注解的有效负载Class<? extends Payload>[] payload() default {};
}

自定义手机号注解关联的验证器class PhoneValidator implements ConstraintValidator<Phone, String>:

package com.mystudy.elastic.job.springboot.validation;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** 自定义手机号注解关联的验证器*/
public class PhoneValidator implements ConstraintValidator<Phone, String> {/*** 自定义校验逻辑方法** @param s* @param constraintValidatorContext* @return*/@Overridepublic boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {//手机号验证规则:158后面随便String check = "158\\d{8}";Pattern regex = Pattern.compile(check);String phone = Optional.ofNullable(s).orElse("");Matcher matcher = regex.matcher(phone);//返回是否匹配return matcher.matches();}
}

待验证对象实体类UserInfo:

package com.mystudy.elastic.job.springboot.validation;/*** 待验证对象实体类* 用户信息类*/
public class UserInfo {/*** 手机号*/@Phone(message = "手机号不是158后面随便的手机号")private String phone;public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}}

验证测试类ValidationTest

package com.mystudy.elastic.job.springboot.validation;import org.junit.After;
import org.junit.Before;
import org.junit.Test;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Set;/*** 验证测试类*/
public class ValidationTest {//验证器对象private Validator validator;//待验证对象private UserInfo userInfo;//验证结果集合private Set<ConstraintViolation<UserInfo>> set;/*** 初始化操作*/@Beforepublic void init() {//初始化验证器validator = Validation.buildDefaultValidatorFactory().getValidator();//初始化待验证对象 用户信息userInfo = new UserInfo();userInfo.setPhone("15987377373");}/*** 结果打印*/@Afterpublic void print() {set.forEach(item -> {//输出验证错误信息System.out.println(item.getMessage());});}@Testpublic void nullValidation() {//使用验证器对对象进行验证set = validator.validate(userInfo);}}

结果:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微信小程序自定义搜索标题栏

一&#xff1a;需求 把微信小程序标题栏处变成搜索栏。自定义返回上级页面。 二&#xff1a;需求分析 首先要把小程序标题栏设置为可自定义。然后计算原标题栏的高度组成结构。根据计算高度设置搜索框和返回按钮的布局。最后进行代码功能实现。 三&#xff1a;功能实现 1&…

4月19号软件更新资讯合集....

JavaWeb 微服务前后端分离 EurekaEleVue 版 v1.5.0 发布 v1.5.0 更新如下&#xff1a; 1、解决 token 过期无法跳转至登录页的问题&#xff1b; 2、授权服务进行重构与优化&#xff1b; 一款 Java 语言基于 SpringCloud、SpringSecurity、OAuth2、Eureka、Vue、ElementUI、…

Go Fuzzing:发现你未曾发现的漏洞

文章目录 Fuzzing(模糊测试)要求示例模拟crash 总结参考资料 Fuzzing(模糊测试) go fuzz文档 对于软件开发者而言&#xff0c;一项重要的任务就是确保程序的安全性。而其中一种风险就是软件中可能存在的漏洞。传统的测试方法往往需要耗费大量的时间和人力&#xff0c;而使用F…

4月21号软件更新资讯合集.....

PlayEdu v1.0-beta.3 发布&#xff0c;视频培训解决方案 PlayEdu 是基于 SpringBoot3 Java17 React18 开发的企业内部培训系统。它专注于提供私有化部署方案&#xff0c;包括视频&#xff0c;图片等资源的内网部署。目前主要支持有本地视频上传播放、学员邮箱登录、无限级部门…

多数据源 使用 mybatis-plus-generator 3.5.1版本进行代码生成

文章目录 前言多数据源 使用 mybatis-plus-generator 3.5.1版本进行代码生成1. 说明2. 添加依赖2.1. mybatis-plus-generator 自动生成依赖2.2. 多数据源依赖2.3. 建立新项目的完全pom.xml 3. application.yml 多数据源配置 mybatis-plus-generator配置4. 创建一个MybatisPlus…

多通道振弦传感器无线采集仪 数字传感器起始通道分配

多通道振弦传感器无线采集仪 数字传感器起始通道分配 寄存器 DS_CHNUM(299)用于设置读取到的数字传感器数据从哪个通道开始占用&#xff0c;默认为 1。 单个数字传感器占用的通道数量与具体的传感器类型有关&#xff0c;例如&#xff1a;每个激光测距仪会占用 1 个通道&#xf…

Python爬虫之MongoDB

目录 一、Mongo概述 二、安装&下载 1.下载&#xff1a; 2.安装 三、基本命令 插⼊数据 查询数据 修改数据 删除数据 索引 四、Python与MongoDB交互 1.安装pymongo 2.使⽤ 一、Mongo概述 MongoDB是什么&#xff1f; MongoDB是⾮关系型数据库(No sql) 为啥需要…

基于C#asp.net心里咨询服务网站系统

功能模块&#xff1a; 主要分为管理员和注册用户&#xff0c;注册用户可以查看所有人发布的心里文章&#xff0c;情感在线问答&#xff0c;查询相似问题&#xff0c;以及进入论坛进行交流&#xff08;发帖跟帖评论收藏等&#xff09;后台管理主要是针对个人信息修改 管理员对注…

商品价格监控业务场景,API数据分析

商品价格监控指的是对特定商品价格进行实时监控和跟踪&#xff0c;及时更新最新价格并分析价格变化的行为。这种监控可以帮助企业及时了解市场行情&#xff0c;并根据价格变化情况做出相应的调整&#xff0c;以更好地应对市场变化。 一般来说&#xff0c;商品价格监控需要以下…

KVM虚拟机的磁盘无损扩容方法-qcow2格式的

起因&#xff1a;我的KVM主机上安装了基于Debian11的 虚拟机母鸡&#xff0c;其他虚拟机都由此克隆而来。因为最初只配置了8G的虚拟硬盘&#xff0c;因此在需要占用比较大的空间的应用时&#xff0c;就比较麻烦。度娘等中文搜索结果没找到答案&#xff0c;只能google了。 这里…

JavaScript概述四(DOM文档对象模型)

1.DOM(Document Object Model) 会把网页里面的元素当成对象去操作,包含对象的属性,属性值,方便我们去 操作网页。 整个页面最终会形成一个对象 :document ,页面里面的所有的元素(如 标签 ) 最终都会转换成 js 里面的对象。 1.1 获取页面的元素&#xff08;通过选择器&#xff0…

JS-11A/224时间继电器 JOSEF约瑟 板前、板后接线

系列型号&#xff1a; JS-11A/11集成电路时间继电器&#xff1b;JS-11A/12集成电路时间继电器&#xff1b; JS-11A/13集成电路时间继电器&#xff1b;JS-11A/136集成电路时间继电器&#xff1b; JS-11A/137集成电路时间继电器&#xff1b;JS-11A/22集成电路时间继电器&#…

数据结构与算法(三):数论(树形结构、二叉树、二叉搜索树、红黑树、Btree、B+Tree、赫夫曼树、堆树)

数论&#xff08;树形结构、二叉树、二叉搜索树、红黑树、Btree、BTree、赫夫曼树、堆树&#xff09; 树形结构概念 在树形结构里面重要的术语&#xff1a; 结点&#xff1a;树里面的元素。 父子关系&#xff1a;结点之间相连的边 子树&#xff1a;当结点大于1时&#xff0…

华为OD机试真题(Java),数字涂色(100%通过+复盘思路)

一、题目描述 疫情过后&#xff0c;希望小学终于又重新开学了&#xff0c;三年二班开学第一天的任务是将后面的黑板报重新制作。 黑板上已经写上了N个正整数&#xff0c;同学们需要给这每个数分别上一种颜色。 为了让黑板报既美观又有学习意义&#xff0c;老师要求同种颜色的…

LoadRunner参数化最佳实践:让你的性能测试更加出色!

距离上次使用loadrunnr 已经有一年多的时间了。初做测试时在项目中用过&#xff0c;后面项目中用不到&#xff0c;自己把重点放在了工具之外的东西上&#xff0c;认为性能测试不仅仅是会用工具&#xff0c;最近又想有一把好的利器毕竟可以帮助自己更好的完成性能测试工作。这算…

QMS-云质说质量 - 1 张小泉的质量危机

云质QMS原创 转载请注明来源 作者&#xff1a;王洪石 引言 百年老店的拍蒜质量门 最近张小泉拍蒜断刀事件&#xff0c;吸引了全民关注&#xff0c;虽然随后发布了“断刀召集令”&#xff0c;但从事件发生到后续拖沓且不专业的应对&#xff0c;张小泉肯定是“失蒜”了。 张小泉…

Spring Security实战(六)—— 跨域与CORS

跨域是一种浏览器同源安全策略&#xff0c;即浏览器单方面限制脚本的跨域访问。 一、认识跨域 跨域&#xff08;Cross-Origin&#xff09;指的是在Web开发中&#xff0c;当一个网页的内容要从不同源&#xff08;即不同的域名、协议或端口&#xff09;获取时&#xff0c;就会发…

ajax的介绍及使用

ajax的介绍 开发流程 前端 ajax:前后端沟通的桥梁 后端 ajax介绍 ajax叫做异步的Javascript和xml ajax通过浏览器与服务器&#xff08;后端&#xff09;进行少量数据交互&#xff0c;进行页面异步更新&#xff08;网页不会重新加载&#xff09; 优点&#xff1a; 减轻服务器负…

Vue3进阶使用详解(node.js、Vue3路由基础项目、axios的使用详细(实现数据分页---前后端分离)、axios加载失败)

Vue3进阶使用详解(node.js、Vue3路由基础项目、axios的使用详细(实现数据分页—前后端分离)、axios加载失败) Vue cli CLI是Commond-Line Interface&#xff0c;翻译为命令界面&#xff0c;又称脚手架。VueCLI是一个官方发布vue.js项目脚手架。使用VueCLI可以快速搭建vue开发…

v-for比v-if优先级更高?面试官:回去等通知吧

大厂面试题分享 面试题库 前后端面试题库 &#xff08;面试必备&#xff09; 推荐&#xff1a;★★★★★ 地址&#xff1a;前端面试题库 web前端面试题库 VS java后端面试题库大全 前言 v-if和v-for哪个优先级更高呢&#xff1f;这是面试官常常问到的一个问题&#xff0c;…