Независимо от того, какой тип приложения мы разрабатываем, проверка кода является нашей повседневной задачей. В течение многих лет мы использовали большое разнообразие методов и структур для успешной проверки. Тем не менее, когда-нибудь у нас был стандарт для Java для проверки,
спецификация Bean Validation (JSR-303) . Вопрос в следующем: стоит ли писать (или переписывать) наши проверки с использованием стандарта Bean Validation? Есть ли практическое преимущество в использовании JSR-303?
Сначала напишем валидатор (ограничение в номенклатуре Bean Validation), а затем воспользуемся им в нашем коде, чтобы увидеть, о чем мы говорим.
Создание ограничения JSR-303
Ограничение JSR-303 — это простая аннотация Java. Например, если мы хотим проверить ISBN, мы должны создать аннотацию @ISBN, например, следующую:
package org.openxava.books.constraints;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.*;
import javax.validation.*;
import org.openxava.books.constraints.impl.*;
@Constraint(validatedBy = ISBNValidator.class) // ISBNValidator contains the validation logic
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
public @interface ISBN {
String message() default "{org.openxava.books.constraints.ISBN.message}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
Ключевой частью здесь является аннотация @Constraint. Он помечает эту аннотацию как ограничение и указывает класс валидатора ISBNValidator, то есть класс с логикой валидации:
package org.openxava.books.constraints.impl;
import javax.validation.*;
import org.openxava.books.constraints.*;
public class ISBNValidator implements ConstraintValidator<ISBN, String> {
private static org.apache.commons.validator.ISBNValidator validator =
new org.apache.commons.validator.ISBNValidator(); // Validator from commons validator
public void initialize(ISBN isbn) {
}
public boolean isValid(String value, ConstraintValidatorContext ctx) { // The validation logic
if (value == null || value.trim().equals("")) return true;
return validator.isValid(value); // We simply delegate in commons validator
}
}
Валидатор должен реализовывать ConstraintValidator, поэтому он должен иметь методы initialize () и isValid (), последний содержит логику проверки. В этом случае мы просто делегируем валидатор из проекта Apache Commons Validator.
Как мы видим, создать валидатор довольно просто. Теперь, как мы можем использовать эту проверку в нашем приложении?
Использование валидатора
Спецификация JSR-303 говорит о том, как определять валидаторы, а не о том, как они используются и как они ведут себя в нашем приложении, это зависит от используемой нами среды. JPA2 и JSF2 имеют интеграцию Bean Validation, более того, многие современные фреймворки также поддерживают JSR-303. В этом случае мы собираемся разработать мини-приложение с использованием фреймворка OpenXava, которое использует вышеуказанное приложение @ISBN. Не паникуйте, разработка приложения OpenXava коротка (и приятна), поскольку нам нужно только написать классы предметной области.
После создания нового проекта OpenXava ( выполнения цели ant ) мы добавляем в него классы Author и Book.
Author.groovy:
package org.openxava.books.model
import javax.persistence.*
import org.openxava.model.*
import org.openxava.annotations.*
@Entity
class Author extends Identifiable {
@Required
String name
}
Book.groovy:
package org.openxava.books.model
import org.openxava.model.*;
import org.openxava.annotations.*;
import org.openxava.books.constraints.*;
import javax.persistence.*;
@Entity
class Book extends Identifiable {
@Required @Column(length=60)
String title
@ManyToOne(fetch=FetchType.LAZY)
@DescriptionsList
Author author
@Column(length=10)
@ISBN
String isbn
}
Хотя мы могли писать классы на Java, мы выбрали Groovy. Да, Groovy Web-разработка без Grails возможна. Однако важным моментом здесь является аннотация @ISBN в свойстве isbn. Нам не нужно больше работать, чтобы проверка работала. Если мы перейдем по адресу http: // localhost: 8080 / Books / modules / Book и попытаемся добавить книгу с неправильным ISBN, мы получим что-то вроде этого:
Как мы видим, использование проверки подлинности @ISBN в нашем приложении является полностью декларативной задачей, поэтому ее очень просто.
Почему я должен использовать Bean Validation?
Хотя JSR-303 прост в использовании и достаточно универсален для удовлетворения наших потребностей в валидации, на самом деле он не является чем-то впечатляющим и, возможно, не намного лучше, чем наша текущая среда валидации, поэтому зачем нам его использовать? Поскольку он поддерживается JPA2, JSF2, Spring Roo, Wicket, Tapestry и т. Д., А также должен быть включен в состав Java EE 6. Поэтому он дает нам больше свободы, поскольку наш код меньше зависит от среды приложения, в которой мы работаем. используя, таким образом, легче перенести наш код (по крайней мере, часть модели) из Wicket в Tapestry или из Spring Roo в OpenXava.
Используйте стандарт Bean Validation. Буть свободен!