Validação de Bean
A API de Validação de Bean é introduzida com a plataforma Java™ Enterprise Edition 6 como um mecanismo padrão para validar JavaBeans em todas as camadas de um aplicativo, incluindo apresentação, negócios e acesso a dados.
Antes da especificação de uma Validação de Bean, JavaBeans eram validados em cada camada. Para evitar a reimplementação de validações em cada camada, os desenvolvedores empacotavam validações diretamente em suas classes ou copiavam o código de validação, o que ficava geralmente confuso. Ter uma implementação que seja comum para todas as camadas do aplicativo simplifica o trabalho dos desenvolvedores e economiza tempo.
A especificação da Validação de Bean define um modelo de metadados e uma API que são usados para validar JavaBeans para integridade de dados. A origem de metadados são as anotações de restrição definidas que podem ser substituídas e estendidas com o uso de descritores de validação XML. O conjunto de APIs fornece um modelo de programação fácil de usar, permitindo que qualquer camada de aplicativo use o mesmo conjunto de restrições de validação. As restrições de validação são usadas para verificar o valor dos campos, métodos e tipos anotados para garantir que eles sigam a restrição definida.
As restrições podem ser integradas ou definidas pelo usuário. Várias anotações integradas estão disponíveis no pacote javax.validation.constraints. Elas são usadas para fazer definições de restrições regulares e para compor restrições. Consulte as informações sobre restrições integradas de Validação de Bean para obter uma lista das restrições integradas. Para obter mais detalhes sobre o modelo de metadados de Validação de bean e APIs, consulte o documento da especificação Validação de Bean JSR 349.
O exemplo a seguir é uma classe Enterprise JavaBeans (EJB) simples decorada com anotações de restrição integradas.
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;
}
}
As anotações @Size no construtor e endereço especificam que o valor de sequência não deve ter mais de 20 caracteres. A anotação @NotNull no endereço indica que ele não pode ser nulo. Quando o objeto Home é validado, o construtor e os valores de endereço são transmitidos para a classe do validador definida para a anotação @Size. O valor do endereço também é transmitido para a classe do validador @NotNull. As classes do validador fazem a verificação de valores para as restrições adequadas, e se alguma restrição falhar na verificação, um objeto ConstraintViolation é criado e retornado em um conjunto para o responsável pela chamada validando o objeto Home.
APIs de Validação
O pacote javax.validation contém as APIs de validação de bean que descrevem como validar programaticamente JavaBeans.
ConstraintViolation é a classe que descreve a falha de restrição. Um conjunto de classes ConstraintViolation é retornado para uma validação de objeto. A violação de restrição também expõe uma mensagem legível por humanos descrevendo a violação.
Uma ValidationException é levantada se acontecer uma falha durante a validação.
A interface do Validador é a principal API de validação, e uma instância do Validador é o objeto capaz de validar os valores dos campos, métodos e tipos do objeto Java. A API de autoinicialização é o mecanismo usado para obter acesso a um ValidatorFactory que é usado para criar uma instância do Validador. Para aplicativos implementados no produto, a autoinicialização é feita automaticamente. Há duas maneiras para os aplicativos obterem o validador ou o ValidatorFactory. Uma maneira é a injeção, por exemplo, usar a anotação @Resource, e outra maneira é usar java: lookup.
@Resource ValidatorFactory _validatorFactory;
@Resource Validator _validator;
ValidatorFactory validatorFactory = (ValidatorFactory)context.lookup("java:comp/ValidatorFactory");
Validator validator = (Validator)context.lookup("java:comp/Validator");
APIs de Solicitação de Metadados de Restrição
As APIs de metadados suportam provedores de ferramenta, fornecem integração com outras estruturas, bibliotecas e tecnologias Java Platform, Enterprise Edition. O repositório de metadados das restrições de objetos é acessado por meio da instância do Validador de uma determinada classe.
Descritores de Implementação XML
Além de declarar restrições em anotações, existe suporte para o uso de XML para declarar suas restrições.
A descrição de XML de validação é composta por dois tipos de arquivos xml. O arquivo META-INF/validation.xml descreve a configuração de validação para o módulo. O outro tipo de arquivo XML descreve declarações de restrições e corresponde exatamente ao método de declaração de anotações. Por padrão, todas as declarações de restrição expressas por meio de anotações são ignoradas para as classes descritas em XML. É possível forçar a validação a usar as anotações e as declarações de restrição XML usando a configuração ignore-annotation="false" no bean. O produto garante que os módulos aplicativos implementados contendo um arquivo validation.xml e as restrições definidas em arquivos XML sejam isolados do outro módulo validation.xml e arquivos de restrição, criando instâncias do validador específicas para o módulo contendo os descritores XML.
Conceitos de Validação de Bean Avançados
A API de Validação de Bean fornece um conjunto de restrições integradas e uma interface que permite declarar restrições customizadas. Isso é feito criando anotações de restrição e declarando uma anotação em um tipo, campo ou propriedade de bean. A composição de restrições também é feita declarando a restrição em outra definição de restrição.
O exemplo a seguir mostra a criação de uma restrição CommentChecker definida para garantir que um campo de sequência de comentário não seja nulo. O texto do comentário é colocado entre colchetes [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 "The comment is not valid.";
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) {
// Um comentário NULL não é permitido; falha na restrição.
return false;
}
if (!comment.contains("[") && !comment.contains("]")) {
// Não é possível localizar nenhum colchete aberto ou fechado; falha na restrição.
return false;
}
// Ignore espaços iniciais e finais
String trimmedComment = comment.trim();
return // validar condição de prefixo '['
trimmedComment.charAt(0) == '[' &&
// validar condição de sufixo ']'
trimmedComment.charAt(trimmedComment.length()!-1) == ']';
}
}
Após @CommentChecker ser definido, ele pode ser usado
para garantir que o campo de sequência de comentário seja um comentário
válido baseado na implementação de CommentValidator isValid(). O exemplo
a seguir mostra o uso da restrição @CommentChecker. Quando o bean myChecker é validado, a sequência de comentário é validada
pela classe CommentValidator para garantir que restrições definidas sejam
atendidas. package com.my.company;
public myChecker {
@CommentChecker
String comment = null;
...
}
O produto fornece um provedor de validação de bean padrão, mas talvez você queira usar um provedor alternativo em seu aplicativo. É possível escolher um provedor alternativo programaticamente chamando o método javax.Validation.Validation.byProvider() para criar um factory de validação. Alternativamente, é possível escolher um provedor alternativo de forma declarativa, especificando o elemento <default-provider/> no arquivo validation.xml. Se desejar assegurar que as classes do provedor alternativo não entrem em conflito com o provedor padrão, configure a ordem do carregador de classes do servidor ou do aplicativo para o valor: Classes carregadas com o carregador de classes primeiro (pai por último). Consulte a documentação de carregamento de classe para obter informações adicionais sobre como definir essa configuração.
A especificação de Validação de Bean indica que se mais de um arquivo validation.xml for localizado no caminho da classe, ocorrerá uma ValidationException. No entanto, o WebSphere Application Server suporta um ambiente no qual diversas equipes desenvolvem módulos que são montados e implementados juntos em um Application Server. Nesse ambiente, todos os módulos EJB dentro de um aplicativo são carregados com o mesmo carregador de classes, e é possível configurar os carregadores de classes de aplicativo para que todos os módulos EJB e de archive Web (WAR) sejam carregados por um único carregador de classes. Devido a isso, o produto fornece suporte para diversos arquivso validation.xml no mesmo caminho da classe.
<constraint-mapping>META-INF/constraints-house.xml</constaint-mapping>
<constraint-mapping>META-INF/constraints-rooms.xml</constraint-mapping>
A exceção para esse comportamento é quando todas as classes e configuração de restrições de validação de bean estão visíveis para todos os módulos aplicativos. Em um caso em que um único arquivo validation.xml é definido em um arquivo EAR, e nenhum outro arquivo validation.xml está visível em um caminho da classe do módulo, qualquer módulo que crie um factory de validador ou validador usará o arquivo validation.xml definido no arquivo EAR. Isto torna possível para outros módulos criar um factory de validador que usa o arquivo validation.xml de outro módulo, se o caminho da classe tiver sido configurado de forma que ambos os módulos sejam visívels no no mesmo caminho da classe e apenas um arquivo validation.xml esteja visível para estes módulos.
Para ter um entendimento mais detalhado sobre APIs de Validação de bean e metadados, consulte o documento da especificação Validação de Bean JSR 349.