Validación de Métodos en Componentes JBoss Seam

JUAN MIGUEL BERNAL GONZALEZ 2015/12/04 12:32

Hemos añadido la posibilidad de hacer la validación de los métodos de los componenetes Seam (aquellos que se definen en el fichero componentes.xml mediante la etiqueta <component> o mediante la anotacion @Name, tanto para beans Java como para EJBs de sessión. Para validar un método solo hay que añadir la anotación org.jboss.seam.annotations.validation.@MethodValidated en el método a validar.

Cuando un componente Seam forma parte de una jerarquía de herencia, las anotaciones de validación tienen que encontrarse en la clase o interface raíz de la jerarquía. Cuando el componente Seam es un EJB, las anotaciones de validación tienen que estar en una interface, no pueden estar en la implementación ni ser un EJB sin interfaces (un @LocalBean).

Para esta validación podéis utilizar los validadores de Bean Validation 1.0 e Hibernate Validation 4.3.2.Final, además de los que os hayáis definido vosotros con estas tecnologías.

Tenemos que realizar las siguientes modificaciones:

  • Abrimos el POM Principal del proyecto y modificamos el <parent> a la versión 2.0.20 o posterior.
  • Posiblemente, tengamos problemas de dependencias si estabamos en una version del <parent> anterior a la 2.0.17. Para solucionar el problema, abrimos el POM del módulo WEB y eliminamos las dependencias <artifactId>cas-client-core</artifactId> y <artifactId>velocity</artifactId> y añadimos las siguiente en su lugar:
                <dependency>
			<groupId>org.jasig.cas.client</groupId>
			<artifactId>cas-client-support-saml</artifactId>
		</dependency>
  • Abrimos el fichero weblogic-applicaction.xml y añadimos dentro de la etiqueta <prefer-application-packages> la etiqueta <package-name>org.hibernate.validator.*</package-name>.

Veamos un par de ejemplos con un componente Seam Java bean:

package es.um.atica.portalfundeweb.rest;
 
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
 
import org.hibernate.validator.constraints.Length;
import org.jboss.seam.annotations.Logger;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.validation.MethodValidated;
import org.jboss.seam.log.Log;
 
import org.hibernate.validator.constraints.Length;
 
@Name("pruebaValidacion")
public class PruebaValidacion {
 
    @MethodValidated
    @Length(min=5)
    public String saluda(@NotNull @Length(min=2, max=10) String nombre) {      
        return "Hola " + nombre + "!!!" ;
    }
 
    @MethodValidated
    @Valid
    public PersonaPrueba validaPersonaPrueba( 
            @NotNull @Length(min = 2, max = 10 ) String nombre,
            @NotNull @Length(min = 2, max = 10 ) String apellido,
            @NotNull @Length(min = 2, max = 10 ) String movil ) {
 
        return new PersonaPrueba(nombre, apellido, movil);
    }
 
}

En el comonente Seam PruebaValidacion tenemos dos métodos saluda y validaPersonaPrueba, estos métodos tienen anotaciones de validación, tanto para los parámetros de entrada como para el resultado de la operación. Además de la anotación @MethodValidated, que indica, que el método se debe validar.

Para el método saluda, el parámetro de entrada nombre no puede ser nulo y tiene que tener una longitud entre 2 y carácteres. El resultado del método tiene que tener una longitud mínima de 5 carácteres.

Para el método validaPersonaPrueba, los parámetros de entrada no puede ser nulos y tienen que tener una longitud entre 2 y carácteres. El resultado del método es una instancia de la clase PersonaPrueba. Para validar un tipo complejo, se utiliza la anotación javax.validation.@Valid.

package es.um.atica.portalfundeweb.rest;
 
import javax.validation.constraints.NotNull;
 
import org.hibernate.validator.constraints.Length;
 
 
public class PersonaPrueba {
 
    public PersonaPrueba(String nombre, String apellido, String movil) {
        this.nombre = nombre;
        this.apellido = apellido;
        this.movil = movil;
    }
 
    @NotNull
    @Length(min=5, max=10)
    private String nombre;
 
    @NotNull
    @Length(min=5, max=10)
    private String apellido;
 
    @NotNull
    @Length(min=5, max=10)    
    private String movil;
 
    public String getNombre() {
        return nombre;
    }
 
    public void setNombre( String nombre ) {
        this.nombre = nombre;
    }
 
    public String getApellido() {
        return apellido;
    }
 
    public void setApellido( String apellido ) {
        this.apellido = apellido;
    }
 
    public String getMovil() {
        return movil;
    }
 
    public void setMovil( String movil ) {
        this.movil = movil;
    }
 
    @Override
    public String toString() {
        return nombre + " " + apellido + " --> " + movil;
    }
 
}

La anotación javax.validation.@Valid indica al sistema de validación, que valide las propiedades de la clase PersonaPrueba. Esta clase tiene tres propiedades que no pueden ser nulas y tienen que tener una longitud comprendida entre 5 y 10 carácteres.

Veamos los mismos ejemplos con un componente Seam EJB:

  • Primero la interface:
package es.um.atica.portalfundeweb.validacion;
 
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
 
import org.hibernate.validator.constraints.Length;
import org.jboss.seam.annotations.validation.MethodValidated;
 
import es.um.atica.portalfundeweb.rest.PersonaPrueba;
 
public interface PruebaValidacionEjb {
 
    @MethodValidated
    @Length(min=5)
    String saluda(@NotNull @Length(min=2, max=10) String nombre);
 
    @MethodValidated
    @Valid
    PersonaPrueba validaPersonaPrueba( @NotNull @Length(min = 2, max = 10 ) String nombre,
                                        @NotNull @Length(min = 2, max = 10 ) String apellido,
                                        @NotNull @Length(min = 2, max = 10 ) String movil );
 
}
  • Ahora la implementación:
package es.um.atica.portalfundeweb.validacion;
 
import javax.ejb.Local;
import javax.ejb.Stateless;
 
import org.jboss.seam.annotations.Name;
 
import es.um.atica.portalfundeweb.rest.PersonaPrueba;
 
@Local(PruebaValidacionEjb.class)
@Stateless
@Name("pruebaValidacionEjb")
public class PruebaValidacionEjbImpl implements PruebaValidacionEjb {
 
    @Override
    public String saluda(String nombre){
        return "Hola " + nombre + "!!!" ;
    }
 
    @Override
    public PersonaPrueba validaPersonaPrueba(String nombre, String apellido, String movil ) {
        return new PersonaPrueba(nombre, apellido, movil);
    }
 
}

La anotación org.jboss.seam.annotations.validation.@MethodValidated tiene la siguiente definición:

package org.jboss.seam.annotations.validation;
 
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
 
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
 
import org.jboss.seam.validation.ValidationMode;
import org.jboss.seam.validation.handlers.MethodConstraintViolationHandler;
import org.jboss.seam.validation.handlers.ThrowValidationExceptionHandler;
 
/**
 * This is an annotation that is used with the Interceptor MethodValidationInterceptor,
 * that will validate the parameters and the result of a executed method in a seam component.
 * 
 * @author juanmiguelbg
 * @version 0.0.1
 */
@Target(METHOD)
@Retention(RUNTIME)
@Inherited
public @interface MethodValidated {
 
    /**
     * Execute the validation on the method parameters only.
     */
    ValidationMode mode() default ValidationMode.BOTH;
 
    /**
     * A - potentially empty - number of validation groups for which
     * the validation shall be performed. The @link {@link javax.validation.groups.Default}
     * group will be validated if no group is given.
     */
    Class<?>[] groups() default { javax.validation.groups.Default.class };
 
    Class<? extends MethodConstraintViolationHandler> constraintViolationHandler() default ThrowValidationExceptionHandler.class;
}

La anotación tiene las siguientes propiedades:

  • mode: el modo de validación, que puede ser un valor del enumerado org.jboss.seam.validation.ValidationMode:
    • BOTH: validar los parámetros y la respuesta (valor por defecto).
    • PARAMETERS: solo validar los parámetros.
    • RESULT: solo validar el resultado.
    • NONE: no validar.
  • groups: el grupo de validación. Se pueden agrupar validaciones. El grupo por defecto es javax.validation.groups.Default.class.
  • constraintViolationHandler: clase que implementa la interface org.jboss.seam.validation.handlers.MethodConstraintViolationHandler, que permite indicar que hacer con los violaciones de las restricciones de validación. Los handlers disponibles son:
    • org.jboss.seam.validation.handlers.ThrowValidationExceptionHandler: que lanza la excepción org.jboss.seam.validation.exceptions.ValidationException con el conjunto de las restricciones violadas. Si estamos dentro de una transacción, y se lanza dicha exceción, y esta sale del punto de creación (begin) de la transacción, la transacción se marcara para rollback. Es el handler por defecto, también es el comportamiento por defecto en JEE 7.
    • org.jboss.seam.validation.handlers.AddToStatusMessageHandler: que añade la información de las restricciones violadas al StatusMessages, que luego se mostraran en el componente PrimeFaces Growll o en el Messages global de la aplicación. Este handler no lanza excepción, por tanto si esta dentro de una transacción, esta no se marcara para rollback.

Bean Validation

Hibernate Validator

The Java EE 6 Tutorial

  • fdw2.0/fundeweb2.0/gt/validacion_metodos-componentes_seam.txt
  • Última modificación: 07/11/2017 10:46
  • (editor externo)