javascript
jsr303自定义验证_JSR 310新日期/时间API的自定义JSR 303 Bean验证约束
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验证约束的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 泡泡糖怎么吹 怎样吹泡泡糖
- 下一篇: 使用Testcontainers和Pos