效果和优点


先看最后效果:

public class UserEntity {@Password  private String password;@Emailprivate String email;}

上面使用了两个自定义的注解来验证password和email,这样做的好处是:一处定义,处处使用,要修改验证规则时,也只要修改注解就可以了。而如果自定义,使用hibernate提供的标签的话:

@Pattern(regexp="...")
private String email;

如果写了很多个类之后,突然要修改验证规则regexp,此时工作量将要大得多。

实现


首先,引入hibernate validation依赖,添加:

    <!-- hibernate validator --><!-- hibernate 验证框架 --><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>5.2.2.Final</version></dependency>

hibernate validation是JSR的参考实现,所以,用它做bean验证。

自定义一个验证注解分为三步:

  • 创建注解(Create a constraint annotation)
  • 创建验证类(Implement a validator)
  • 定义默认错误信息(Define a default error message)

    第一步,创建注解:

@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = { EmailValidator.class })
public @interface Email {String message() default "这不是有效的电子邮件格式";/*** @return the regular expression to match*/String regexp() default "[a-zA-Z0-9._%+-]+@[a-zA-Z0-9]+\\.[a-zA-Z]{2,4}";Class<?>[] groups() default { };Class<? extends Payload>[] payload() default { };/*** Defines several {@link Size} annotations on the same element.** @see Size*/@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })@Retention(RUNTIME)@Documented@interface List {Email[] value();}}

通过@interface关键字来创建注解,而每一个方法就是注解的一个参数。比如上面的代码,就可以这样使用@Email(regexp="...",message="...")。其它可以不用去管,直接复制就可以了,要注意的是@Constraint(validatedBy = { EmailValidator.class }),这里指定注解的验证类,根据实际替换类名。

第二步,创建验证类:

public class EmailValidator implements ConstraintValidator<Email, String>{private String regexp;@Overridepublic void initialize(Email constraintAnnotation) {this.regexp = constraintAnnotation.regexp();}@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if(value==null){return true;}if( value.matches(regexp)){return true;}return false;}}

这里只要实现ConstraintValidator<Email, String>接口就创建了一个验证器。initialize方法得到注解的regexp值,在isValid方法中进行验证,符合正则表达式就返回true,否则返回false。

需要注意的是,当value为空,也就是验证的对象没有初始化的时候,要编写相应的验证规则,不然会报错的。在上面代码中编写的是:

if(value==null){return true;}

也即是,当验证对象为空时,返回成功。

第三步是编写默认错误信息。其实这一步在第一步已经做了,通过default,所以这步不用做。


1、hibernate validation的文档说得更详细:
Creating a simple constraint.html

2、这篇博客及其下一篇讲得也挺好:
深入理解Java:注解(Annotation)自定义注解入门

3、常见错误:
HV000030: No validator could be found for type
原因一般是没有设置@Constraint(validatedBy = { EmailValidator.class })

HV000028: Unexpected exception during isValid call
原因一般是没有设置

if(value==null){return true;}

4、JSR文献:
JSR 303: Bean Validation

自定义hibernate validation注解相关推荐

  1. Hibernate Validation校验注解详解

    在前后端传递数据的时候,往往后端需要校验传递数据的格式,比如用户名的格式,密码是否为空.我们可以在service层编写代码判断,但是当我们在多处需要校验传递来的数据的时候,就会出现大量重复的代码,一旦 ...

  2. 自定义Hibernate Validator规则注解

    自定义规则注解 除了使用已定义的校验规则外,我们也可以根据自定的业务自定义校验规则,接下来我们介绍一下如何自定义 Hibernate Validator校验规则. 创建自定义规则无参数注解介绍 声明自 ...

  3. java注解返回不同消息,Spring MVC Controller中的一个读入和返回都是JSON的方法如何获取javax.validation注解的异常信息...

    Spring MVC Controller中的一个读入和返回都是JSON的方法怎么获取javax.validation注解的错误信息? 本帖最后由 LonelyCoder2012 于 2014-03- ...

  4. Spring Boot 后台验证 Hibernate Validation

    后台验证详解 开发项目过程中,后台在很多地方需要进行校验操作,比如:前台表单提交,调用系统接口,数据传输等.而现在多数项目都采用MVC分层式设计,每层都需要进行相应地校验. 针对这个问题, JCP 出 ...

  5. 模拟hibernate的注解来创建数据表,内置注解

    目录 导读 注解释义 注解定义 内置三大注解 override注解 Deprecated注解 SuppressWarnings注解 元注解 SOURCE和RUNTIME的区别 SOURCE RUNTI ...

  6. hibernate annotation注解方式来处理映射关系

    2019独角兽企业重金招聘Python工程师标准>>> 在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟 ...

  7. return error怎么定义_这一次搞懂Spring自定义标签以及注解解析原理

    自定义标签解析原理 在上一篇分析默认标签解析时看到过这个类DefaultBeanDefinitionDocumentReader的方法parseBeanDefinitions:拉勾IT课小编为大家分解 ...

  8. java 自定义json解析注解 复杂json解析 工具类

    java 自定义json解析注解 复杂json解析 工具类 目录 java 自定义json解析注解 复杂json解析 工具类 1.背景 2.需求-各式各样的json 一.一星难度json[json对象 ...

  9. hibernate @Where注解

     @Where注解使用. 这是一个hibernate的注解,主要作用是在HQL转成SQL时自动添加where条件. @Where注解一般可以放在Class的头上,也可以放在get方法的头上. @W ...

最新文章

  1. 通过特征类型超参数控制权重类型
  2. 《论语》原文及其全文翻译 学而篇16
  3. 亲手完成4大企业实战项目,挑战Python全栈高薪岗位!
  4. ACL2020 | 线上搜索结果大幅提升!亚马逊提出对抗式query-doc相关性模型
  5. 吴恩达机器学习 逻辑回归 作业3(手写数字分类) Python实现 代码详细解释
  6. 约束最优化方法之最优性条件
  7. c语言无法定位程序输入点 于动态链接库,无法定位程序输入点于动态链接库?解决方法步骤...
  8. 苹果手机怎么清理听筒灰尘_iPhone手机听筒声音小、有杂音?成都苹果维修点教你轻松解决...
  9. 用c语言编写人机结合的加法,综合集成研讨厅中人机结合的研讨流程研究.pdf
  10. win10计算机控制面板在哪里,教您win10控制面板在哪
  11. 基于php的外卖订餐系统开题报告_校园网上订餐系统的设计与实现(PHP,MySQL)
  12. commons-poll、jedis-2.7.0、jedis.properties资源分享
  13. CSDN明星博主Leo新作——《程序员羊皮卷》即将隆重上市
  14. SCI入门级知识(带你了解SCI期刊)
  15. 简历石沉大海?程序员简历到底该怎么写?
  16. scrapy.loader.processors.TakeFirst is deprecated, instantiate itemloaders.processors.TakeFirst inste
  17. 【计算机毕业设计】KTV点歌系统
  18. 基于三维GIS平台的智慧园区建设方案
  19. 2022计算机保研碎碎念:从零offer到上岸(一个很佛系的fw的故事:上科大cs/浙软/软件所/南大cs/天大cs)
  20. 互联网之父与李开复记者见面会问答实录

热门文章

  1. mybatis 一对一 一对多 级联查询
  2. 6、jeecg 笔记之 自定义excel 模板导出(一)
  3. cesium label 显示隐藏到地底下
  4. greenplum gpfdist应用
  5. aix查看lv_Aix 添加VG,LV并挂载使用
  6. (五)ElasticSearch 6.1.1数据类型
  7. 1058. A+B in Hogwarts (20)
  8. datatables 的导出button自定义
  9. ExecuteScalar
  10. hdu 1874(Dijkstra + Floyd)