今天我们主要分享项目实战中,另一种常用的参数校验框架 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.

咋用?

第一步:引入依赖包。不用太纠结,用就完了。

  1. <dependencies>
  2. <dependency>
  3. <groupId>org.hibernate</groupId>
  4. <artifactId>hibernate-validator</artifactId>
  5. <version>6.0.17.Final</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.glassfish</groupId>
  9. <artifactId>javax.el</artifactId>
  10. <version>3.0.1-b09</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.hibernate</groupId>
  14. <artifactId>hibernate-validator-cdi</artifactId>
  15. <version>6.0.17.Final</version>
  16. </dependency>
  17. </dependencies>

  

第二步:定义登录请求对象,添加校验规则。主要关注注解即可,So easy!!

  1. import javax.validation.constraints.*;
  2.  
  3. public class UserLoginRequest {
  4.  
  5. @NotNull(message = "[接口版本号]不能为空!")
  6. @Pattern(regexp = "^(\\d+)(\\.\\d+)?$", message = "[接口版本号]格式错误!")
  7. @Size(min = 0, max = 4, message = "[接口版本号]长度错误,最大长度为[{max}]!")
  8. private String versionNo;
  9.  
  10. @NotNull(message = "[手机号]不能为空!")
  11. @Size(min = 0, max = 11, message = "[用户手机号码]长度错误,最大长度为[{max}]!")
  12. private String mobile;
  13.  
  14. @NotNull(message = "[订单号]不能为空!")
  15. @Size(min = 0, max = 32, message = "[订单号]长度错误,最大长度为[{max}]!")
  16. private String orderId;
  17.  
  18. @NotNull(message = "[验证码]不能为空!")
  19. @Size(min = 0, max = 6, message = "[验证码]长度错误,最大长度为[{max}]!")
  20. private String smsCode;
  21.  
  22. //TODO 提供setter/getter ... ...
  23. }

  

第三步:按照常规,应该写个测试类,跑跑看,这次咱们就一步到位,直接封装工具类。你可以直接拿到真实项目去实践,用良心保证绝对好用。

  1. import javax.validation.*;
  2. import java.util.*;
  3.  
  4. public class ValidateUtil {
  5.  
  6. public static <T> void validate(T t) {
  7. if (null == t) {
  8. throw new ValidateException("E0001", "参数为空");
  9. }
  10.  
  11. ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
  12. Validator validator = factory.getValidator();
  13. Set<ConstraintViolation<T>> constraintViolations = validator.validate(t);
  14.  
  15. List<String> errorList = new ArrayList<String>();
  16. for (ConstraintViolation<T> constraintViolation : constraintViolations) {
  17. errorList.add(constraintViolation.getMessage());
  18. }
  19. if (!errorList.isEmpty()) {
  20. throw new ValidateException("E9999", errorList.toString());
  21. }
  22. }
  23. }

  

第四步:自定义异常,这个根据实际情况而定,非必须。

  1. public class ValidateException extends RuntimeException {
  2.  
  3. private String code;
  4. private String msg;
  5.  
  6. /**
  7. * @param code 异常码
  8. * @param msg 异常消息
  9. */
  10. public ValidateException(String code, String msg) {
  11. super(msg);
  12. this.setCode(code);
  13. this.setMsg(msg);
  14. }
  15.  
  16. //TODO 提供setter/getter ... ...
  17. }

  

第五步:跑起来,看一看是否经得起考验。

  1. public class App {
  2. public static void main(String[] args) {
  3. UserLoginRequest request = new UserLoginRequest();
  4. request.setVersionNo("abc"); //版本号输入错误
  5. request.setMobile("138013800000"); //手机号长度有误
  6. try {
  7. ValidateUtil.validate(request);
  8. } catch (ValidateException e) {
  9. //TODO 在实际业务中直接获取异常码、异常信息进行包装返回给前端即可
  10. System.out.println(String.format("code: %s, msg:%s",e.getCode(),e.getMsg()));
  11. }
  12. }
  13. }

  

第六步:结果分析,看到结果,果真达到预期:手机号码长度错误、接口版本号格式有误、其它参数值传入为空。

3.

技术无止境,剩下的还需要各位自行去耕耘,不过掌握上面这些,已经够你在项目中喝一壶的啦。

好了,通过这次正规军式的分享 + 上次野战军式的分享,相信你今后肯定能玩转 API 参数校验,也就可以专心去写业务代码啦,如果你之前尚未接触过这些,不妨拿去实践,大概率会大幅提升你的研发效率,腾出更多时间喝咖啡,幸福感陡然上升。

API参数如何验证?别纠结,拿去用就是的更多相关文章

  1. .Net Core Web Api使用模型验证验证参数合法性

    在接口开发过程中免不了要去验证参数的合法性,模型验证就是帮助我们去验证参数的合法性,我们可以在需要验证的model属性上加上Data Annotations特性后就会自动帮我们在action前去验证输 ...

  2. 徒手生撸一个验证框架,API 参数校验不再怕!

    你们之中大概率早已练就了代码的拷贝.粘贴,无敌的码农神功,其实做久了业务功能开发,练就这两个无敌神功,那是迟早的事儿.今天先抛一个小问题,来打通你的任督二脉,就是很好奇的问一下:业务功能开发中,输入参 ...

  3. ABP(现代ASP.NET样板开发框架)系列之17、ABP应用层——参数有效性验证

    点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之17.ABP应用层——参数有效性验证 ABP是“ASP.NET Boilerplate Project (ASP. ...

  4. 细说 Web API参数绑定和模型绑定

    今天跟大家分享下在Asp.NET Web API中Controller是如何解析从客户端传递过来的数据,然后赋值给Controller的参数的,也就是参数绑定和模型绑定. Web API参数绑定就是简 ...

  5. ABP应用层——参数有效性验证

    ABP应用层——参数有效性验证 基于DDD的现代ASP.NET开发框架--ABP系列之17.ABP应用层——参数有效性验证 ABP是“ASP.NET Boilerplate Project (ASP. ...

  6. Parameter Binding in ASP.NET Web API(参数绑定)

    Parameter Binding in ASP.NET Web API(参数绑定) 导航 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnbl ...

  7. SpringBoot2.0针对请求参数@RequestBody验证统一拦截

    title: "SpringBoot2.0针对请求参数@RequestBody验证的统一拦截"categories: SpringBoot2.0 Shirotags: Spring ...

  8. golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息

    golang学习笔记10 beego api 用jwt验证auth2 token 获取解码信息 Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放 ...

  9. .net core Web API参数绑定规则

    参数推理绑定 先从一个问题说起,微信小程序按照WebAPI定义的参数传递,Get请求服务器端可以正常接收到参数,但是Post请求取不到. Web API代码(.netcore 3.1)如下: [Htt ...

随机推荐

  1. safari坑之 video

    博客地址: https://www.seyana.life/post/19 本来是打算给博客左上角的gif做个优化, 把gif换成webm,以video的形式自动播放,能从180k降到50k, 现在浏 ...

  2. Flutter 拖拽控件Draggable看这一篇就够了

    注意:无特殊说明,Flutter版本及Dart版本如下: Flutter版本: 1.12.13+hotfix.5 Dart版本: 2.7.0 Draggable系列组件可以让我们拖动组件. Dragg ...

  3. git版本回退问题记录

    因为之前有个前端改了文件目录进行合并时候丢失掉些许代码,然后我在以前分支进行了代码层级的整理,项目如果想要启动还需还原回以前的版本,我进行了三次文件夹层级提交,所以我需要进行三次的版本回退. git命 ...

  4. Git使用ssh公钥

    Git使用ssh公钥 一.  何谓公钥 1.很多服务器都是需要认证的,ssh认证是其中的一种.在客户端生成公钥,把生成的公钥添加到服务器,你以后连接服务器就不用每次都输入用户名和密码了. 2.很多gi ...

  5. LeetCode专题——详解搜索算法中的搜索策略和剪枝

    本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是LeetCode专题第20篇文章,今天讨论的是数字组合问题. 描述 给定一个int类型的候选集,和一个int类型的target,要求返 ...

  6. Win10下如何安装和搭建appium自动化测试环境

    转:https://www.cnblogs.com/huainanhai/p/11577419.html 安装Android SDK https://www.jianshu.com/p/2acdc1d ...

  7. asp:textbox 的 TextMode:password

    1.  用于输入或显示密码的文本框,设置属性TextMode为Password <asp:TextBox ID="txt_Password" runat="serv ...

  8. Natas5 Writeup(Cookie伪造)

    Natas5: 提示不允许进入,没有登录,burp抓包,查看cookie信息后发现存在loggedin项,且值为0,猜测该值代表是否登录,将其修改为1,得到flag. flag:aGoY4q2Dc6M ...

  9. 【Springboot】用Prometheus+Grafana监控Springboot应用

    1 简介 项目越做越发觉得,任何一个系统上线,运维监控都太重要了.关于Springboot微服务的监控,之前写过[Springboot]用Springboot Admin监控你的微服务应用,这个方案可 ...

  10. Python基础 | 关于“循环”那些事

    目录 for 循环 list range enumerate zip while 循环 while相当于if时 while充当for和if的混合体 泛循环 列表解析 map 迭代器 生成器 循环的跳出 ...