API参数如何验证?别纠结,拿去用就是
今天我们主要分享项目实战中,另一种常用的参数校验框架 Hibernate Validator,请准备好小板凳,我们的分享开始。
1.
是啥?
先抛一张图,锻炼一下你的观察力。
通过上图有没有发现,数据校验可谓是贯穿所有的应用程序层(从表示层到持久层),而通常在每一层要实现相同的验证逻辑,这样既耗时又容易出错。
那再抛一张图,欢迎大家一起来找茬(结合上幅图)。
我们会发现,为了避免每层进行重复的数据验证,可以将验证逻辑直接捆绑到域模型中,将域类与验证代码混淆。
有点意思,你可能会有点懵,莫急!你就简单认为在你的实体类属性上加点校验规则,但是这些校验规则到底该怎么加呢?
这不在 JSR380-Bean Validation 2.0 中为实体和方法验证定义元数据模型和API,是不是又茫然啦,啥是 JSR?啥是JSR380?
为了以后再见到内心不发虚,我们再解释一下。
JSR 是 Java 界的一个重要标准,是 Java Specification Requests 的缩写,意思是 Java 规范提案,任何人都可以提交 JSR ,以向 Java 平台增添新的 API 和服务。
JSR380-Bean Validation 2.0 是 Java 定义的一套最新的数据校验规范。
说了这么多,只有规范没有实现,一切都是扯淡。别急,该我们的大猪蹄子 Hibernate Validator 登场了。
那 Hibernate Validator 到底是啥?一句话说清楚:Hibernate Validator 是 JSR 380 数据校验规范的一种实现。
到这,你多多少少应该了解 JSR、JSR 380、Hibernate Validator。
好了,光耍嘴皮子,不干活那是码农中的流氓,也是时候真刀真枪的操练起来了。
2.
咋用?
第一步:引入依赖包。不用太纠结,用就完了。
- <dependencies>
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-validator</artifactId>
- <version>6.0.17.Final</version>
- </dependency>
- <dependency>
- <groupId>org.glassfish</groupId>
- <artifactId>javax.el</artifactId>
- <version>3.0.1-b09</version>
- </dependency>
- <dependency>
- <groupId>org.hibernate</groupId>
- <artifactId>hibernate-validator-cdi</artifactId>
- <version>6.0.17.Final</version>
- </dependency>
- </dependencies>
第二步:定义登录请求对象,添加校验规则。主要关注注解即可,So easy!!
- import javax.validation.constraints.*;
- public class UserLoginRequest {
- @NotNull(message = "[接口版本号]不能为空!")
- @Pattern(regexp = "^(\\d+)(\\.\\d+)?$", message = "[接口版本号]格式错误!")
- @Size(min = 0, max = 4, message = "[接口版本号]长度错误,最大长度为[{max}]!")
- private String versionNo;
- @NotNull(message = "[手机号]不能为空!")
- @Size(min = 0, max = 11, message = "[用户手机号码]长度错误,最大长度为[{max}]!")
- private String mobile;
- @NotNull(message = "[订单号]不能为空!")
- @Size(min = 0, max = 32, message = "[订单号]长度错误,最大长度为[{max}]!")
- private String orderId;
- @NotNull(message = "[验证码]不能为空!")
- @Size(min = 0, max = 6, message = "[验证码]长度错误,最大长度为[{max}]!")
- private String smsCode;
- //TODO 提供setter/getter ... ...
- }
第三步:按照常规,应该写个测试类,跑跑看,这次咱们就一步到位,直接封装工具类。你可以直接拿到真实项目去实践,用良心保证绝对好用。
- import javax.validation.*;
- import java.util.*;
- public class ValidateUtil {
- public static <T> void validate(T t) {
- if (null == t) {
- throw new ValidateException("E0001", "参数为空");
- }
- ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
- Validator validator = factory.getValidator();
- Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
- List<String> errorList = new ArrayList<String>();
- for (ConstraintViolation<T> constraintViolation : constraintViolations) {
- errorList.add(constraintViolation.getMessage());
- }
- if (!errorList.isEmpty()) {
- throw new ValidateException("E9999", errorList.toString());
- }
- }
- }
第四步:自定义异常,这个根据实际情况而定,非必须。
- public class ValidateException extends RuntimeException {
- private String code;
- private String msg;
- /**
- * @param code 异常码
- * @param msg 异常消息
- */
- public ValidateException(String code, String msg) {
- super(msg);
- this.setCode(code);
- this.setMsg(msg);
- }
- //TODO 提供setter/getter ... ...
- }
第五步:跑起来,看一看是否经得起考验。
- public class App {
- public static void main(String[] args) {
- UserLoginRequest request = new UserLoginRequest();
- request.setVersionNo("abc"); //版本号输入错误
- request.setMobile("138013800000"); //手机号长度有误
- try {
- ValidateUtil.validate(request);
- } catch (ValidateException e) {
- //TODO 在实际业务中直接获取异常码、异常信息进行包装返回给前端即可
- System.out.println(String.format("code: %s, msg:%s",e.getCode(),e.getMsg()));
- }
- }
- }
第六步:结果分析,看到结果,果真达到预期:手机号码长度错误、接口版本号格式有误、其它参数值传入为空。
3.
技术无止境,剩下的还需要各位自行去耕耘,不过掌握上面这些,已经够你在项目中喝一壶的啦。
好了,通过这次正规军式的分享 + 上次野战军式的分享,相信你今后肯定能玩转 API 参数校验,也就可以专心去写业务代码啦,如果你之前尚未接触过这些,不妨拿去实践,大概率会大幅提升你的研发效率,腾出更多时间喝咖啡,幸福感陡然上升。
API参数如何验证?别纠结,拿去用就是的更多相关文章
- .Net Core Web Api使用模型验证验证参数合法性
在接口开发过程中免不了要去验证参数的合法性,模型验证就是帮助我们去验证参数的合法性,我们可以在需要验证的model属性上加上Data Annotations特性后就会自动帮我们在action前去验证输 ...
- 徒手生撸一个验证框架,API 参数校验不再怕!
你们之中大概率早已练就了代码的拷贝.粘贴,无敌的码农神功,其实做久了业务功能开发,练就这两个无敌神功,那是迟早的事儿.今天先抛一个小问题,来打通你的任督二脉,就是很好奇的问一下:业务功能开发中,输入参 ...
- ABP(现代ASP.NET样板开发框架)系列之17、ABP应用层——参数有效性验证
点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之17.ABP应用层——参数有效性验证 ABP是“ASP.NET Boilerplate Project (ASP. ...
- 细说 Web API参数绑定和模型绑定
今天跟大家分享下在Asp.NET Web API中Controller是如何解析从客户端传递过来的数据,然后赋值给Controller的参数的,也就是参数绑定和模型绑定. Web API参数绑定就是简 ...
- ABP应用层——参数有效性验证
ABP应用层——参数有效性验证 基于DDD的现代ASP.NET开发框架--ABP系列之17.ABP应用层——参数有效性验证 ABP是“ASP.NET Boilerplate Project (ASP. ...
- Parameter Binding in ASP.NET Web API(参数绑定)
Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...
- SpringBoot2.0针对请求参数@RequestBody验证统一拦截
title: "SpringBoot2.0针对请求参数@RequestBody验证的统一拦截"categories: SpringBoot2.0 Shirotags: Spring ...
- golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息
golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放 ...
- .net core Web API参数绑定规则
参数推理绑定 先从一个问题说起,微信小程序按照WebAPI定义的参数传递,Get请求服务器端可以正常接收到参数,但是Post请求取不到. Web API代码(.netcore 3.1)如下: [Htt ...
随机推荐
- safari坑之 video
博客地址: https://www.seyana.life/post/19 本来是打算给博客左上角的gif做个优化, 把gif换成webm,以video的形式自动播放,能从180k降到50k, 现在浏 ...
- Flutter 拖拽控件Draggable看这一篇就够了
注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 Draggable系列组件可以让我们拖动组件. Dragg ...
- git版本回退问题记录
因为之前有个前端改了文件目录进行合并时候丢失掉些许代码,然后我在以前分支进行了代码层级的整理,项目如果想要启动还需还原回以前的版本,我进行了三次文件夹层级提交,所以我需要进行三次的版本回退. git命 ...
- Git使用ssh公钥
Git使用ssh公钥 一. 何谓公钥 1.很多服务器都是需要认证的,ssh认证是其中的一种.在客户端生成公钥,把生成的公钥添加到服务器,你以后连接服务器就不用每次都输入用户名和密码了. 2.很多gi ...
- LeetCode专题——详解搜索算法中的搜索策略和剪枝
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第20篇文章,今天讨论的是数字组合问题. 描述 给定一个int类型的候选集,和一个int类型的target,要求返 ...
- Win10下如何安装和搭建appium自动化测试环境
转:https://www.cnblogs.com/huainanhai/p/11577419.html 安装Android SDK https://www.jianshu.com/p/2acdc1d ...
- asp:textbox 的 TextMode:password
1. 用于输入或显示密码的文本框,设置属性TextMode为Password <asp:TextBox ID="txt_Password" runat="serv ...
- Natas5 Writeup(Cookie伪造)
Natas5: 提示不允许进入,没有登录,burp抓包,查看cookie信息后发现存在loggedin项,且值为0,猜测该值代表是否登录,将其修改为1,得到flag. flag:aGoY4q2Dc6M ...
- 【Springboot】用Prometheus+Grafana监控Springboot应用
1 简介 项目越做越发觉得,任何一个系统上线,运维监控都太重要了.关于Springboot微服务的监控,之前写过[Springboot]用Springboot Admin监控你的微服务应用,这个方案可 ...
- Python基础 | 关于“循环”那些事
目录 for 循环 list range enumerate zip while 循环 while相当于if时 while充当for和if的混合体 泛循环 列表解析 map 迭代器 生成器 循环的跳出 ...