基于Java Bean Validation对Request参数进行校验的设计思路

简介:

 数据校验是任何一个应用程序都会用到的功能,无论是显示层还是持久层. 通常,相同的校验逻辑会分散在各个层中, 这样,不仅浪费了时间还会导致重复代码的发生. 为了避免重复, 开发人员经常会把这些校验逻辑直接写在领域模型里面, 但是这样又把领域模型代码和校验代码混杂在了一起, 而这些校验逻辑更应该是描述领域模型的元数据.

 wKiom1V6fwCQfN-RAACyvw5fsaI471.jpg

     JSR 303 - Bean Validation (version 1.1)- 为实体验证定义了元数据模型和API. 默认的元数据模型是通过Annotations来描述的,但是也可以使用XML来重载或者扩展. Bean Validation API 并不局限于应用程序的某一层或者哪种编程模型, 例如,如图所示, Bean Validation 可以被用在任何一层, 或者是像类似Swing的富客户端程序中.


   wKioL1V6gLTAlJ-eAADWJPTcUH0246.jpg



    从上述描述和图示可以看到数据检验伴随整个系统的各个层面,专业的说数据校验属于面向方面的范畴。

    本文关注在Web开发中Http请求参数的数据校验。

   1.引出问题 

   下面是12306车次查询API:

   wKiom1V6ge2ijEdPAAGR0401SFQ806.jpg

    注:上面的请求是php的,暂且我们转为Servlet。

    请求有五个参数,在做查询的时候通常会做数据校验处理,这里涵盖了数据格式,数据有效性。比如date就要校验数据格式,tt就要校验数据有效性(通常车次类型是固定数目的类型编码,较少改动)。

  

    在Web开发中这样的请求参数校验是很多的,通常在前端对参数校验之后,后端仍然是需要再次严格的校验。那么对于这样的非业务代码就可以抽取出来,单独做数据校验,如果校验通过,则继续下一步业务处理,不通过则做相应的处理。

   

  2. 如何解决

     上面提到做单独的数据校验,这里的数据来自Http Request Parameter,校验则是我们要做的工作。校验有分为编写参数的校验规则和校验逻辑处理。

      如何编写校验规则,如何进行校验逻辑处理? 这里引入Java Bean Validation规范,其定义了元数据模型(可以认为是校验规则)和API(校验处理的接口)。 Java Bean Validation规范的实现有Hibernate-Validator,Oval等等,可以借助Bean Validation的实现解决方案来做这部分工作。剩下的就是Http Request Parameter到Bean的映射,这里我称该Bean为ParameterBean(参数实体)。

    整个解决方案的思路如下图:

   wKioL1V6khiCh4teAAEQhWc3-FE048.jpg

    


     流程说明:首先将请求参数进行包装,包装成参数Bean;然后通过Validation API的实现进行Bean校验得到校验结果;最后更加校验结果来进行下一步具体业务处理。

    实际开发中要首先定义好请求参数对应的参数Bean,对该Bean进行校验规则的编写,可以采用XML配置或者Annotation的方式。


 3. 具体实现

    具体实现则是熟悉和应用Bean Validation规范以及其对应的实现者,通过自定义扩展更多的校验规则。抽取出业务里关于请求参数的逻辑,交由Bean Validation模块单独处理。


  下图是一个简单的抽取请求参数校验的实现类结构图:

 wKioL1V6lBCBuFzOAAO4uekxWYY702.jpg


   

    在实际开发中可以更加需要进一步扩展,而正真依赖请求参数校验模块的接口则只有ParameterValidator这个接口,从而分离了请求参数校验,使其独立与业务逻辑。  

  

    至此关于“基于Java Bean Validation对Request参数进行校验的设计思路“就告一段落,更多想法有待探索和实践。



本文转自 secondriver 51CTO博客,原文链接:http://blog.51cto.com/aiilive/1661317,如需转载请自行联系原作者

相关文章
|
2月前
|
存储 Java
Java-参数传值
Java-参数传值
25 4
|
2月前
|
Java
【Java每日一题】— —第二十二题:类名作参数进行方法调用的传递问题。
【Java每日一题】— —第二十二题:类名作参数进行方法调用的传递问题。
26 1
|
2月前
|
存储 Java fastjson
Java泛型-4(类型擦除后如何获取泛型参数)
Java泛型-4(类型擦除后如何获取泛型参数)
33 1
|
2月前
|
缓存 算法 安全
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(二)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
18 0
|
2月前
|
缓存 Java C#
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍(一)
【JVM故障问题排查心得】「Java技术体系方向」Java虚拟机内存优化之虚拟机参数调优原理介绍
84 0
|
2月前
|
Java 应用服务中间件 Spring
SpringBoot出现 java.lang.IllegalArgumentException: Request header is too large 解决方法
SpringBoot出现 java.lang.IllegalArgumentException: Request header is too large 解决方法
49 0
|
1天前
|
消息中间件 安全 Java
在Spring Bean中,如何通过Java配置类定义Bean?
【4月更文挑战第30天】在Spring Bean中,如何通过Java配置类定义Bean?
8 1
|
7天前
|
存储 Java 测试技术
一文搞清楚Java中的方法、常量、变量、参数
在JVM的运转中,承载的是数据,而数据的一种变现形式就是“量”,量分为:**常量与变量**,我们在数学和物理学中已经接触过变量的概念了,在Java中的变量就是在程序运行过程中可以改变其值的量。
15 0
|
9天前
|
Java 测试技术 Spring
|
19天前
|
存储 监控 安全
泛型魔法:解码Java中的类型参数
泛型魔法:解码Java中的类型参数
35 0
泛型魔法:解码Java中的类型参数