Validación de beans
La API de validación de beans se presenta con la plataforma Java™ Enterprise Edition 6 como un mecanismo estándar para validar JavaBeans en todas las capas de una aplicación, incluida la presentación, la empresa y el acceso a datos.
Antes de la especificación de la validación de beans, se han validado los JavaBeans en cada capa. Para evitar la reimplementación de validaciones en cada capa, los desarrolladores empaquetaban las validaciones directamente en sus clases o copiaban el código de validación, que a menudo resultaba confuso. Tener una implementación común para todas las capas de la aplicación simplifica el trabajo a los desarrolladores y ahorra tiempo.
La especificación de validación de beans define un modelo de metadatos y una API que se utilizan para validar los JavaBeans para la integridad de datos. El origen de los metadatos son las anotaciones de restricción definidas que se pueden alterar temporalmente y ampliar utilizando descriptores de validación XML. El conjunto de API proporciona un modelo de programación fácil de utilizar que permite a cualquier capa de aplicación utilizar el mismo conjunto de restricciones de validación. Las restricciones de validación se utilizan para comprobar el valor de los campos, métodos y tipos anotada para garantizar que se ajustan a la restricción definida.
Las restricciones pueden ser incorporadas o definidas por el usuario. Hay varias anotaciones incorporadas disponibles en el paquete de javax.validation.constraints. Se utilizan para definir las definiciones de restricciones regulares y para crear las restricciones. Consulte la información sobre las restricciones incorporadas de validación de bean para obtener una lista de restricciones incorporadas. Para obtener más detalles sobre el modelo de metadatos de validación de beans y las API, consulte el documento de la especificación de validación de beans JSR 349.
El ejemplo siguiente es una clase simple EJB (Enterprise JavaBeans) que se decora con anotaciones de restricciones incorporadas.
public class Home {
@Size(Max=20)
String builder;
@NotNull @Size(Max=20)
String address;
public String getAddress() {
return address;
}
public String getBuilder() {
return address;
}
public String setAddress(String newAddress) {
return address = newAddress;
}
public String setBuilder(String newBuilder) {
return builder = newBuilder;
}
}
Las anotaciones @Size en builder y address especifican que el valor de serie asignado no debe ser mayor de 20 caracteres. La anotación @NotNull en address indica que no puede ser nulo. Cuando se valida el objeto Home, los valores de builder y address se pasan a la clase de validador definida para la anotación @Size. El valor de address también se pasa a la clase de validador @NotNull. Las clases de validador manejan la comprobación de los valores para las restricciones adecuadas y, si cualquier restricción no pasa la validación, se crea un objeto ConstraintViolation, y se devuelve en un conjunto al interlocutor que valida el objeto Home.
API de validación
El paquete javax.validation contiene las API de validación de beans que describen cómo validar mediante programación JavaBeans.
ConstraintViolation es la clase que describe una anomalía de restricción única. Se devuelve un conjunto de clases ConstraintViolation para un objeto de validación. La violación de restricción también expone un mensaje legible que describe la violación.
Se emiten excepciones ValidationException si se produce un error durante la validación.
La interfaz del validador es la API de validación principal y una instancia del validador es el objeto que puede validar los valores de los campos, métodos y tipos de objetosJava. La API de rutina de carga es el mecanismo utilizado para obtener acceso a una ValidatorFactory que se utiliza para crear una instancia de Validator. Para las aplicaciones desplegadas en el producto, la rutina de carga se realiza automáticamente. Las aplicaciones pueden obtener el Validator o el ValidatorFactory de dos maneras. Una es la inyección, por ejemplo, mediante la anotación @Resource, y la otra es la búsqueda java:.
@Resource ValidatorFactory _validatorFactory;
@Resource Validator _validator;
ValidatorFactory validatorFactory = (ValidatorFactory)context.lookup("java:comp/ValidatorFactory");
Validator validator = (Validator)context.lookup("java:comp/Validator");
API de solicitud de metadatos de restricción
Los metadatos de las API dan soporte a los proveedores de herramientas, proporcionan integración con otras infraestructuras, bibliotecas y tecnologías de Java Platform, Enterprise Edition. Se accede al repositorio de metadatos de restricciones de objetos a través de la instancia de Validator de una clase determinada.
Descriptores de despliegue XML
Además de declarar restricciones en las anotaciones, existe soporte para utilizar XML para declarar las restricciones.
La descripción XML de validación se compone de dos tipos de archivos xml. El archivo META-INF/validation.xml describe la configuración de validación de beans para el módulo. El otro tipo de archivo XML describe las declaraciones de restricciones y coincide estrechamente con el método de declaración de anotaciones. De forma predeterminada, todas las declaraciones de restricción expresadas a través de las anotaciones se ignoran para las clases descritas en XML. Es posible forzar la validación para utilizar tanto las anotaciones como las declaraciones de restricción XML utilizando el valor ignore-annotation="false" en el bean. El producto garantiza que los módulos de la aplicación desplegados que contienen un archivo validation.xml y las restricciones definidas en archivos XML se aíslen de otros archivos validation.xml y de restricciones de módulos mediante la creación de instancias de validador específicas del módulo que contiene los descriptores XML.
Conceptos avanzados de validación de beans
La API de validación de beans proporciona un conjunto de restricciones incorporados y una interfaz que permite declarar restricciones personalizadas. Esto se realiza mediante la creación de anotaciones de restricción y declarando una anotación en un tipo, campo o propiedad de bean. La composición de restricciones también se realiza declarando la restricción en otra definición de restricción.
En el ejemplo siguiente se muestra la creación de una restricción CommentChecker definida para asegurarse de que un campo de serie de comentario no es nulo. El texto del comentario se incluye entre corchetes, por ejemplo [texto].
package com.my.company;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import javax.validation.Constraint;
import javax.validation.Payload;
@Documented
@Constraint(validatedBy = CommentValidator.class)
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
public @interface CommentChecker {
String message() default "El comentario no es válido.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
…}
package com.my.company;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class CommentValidator implements ConstraintValidator<CommentChecker, String> {
public void initialize(CommentChecker arg0) {
}
public boolean isValid(String comment, ConstraintValidatorContext context) {
if (comment == null) {
// No se permite un comentario nulo, la restricción falla.
return false;
}
if (!comment.contains("[") && !comment.contains("]")) {
// No se encuentran corchetes de apertura o cierre, la restricción falla
return false;
}
// Ignorar espacios iniciales y finales
String trimmedComment = comment.trim();
return // validate '[' prefix condition
trimmedComment.charAt(0) == '[' &&
// validate ']' suffix condition
trimmedComment.charAt(trimmedComment.length()!-1) == ']';
}
}
Después de que se haya definido @CommentChecker, se puede utilizar para garantizar que el campo de serie de comentario sea un comentario válido basándose en la implementación de CommentValidator isValid(). En el siguiente ejemplo se muestra el uso de la restricción @CommentChecker. Cuando se valida el bean myChecker, la clase CommentValidator valida la serie de comentario para garantizar que se cumplan las restricciones definidas. package com.my.company;
public myChecker {
@CommentChecker
String comment = null;
...
}
El producto proporciona un proveedor de validación de bean por defecto, aunque es recomendable que utilice otro proveedor en su aplicación. Puede elegir un proveedor alternativo de forma programática llamando al método javax.validation.Validation.byProvider() para crear una fábrica de validación. Como alternativa, puede elegir un proveedor alternativo de forma declarativa especificando el elemento <default-provider/> en el archivo validation.xml. Si desea asegurarse de que las clases de proveedor alternativo no estén en conflicto con el proveedor predeterminado, establezca el orden de cargador de clases de aplicación o servidor en el valor Clases cargadas con cargador de clases local primero (padre último). Consulte la documentación de carga de clases para obtener información adicional sobre cómo establecer este valor.
La especificación de validación de beans indica que si se encuentra más de un archivo validation.xml en la vía de acceso de clases, se produce una ValidationException. Sin embargo, WebSphere Application Server da soporte a un entorno en el que varios equipos desarrollan módulos que se ensamblan y se despliegan juntamente en el servidor de aplicaciones. En este entorno, todos los módulos EJB dentro de una aplicación se cargan con el mismo cargador de clases y es posible configurar los cargadores de clases de aplicaciones de modo que todos los módulos EJB y WAR (Web Archive) los cargue un solo cargador de clases. Debido a esto, el producto proporciona soporte para varios archivos validation.xml en la misma vía de acceso de clases.
<constraint-mapping>META-INF/constraints-house.xml</constaint-mapping>
<constraint-mapping>META-INF/constraints-rooms.xml</constraint-mapping>
La excepción a este comportamiento es cuando todas las clases y la configuración de restricciones de validación de beans son visibles para todos los módulos de la aplicación. En un caso en el que un único archivo validation.xml se define en un archivo EAR y ningún otro archivo validation.xml está visible en una vía de acceso de clase de módulo, cualquier módulo que crea una fábrica de validador o validador utilizará el archivo validation.xml que se define en el archivo EAR. Esto hace posible que otros módulos creen una fábrica de validador que utiliza el archivo validation.xml de otro módulo siempre que la vía de acceso de clases se haya configurado para que los módulos sean visibles en la misma vía de acceso de clases y sólo un archivo validation.xml sea visible.
Para obtener una descripción más detallada sobre las API y los metadatos de validación de beans, consulte el documento de la especificación de validación de beans JSR 349.