---
title: Validação
---
# Validação com Bean Validation!
O VRaptor possui validação com o Bean Validation. Basta você anotar seu modelo definindo as _constraints_:
~~~
#!java
public class Cliente {
@NotEmpty @Size(min=10, max=50) private String nome;
@Past private Date nascimento;
}
~~~
Em seu controller:
~~~
#!java
public void cadastrar(@NotNull @Valid Cliente cliente) {
// em caso de erros irá redirecionar para a página de formulário
validation.onErrorForwardTo(this).formulario();
}
~~~
##Dependências
Para ativar a validação é necessário ter no _classpath_ alguma implementação para o Bean Validator. Veja mais informações [aqui](/pt/dependencias-e-pre-requisitos).
Se você estiver usando um _servidor de aplicações_ como Wildfly ou Glassfish, você não precisa adicionar nenhuma dependência. Porém se você usar apenas um _servlet container_, é necessário adicionar o Hibernate validator em seu projeto maven, basta incluir no _classpath_ o artefato:
~~~
#!xml
org.hibernatehibernate-validator-cdi5.0.1.Final
~~~
É necessário também indicar ao CDI para não validar os métodos automaticamente. Para isso adicione o arquivo META-INF/validation.xml com o segunte conteúdo:
~~~
#!xml
~~~
##Criando validações customizadas
Com o Bean Validator você pode criar anotações com suas validações customizadas. Se você quer, por exemplo, validar se o login de um usuário já está em uso, basta criar o código abaixo:
~~~
#!java
@Target({ ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = { LoginAvailableValidator.class })
@Documented
public @interface LoginAvailable {
String message() default "{login_already_exists}";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
}
~~~
E agora o `LoginAvailableValidator` que fará a validação:
~~~
#!java
public class LoginAvailableValidator implements ConstraintValidator {
@Inject private UserDao userDao;
public boolean isValid(User user, ConstraintValidatorContext context) {
return !userDao.containsUserWithLogin(user.getLogin());
}
}
~~~
Note no código que é possível injetar qualquer componente gerenciável pelo CDI, que pode ser uma DAO ou qualquer outro componente.
##Redirecionando em caso de erro
Quando ocorre um erro de validação, você pode redirecionar o usuário para qualquer outra tela. Abaixo alguns exemplos:
~~~
#!java
validator.onErrorForwardTo(MusicController.class).list() ==> validator.onErrorUse(logic()).forwardTo(MusicController.class).list();
validator.onErrorRedirectTo(MusicController.class).list() ==> validator.onErrorUse(logic()).redirectTo(MusicController.class).list();
validator.onErrorUsePageOf(MusicController.class).list() ==> validator.onErrorUse(page()).of(MusicController.class).list();
validator.onErrorSendBadRequest() ==> validator.onErrorUse(status()).badRequest(errors);
~~~
Além disso, se o redirecionamento é para um método do mesmo controller, podemos usar:
~~~
#!java
validator.onErrorForwardTo(this).list() ==> validator.onErrorUse(logic()).forwardTo(this.getClass()).list();
validator.onErrorRedirectTo(this).list() ==> validator.onErrorUse(logic()).redirectTo(this.getClass()).list();
validator.onErrorUsePageOf(this).list() ==> validator.onErrorUse(page()).of(this.getClass()).list();
~~~
##Mostrando os erros de validação no JSP
Quando existem erros de validação, o VRaptor coloca um atributo na requisição chamado `errors` contendo a lista de erros. Essa lista é representada por items chave-valor, onde temos:
- category: representa o atributo que originou o erro, cujo valor é uma convenção para metodoController.objeto.caminho.do.atributo
- message: representa a mensagem padrão da API do Bean Validation, normalmente um sufixo como: "deve estar no futuro", "não pode ser nulo", etc.
E na view você pode imprimir:
~~~
#!xml
${error.category} - ${error.message}
~~~
Você também pode buscar por um erro somente de uma determinada categoria:
~~~
#!xml
${errors.asMap().title} // retorna a mensagem para o campo title
~~~
##Customizando as Mensagens
Quando há erros de validação, o Bean Validation anexa um atributo, do tipo lista chave-valor, na resposta da requisição, chamada errors. Essa lista é representada por items chave-valor, onde temos:
* category: representa o atributo que originou o erro, cujo valor é uma convenção para metodoController.objeto.atributo
* message: representa a mensagem padrão da API do Bean Validation, normalmente um sufixo como: "deve estar no futuro", "não pode ser nulo", etc.
Na maioria dos casos, queremos customizar essas mensagens com uma descrição mais amigável.
Para isso, basta adicionar o arquivo ValidationMessages.properties em /src/main/resources.
Considerando o exemplo acima da classe Cliente, o arquivo poderia ter a seguinte estrutura para customizar as mensagens padrões:
~~~
cliente.nome.vazio = O nome do cliente não pode ser vazio
cliente.nome.tamanho = O nome do cliente deve possuir entre {min} e {max} caracteres
cliente.nascimento.data = A data de nascimento ${validatedValue} informada deve ser no passado
~~~
E a classe teria que ser alterada para incluir essas chaves
~~~
#!java
public class Cliente {
@NotEmpty(message="{cliente.nome.vazio}")
@Size(min=10, max=50, message="{cliente.nome.tamanho}")
private String nome;
@Past(message="{cliente.nascimento.data}")
private Date nascimento;
}
~~~
Veja que foi adicionado parâmetros afim de deixar nossas mensagens mais dinâmicas e reaproveitáveis. As possibilidades atualmente são:
* os valores dos atributos da restrição mapeados com os nomes de atributo. Ex. {min} e {max} no caso de @Size
* o atual valor a ser validado sob o nome de ${validatedValue}
* uso de if-else curto, como por exemplo: ${value > 1 ? 's' : ''}
* um bean mapeado com o nome de formatter expondo método var-arg format(String format, Object... args) o qual se comporta como java.util.Formatter.format(String format, Object... args). Ex.: ${formatter.format('%1$.2f', validatedValue)}