validator

来自:掘金,作者:金城学子

链接:https://juejin.im/post/5d3fbeb46fb9a06b317b3c48

为什么要用validator实战演练1. @Validated 声明要检查的参数2. 对参数的字段进行注解标注3. 在全局校验中增加校验异常4. 测试自定义参数注解1. 比如我们来个 自定义身份证校验 注解2. 然后自定义Validator3. 使用自定义的注解4.使用groups的校验5.restful风格用法总结

遇到大量参数进行校验,在业务中不断返回异常时抛出异常或返回校验信息,是非常痛苦的。代码相当长,充满了if-else验证码。今天我们将学习spring中jax.validation的注释参数验证。

为什么要用validator

1.1.jax.validation的一系列注释可以帮助我们完成参数验证,避免繁琐的串行验证。

否则,我们的代码将如下所示:

validator

老板看到这个,肯定说9102之后还写,然后就被辞退了。…..

什么是jax.validation

JSR303是一套JaBeans参数验证的标准,定义了很多常用的验证注释。我们可以直接将这些注释添加到我们的JaBeans的属性中(在注释编程时代),这样我们就可以在需要的时候进行检查。它已经包含在SpringBoot的starter-web中,我们可以参考其他项目中的依赖项并自己调整版本:

1.笔记

这里只列出了hibernate validator提供的大多数验证约束注释。关于其他验证约束注释和自定义验证约束注释定义,请参考Hibernate Validator的官方文档。

实战演练

话不多说,就走实用路线,也用了SpringBoot的快速框架。详细代码见github.com/leaJone/myb…

1.@Validated声明要检查的参数。

这里我们在控制器级别做了一个注释声明。

2.注释参数字段。

进口龙目岛。数据;导入org . hibernate . validator . constraints . length;导入jax . validation . constraints . *;导入Ja . io . serializable;导入Ja . util . date;/* * * @ author lijing * @ class name:userdo * @ description:user tranission object * @ date 2019/7/30 13:55 */@ data public class userdo实现serializable { private static final long serialversionuid = 1l;/* * *用户ID */@ not null(message = & # 34;用户id不能是空& # 34;)私有长userId/* *用户名*/@ not blank(message = & # 34;用户名不能是空& # 34;)@Length(max = 20,message = & # 34用户名不能超过20个字符& # 34;)@ Pattern(regexp = & # 34;^[\u4e00-\u9fa5a-za-z0-9\*]*#34;,message = & # 34用户昵称限制:最多20个字符,包括字符、字母和数字& # 34;)私有字符串用户名;/* *手机号码*/@ not blank(message = & # 34;手机号码不能是空& # 34;)@ Pattern(regexp = & # 34;^[1][3,4,5,6,7,8,9][0-9]{9}#34;,message = & # 34手机号码格式错误& # 34;)私串移动;/* *性别*/私串性别;/* * email */@ not blank(message = & # 34;联系人电子邮件地址不能是空& # 34;)@ Email(message = & # 34;不正确的邮箱格式& # 34;)私串邮箱;/* * password */私有字符串密码;/* * *创建时间*/@未来(message = & # 34时间必须在未来& # 34;)私人日期createTime}3.将检查异常添加到全局检查中。

在springBoot中检查绑定参数时,methodargumentnotvalidateexception是一个异常,需要在springBoot中处理,其他异常需要用ConstraintViolationException处理。

为了优雅一点,我们将参数异常,业务异常,统一做了一个全局异常,将控制层的异常包装到我们自定义的异常中为了优雅一点,我们还做了一个统一的结构体,将请求的code,和msg,data一起统一封装到结构体中,增加了代码的复用性

导入com . boot . lea . mybot . dto . RSP dto;导入org . slf4j . logger;导入org . SLF 4j . logger factory;导入org . spring framework . Dao . duplicate keyexception;import org . spring framework . web . bind . methodargumentnotvaliexception;导入org . spring framework . web . bind . annotation . exception handler;导入org . spring framework . web . bind . annotation . restcontrolleradvice;导入org . spring framework . web . servlet . nohandlerfoundexception;导入jax . validation . constraintviolationexception;import jax . validation . validation exception;/* * * @ author lijing * @ class name:GlobalExceptionHandler * @ description:全局异常处理程序* @ date 2019/7/30 13:57 */@ restcontrolleradvice public类GlobalExceptionHandler { private Logger Logger = Logger factory . get Logger(getClass());private static int DUPLICATE _ KEY _ CODE = 1001;private static int PARAM _ FAIL _ CODE = 1002;private static int VALIDATION _ CODE = 1003;/* * *处理自定义异常*/@ exception handler(biz exception . class)public rspdtto handler exception(biz exception e){ logger . error(e . getmessage(),e);返回新的RspDTO(e.getCode()、e . getmessage());}/* * *方法参数验证*/@ exception handler(methodagumentnotvalid exception。class)public rspd来处理methodgargumentnotvalid exception(methodgargumentnotvalid exception e){ logger。error (e.getmessage(),e);返回新的RspDTO(PARAM_FAIL_CODE,e.getBindingResult()。getFieldError()。getDefaultMessage());}/* * * validation exception */@ exception handler(validation exception . class)public RspDTO handlevalidation exception(validation exception e){ logger . error(e . getmessage(),e);返回新的RspDTO(VALIDATION_CODE,e.getCause()。getMessage());}/* * * ConstraintViolationException */@ exception handler(ConstraintViolationException . class)public RspDTO handleConstraintViolationException(ConstraintViolationException e){ logger . error(e . getmessage(),e);返回新的RspDTO(PARAM_FAIL_CODE,e . getmessage());} @ Exception handler(nohandlerfoundexception . class)public RspDTO handlerNoFoundException(Exception e){ logger . error(e . getmessage(),e);返回新的RspDTO(404,& # 34;该路径不存在。请检查路径是否正确& # 34;);} @ exception handler(DuplicateKeyException . class)public RspDTO handleDuplicateKeyException(DuplicateKeyException e){ logger . error(e . getmessage(),e);返回新的RspDTO(DUPLICATE_KEY_CODE,& # 34;数据重复,请检查并提交& # 34;);} @ Exception handler(Exception . class)public RspDTO handle Exception(Exception e){ logger . error(e . getmessage(),e);返回新的RspDTO(500,& # 34;系统忙,请稍后再试& # 34;);}}4.试验

如下:参数校验时确实返回了异常信息和对应的代码,方便我们不再处理参数校验。

在ValidationMessages.properties中,是经过验证的消息,它有一个书面的默认消息,并支持i18n。可以看源代码欣赏。

自定义参数注注:

1.举个例子,我们来做一个自定义的ID验证备注。

该注释作用于Field字段,它在运行时生效,并触发身份验证类IdentityCardNumber。

message 定制化的提示信息,主要是从ValidationMessages.properties里提取,也可以依据实际情况进行定制groups 这里主要进行将validator进行分类,不同的类group中会执行不同的validator操作payload 主要是针对bean的,使用不多。

2.然后定制验证器。

这是用于验证的真实逻辑代码:

IdCardValidatorUtils在项目源代码中,可以自己查看。

3.使用自定义注释

4、使用groups的校验

有的宝宝说,同一个对象要重复使用。比如UserDTO更新时需要检查userId,保存时不需要检查userId。在这两种情况下,它都需要检查用户名,所以使用组:

首先,定义分组接口,创建和更新分组。

然后在@Validated声明需要检查的检查组。

在DTO字段上定义分组类型groups = {}。

@ Datapublic class UserDTO实现Serializable { private static final long serialVersionUID = 1L;/* * *用户ID */@ not null(message = & # 34;用户id不能是空& # 34;,groups = update . class)private Long userId;/* * *用户名*/@ not blank(message = & # 34;用户名不能是空& # 34;)@Length(max = 20,message = & # 34用户名不能超过20个字符& # 34;,groups = {Create.class,update . class })@ Pattern(regexp = & # 34;^[\u4e00-\u9fa5a-za-z0-9\*]*#34;,message = & # 34用户昵称限制:最多20个字符,包括字符、字母和数字& # 34;)私有字符串用户名;/* * *手机号码*/@ not blank(message = & # 34;手机号码不能是空& # 34;)@ Pattern(regexp = & # 34;^[1][3,4,5,6,7,8,9][0-9]{9}#34;,message = & # 34手机号码格式错误& # 34;,groups = {Create.class,Update.class})私有字符串移动;/* * *性别*/私串性别;/* * * email */@ not blank(message = & # 34;联系人电子邮件地址不能是空& # 34;)@ Email(message = & # 34;不正确的邮箱格式& # 34;)私串邮箱;/* * * password */私有字符串密码;/* * *创建时间*/@未来(message = & # 34时间必须在未来& # 34;,groups = {Create.class})私人日期createTime}注意:声明分组时,添加扩展名jax。尽可能多地使用validation.groups.default。否则,当您声明@Validated(Update.class)时,检查group @ Email(message = & # 34;不正确的邮箱格式& # 34;),不会检查,因为默认检查组是groups = {Default.class}。

5、restful风格用法

当检查多个参数时,或者以@RequestParam的形式,需要在控制器上添加@Validated。

摘要

用起来很简单,soEasy,专注于统一的结构返回和统一的参数验证,是减少我们代码中大量try catch的法宝。我觉得在项目中处理好异常,管理好日志,是一个很好的升华。文章简单,只是一个新手的进阶笔记。….

这只是个人观点,技术菜。欢迎给我提建议…我是小白,技术不断更新迭代。我只能跟上大白的步伐……

顺便说一下,我目前是一名Ja开发人员。如果你现在正在学习Ja,了解Ja,渴望成为一名合格的Ja开发工程师,并且在学习Ja的过程中缺乏基础的入门视频教程,可以关注一下,私信我:01。去拿。我这里有最新的全套Ja基础视频教程。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

发表回复

登录后才能评论