jsr303自定义验证

借助JSR 310,Java 8终于为我们带来了不错的日期和时间API。 对于仍在使用Java 7的那些人(就像我目前在我的当前项目中一样),有很好的反向移植,请访问www.threeten.org了解更多详细信息。 但是,由于有关该主题的博客已经很多,因此我将不涉及使用新API的任何细节。 我将在本文中向您展示的是如何通过编写自己的自定义批注将Date / Time API与JSR 303 Bean验证API结合使用。

如果您同时使用bean验证和新的日期/时间API,则可能需要结合使用它们。 API和Hibernate Validator之类的实现仅提供了少数约束,例如NotEmpty@Pattern 。 但是,到目前为止,JSR 310还没有现成的约束。幸运的是,创建自己的约束非常容易。 作为示例,我将演示如何编写自己的@Past批注以验证java.time.LocalDate字段。

为了进行测试,我们将从一个非常简单的类开始,该类包含一个日期和一个dateTime。 这些字段应该代表过去的日期。 因此,它们使用@Past注释进行注释:

ClassWithPastDates

package it.jdev.example.jsr310.validator;import java.time.LocalDate;
import java.time.LocalDateTime;public class ClassWithPastDates {@Pastprivate LocalDate date;@Pastprivate LocalDateTime dateTime;public LocalDate getDate() {return date;}public void setDate(LocalDate date) {this.date = date;}public LocalDateTime getDateTime() {return dateTime;}public void setDateTime(LocalDateTime dateTime) {this.dateTime = dateTime;}}

接下来,我们将为@Past约束编写一个非常基本的单元测试,以证明我们的意图:显然,除了过去的日期之外,我们还希望null引用有效,但将来的日期无效,甚至今天也算作无效。

过去测试

package it.jdev.example.jsr310.validator;import static org.junit.Assert.assertEquals;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Set;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;import org.junit.Before;
import org.junit.Test;public class PastTest {private ClassWithPastDates classUnderTest;@Beforepublic void setup() {classUnderTest = new ClassWithPastDates();}@Testpublic void thatNullIsValid() {Set<ConstraintViolation<ClassWithPastDates>> violations = validateClass(classUnderTest);assertEquals(violations.size(), 0);}@Testpublic void thatYesterdayIsValid() throws Exception {classUnderTest.setDate(LocalDate.now().minusDays(1));classUnderTest.setDateTime(LocalDateTime.now().minusDays(1));Set<ConstraintViolation<ClassWithPastDates>> violations = validateClass(classUnderTest);assertEquals(violations.size(), 0);}@Testpublic void thatTodayIsInvalid() throws Exception {classUnderTest.setDate(LocalDate.now());classUnderTest.setDateTime(LocalDateTime.now());Set<ConstraintViolation<ClassWithPastDates>> violations = validateClass(classUnderTest);assertEquals(violations.size(), 2);}@Testpublic void thatTomorrowIsInvalid() throws Exception {classUnderTest.setDate(LocalDate.now().plusDays(1));classUnderTest.setDateTime(LocalDateTime.now().plusDays(1));Set<ConstraintViolation<ClassWithPastDates>> violations = validateClass(classUnderTest);assertEquals(violations.size(), 2);}private Set<ConstraintViolation<ClassWithPastDates>> validateClass(ClassWithPastDates myClass) {ValidatorFactory factory = Validation.buildDefaultValidatorFactory();Validator validator = factory.getValidator();Set<ConstraintViolation<ClassWithPastDates>> violations = validator.validate(myClass);return violations;}}

现在我们已经建立了基本测试,我们可以实现约束本身。 这包括两个步骤。 首先,我们必须编写注释,然后必须实现ConstraintValidator 。 从注释开始:

@interface过去

package it.jdev.example.jsr310.validator;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;import javax.validation.Constraint;
import javax.validation.Payload;@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PastValidator.class)
@Documented
public @interface Past {String message() default "it.jdev.example.jsr310.validator.Past.message";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};}

如您所见, @Past注释不是很壮观。 需要注意的主要事情是@Constraint批注,在其中我们指定将使用哪个类来执行实际的验证。

PastValidator

package it.jdev.example.jsr310.validator;import java.time.LocalDate;
import java.time.temporal.Temporal;import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;public class PastValidator implements ConstraintValidator<Past, Temporal> {@Overridepublic void initialize(Past constraintAnnotation) {}@Overridepublic boolean isValid(Temporal value, ConstraintValidatorContext context) {if (value == null) {return true;}LocalDate ld = LocalDate.from(value);if (ld.isBefore(LocalDate.now())) {return true;}return false;}}

PastValidator是所有魔术发生的地方。 通过实现ConstraintValidator接口,我们不得不提供两种方法,但对于我们的示例,仅使用isValid()方法,这是我们执行实际验证的地方。

请注意,我们使用java.time.temporal.Temporal作为类型,因为它是LocalDate和LocalDateTime类共同的接口。 这使我们可以对LocalDate和LocalDateTime字段使用相同的@Past

真正的全部就是它。 在这个非常基本的示例中,我展示了创建自己的定制JSR 303 bean验证约束是多么容易。

翻译自: https://www.javacodegeeks.com/2014/09/custom-jsr-303-bean-validation-constraints-for-the-jsr-310-new-datetime-api.html

jsr303自定义验证

jsr303自定义验证_JSR 310新日期/时间API的自定义JSR 303 Bean验证约束相关推荐

  1. JSR 310新日期/时间API的自定义JSR 303 Bean验证约束

    借助JSR 310,Java 8终于为我们带来了不错的日期和时间API. 对于仍在使用Java 7的那些人(例如我目前在我的当前项目中),有很好的反向移植,请访问www.threeten.org了解更 ...

  2. 高级JAVA开发必备技能:java8 新日期时间API((一)JSR-310:ZoneId 时区和偏移量)(JAVA 小虚竹)

    技术活,该赏 点赞再看,养成习惯 大家好,我是小虚竹.之前有粉丝私聊我,问能不能把JAVA8 新的日期时间API(JSR-310)知识点梳理出来.答案是肯定的,谁让我宠粉呢.由于内容偏多(超十万字了) ...

  3. JDK8新特性:新日期时间API全面学习

    旧版jdk对时间和日期的设计非常差 1.设计不合理 在java.util和Java.sql 包中都有日期类,java.util.Data同时包含日期和时间 而Java.sql.Date仅仅包含日期 此 ...

  4. 重学Java8新特性(四) : 日期时间API、LocalDateTime、DateTimeFormatter、开发中时间工具类(常用)

    文章目录 一.JDK8中日期时间API的介绍 1.1.LocalDate.LocalTime.LocalDateTime的使用 2.2.Instant类的使用 2.3.DateTimeFormatte ...

  5. Java日期时间API

    日期时间API 参考:https://lw900925.github.io/java/java8-newtime-api.html 旧日期时间API System java.lang.System类提 ...

  6. 6 日期字符串转日期_Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类...

    因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题,2005年,Stephen Colebourne创建了Joda-Time库,作为替代的日期和时间API.Stephen向JCP提交了 ...

  7. java 包结构 枚举类_Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类...

    因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题,2005年,Stephen Colebourne创建了Joda-Time库,作为替代的日期和时间API.Stephen向JCP提交了 ...

  8. 构造一个日期类java_Java8 新日期时间类(1)

    Java.time 包的优势 使用Java8,新的日期时间API引入覆盖旧的日期时间API的以下缺点. 非线程安全 - java.util.Date不是线程安全的,因此开发者必须在使用日期处理并发性问 ...

  9. java8 日期api_我们多么想要新的Java日期/时间API?

    java8 日期api 当前的Java.net 民意测验问题是:" 对于用Java 8实现的JSR-310(新的日期和时间API)有多重要? "在我撰写本文时,将近150位受访者投 ...

最新文章

  1. 通用试题库管理系统 jsp mysql_通用在线考试系统 JSP+Servlet+MySQL
  2. “JavaScript patterns”中译本 - 《JavaScript 模式》第三章
  3. 前端学习(2702):重读vue电商网站23之element-ui 如何按需导入
  4. php清理html table样式,Parse HTML Table - PHP [closed]
  5. linux删除了mount目录,Linux记录-分区(df/fdisk/mount/umount/fuser)
  6. glob-parent Regular expression denial ofservice
  7. 梅科尔工作室-第五次网页前端培训笔记(Javascript)
  8. 华中科技大学计算机课程学什么,华中科技大学计算机专业课程表
  9. outlook2013配置
  10. 数字逻辑设计(何建新)第二章
  11. Linux TTY基本概念之ttys*、tty*、ttyS*、console理解
  12. java-php-python-ssm蔬菜水果销售系统计算机毕业设计
  13. Linux之系统痕迹命令
  14. [渝粤教育] 西安邮电大学 成本会计学 参考 资料
  15. 手机浏览器调用手机qq客户端的js
  16. 在爱奇艺的B站大佬,有点强
  17. SAP 数据字典常用数据类型
  18. 短视频、直播和视频社交
  19. Koordinator 0.6:企业级容器调度系统解决方案,引入 CPU 精细编排、资源预留与全新的重调度框架
  20. java在spring mvc中的图片接收与发送处理

热门文章

  1. nssl1195-健美猫【???】
  2. 动态规划训练22 [Milking Time POJ - 3616 ]
  3. 38、JAVA_WEB开发基础之下载功能
  4. 十分钟快速了解 ES6 Promise
  5. 深入Synchronized和java.util.concurrent.locks.Lock的区别详解
  6. 漫画:什么是单例设计模式
  7. 不好意思,你这个加分理由不行……
  8. 班级日常分享:一天一瞬间!
  9. 《金色梦乡》金句摘抄(十)
  10. SpringCloud Netflix Eureka