[Resolvido] Anotação @Validate na validação de CPF - Stella Caelum

Consegui inserir um proprietario com a anotação:

@CPF(formatted=true, message="erro no cpf")
	private String cpf;

Mas como faço pra essa msg aparecer na jsp? É assim que usa essa anotação pra validar?

Madrugando, é? Hehehe.

Guevara, basta você anotar a classe POJO com as tuas constraints tanto com as do Bean Validation como dessa API que te passei. Após você anotar a classe o próximo passo é injetar o objeto Validation do Vraptor no seu controller. Nele há um método chamado Validation.validate, que valida teus beans a partir das anotações que você usou.

[code]@Resource
public class CustomerController {

private final Validator validator;

public CustomerController(Validator validator) {
    this.validator = validator;
}

public void store(CustomerDetails customer) {
    validator.validate(customer);
    validator.onErrorForwardTo(this).edit(customer.getId());
}

}[/code]

A validação é devolvida para você dentro do objeto errors que fica acesível do JSP como ${errors}, esse que você já deve conhecer, que é o padrão do Vraptor. Esse objeto na verdade é um map sendo que o key é o campo com erro e value é a mensagem de validação.

<c:if test="${not empty errors}"> Erros de validação: <br /> <c:forEach items="${errors}" var="e"> ${e.category} - ${e.message} <br /> </c:forEach> </c:if>

Abraços

Opa!
Agora sim! :smiley:
Foi só colocar o validator.validate(proprietario) que funcionou. \o/
O legal é que dá pra validar E-Mail, CEP e CNPJ também.
Valeu Garcia!
Abraço!!

obs: o Java tá dominando as madrugadas. :lol:

Opa, beleza??
Onde posso achar a documentação das anotações?
Preciso configurar isto direito pq agora não consigo inserir os dados com o que eu tenho anotado:

@CPF(formatted=true, message="CPF inválido, digite novamente")
	private String cpf;
	@Telefone(format="####-####", message="Telefone incorreto, digite novamente")
	private String telefone;
	@Telefone(format="####-####", message="Celular incorreto, digite novamente")

Stacktrace:

21:21:56,660 DEBUG [OgnlParametersProvider] Applying proprietario.email with [elaine@gmail.com]
21:21:56,679 DEBUG [OgnlParametersProvider] Applying proprietario.cpf with [062.245.741-68]
21:21:56,680 DEBUG [OgnlParametersProvider] Applying proprietario.telefone with [7898-8555]
21:21:56,681 DEBUG [OgnlParametersProvider] Applying proprietario.celular with [8855-1223]
21:21:56,682 DEBUG [OgnlParametersProvider] Applying proprietario.nome with [Elaine]
21:21:56,683 DEBUG [OgnlParametersProvider] Applying proprietario.idProprietario with [4]
21:21:56,685 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for ProprietarioController.altera(Proprietario) as [proprietario]
21:21:56,685 DEBUG [ParametersInstantiatorInterceptor] Parameter values for [DefaultResourceMethod: ProprietarioController.alteraProprietarioController.altera(Proprietario)] are [br.com.imobiliaria.bean.Proprietario@19de6c]
21:21:56,713 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExecuteMethodInterceptor
21:21:56,714 DEBUG [ExecuteMethodInterceptor] Invoking ProprietarioController.altera(Proprietario)
21:21:56,765 DEBUG [JSR303Validator     ] there are 3 violations at bean br.com.imobiliaria.bean.Proprietario@19de6c.
21:21:56,768 DEBUG [JSR303Validator     ] added message Celular incorreto, digite novamente to validation of bean br.com.imobiliaria.bean.Proprietario@19de6c
21:21:56,769 DEBUG [JSR303Validator     ] added message Telefone incorreto, digite novamente to validation of bean br.com.imobiliaria.bean.Proprietario@19de6c
21:21:56,769 DEBUG [JSR303Validator     ] added message CPF inválido, digite novamente to validation of bean br.com.imobiliaria.bean.Proprietario@19de6c
21:21:56,769 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for ProprietarioController.altera(Proprietario) as [proprietario]
21:21:56,979 DEBUG [DefaultLogicResult  ] redirecting to class ProprietarioController
21:21:57,013 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for ProprietarioController.edita(Long) as [idProprietario]
21:21:57,014 DEBUG [DefaultLogicResult  ] redirecting to /imobiliaria/proprietario/edita
21:21:57,015 DEBUG [VRaptor             ] VRaptor ended the request

Esse “format” que eu não sei se está certo.
Abraço!

É só o Garcia que têm a documentação desse js303-br.jar?
Abraço!!

Oi Guevara. Esse projeto é um projeto pessoal meu, e com a pequena falta de tempo a documentação é curta. Tem os javadocs do projeto, se você usa o Eclipse quando você passa o mouse encima do método o Eclipse já completa a documentação.

Fazendo uma rápida explicação, todas as anotações possuem o campo message que se você deixa em branco ele pega as mensagens padrão. Ou vocẽ pode definir sua própria mensagem como você fez.

O campo formatted significa que o campo é formatado, caso contrário considero o campo como “somente numeros”. No caso um CPF válido será 000.000.000-00 e CNPJ 00.000.000/0000-00. Para CEP é considerado 00000-000 e telefone como 00.0000.0000.

O campo format é uma regex de como você quer que seja o formato válido para o campo. A classe RegexConstants [1] possui as regex usadas no projeto, e você pode se basear nelas para escrever seus próprios formatos.

Vou ver se consigo melhorar a documentação dele.

[1] http://github.com/garcia-jj/jsr303-br/blob/master/src/com/github/jsr303br/util/RegexConstants.java

Opa!
Valeu Garcia! :smiley:
Segui então esse formato na inserção dos dados, mas não está passando pela validação:

@CPF(message="CPF inválido, digite novamente")
	private String cpf;
	@Telefone(message="Telefone incorreto, digite novamente")
	private String telefone;
	@Telefone(message="Celular incorreto, digite novamente")
	private String celular;

Deixei apenas as mensagens, e coloquei no formato que vc passou. Mesmo assim diz que o cpf e os telefones estão incorretos.

O padrão para formatted é FALSE, ou seja, se o CPF que você está passando é formatado você precisa colocar formatted=true.

Pois é Garcia, eu fiz isso tb, passei o CPF como 081.675.457-75 e como 08167545775, mesmo assim não valida.
O telefone parece que é validado com o formato 2125474455 e não como 21.2547.4455.

Guevara, alguma coisa está errada aí. Note a classe de teste que tenho no projeto para validar se o CPF está correto:

http://github.com/garcia-jj/jsr303-br/blob/master/test/com/github/jsr303br/CPFTest.java

violations = validator.validate(new Cliente().setCpf1("652.493.248-00")); logger.debug(violations.toString()); Assert.assertTrue(violations.size() == 1);

public class Cliente { @CPF(formatted = true) public String cpf1; }

Agora entendi, deu boa, a validação faz o cálculo mesmo para saber se é válido ou não:
http://www.profcardy.com/artigos/cpf.php
Para alterar o formato do telefone para “21-9999-9999” eu não tô conseguindo:

@Telefone(format="99-9999-9999", message="Telefone incorreto, digite novamente")

Tô seguindo o exemplo da sua classe: http://github.com/garcia-jj/jsr303-br/blob/268684e9d550b381055061346ba5cc87a978893e/test/com/github/jsr303br/TelefoneTest.java
É isso mesmo?
Abraço!!

Lá no “format” do telefone eu coloco a expressão regular?

@Telefone(format=".-//d.-\\d\\d\\d\\d-\\d\\d\\d\\d",message="Telefone incorreto, digite novamente", formatted=true)

Tava precisando colocar os parênteses com o ddd ali:

16:35:44,970 DEBUG [OgnlParametersProvider] Applying proprietario.telefone with [(21)9999-9999]
16:35:44,971 DEBUG [OgnlParametersProvider] Applying proprietario.celular with [(21)8888-8888]

Abraço!

Putz, consegui, segui este tutorial aqui:
http://www.vaniomeurer.com.br/tag/javautilregex/
Ficou assim:

@Telefone(format=".\\d\\d.\\d\\d\\d\\d-\\d\\d\\d\\d",message="Telefone incorreto, digite novamente", formatted=true)

Abraço!! \o/

Oi Guevara. Como eu tinha te dito no outro post você deve usar expressões regulares. Vou ver se essa semana melhoro a documentação dele.

Abraços

Valeu Garcia!
Quando sair a documentação avise que eu vou baixar. =)
Esta validação ficou bem legal, tava pensando se seria possível fazer a validação para valores, anotar um atributo BigDecimal por exemplo. O problema seria o banco, pq o Hibernate cria a coluna como numeric(19,2) o valor fica assim 1504.00, ao invés de 1.504,00, pior ainda usando máscara no input. hehe
Abraço!!

Guevara, BigDecimal é sempre 1504.00 e não 1504,00. Quando você enxerga com virgulas isso é na verdade apenas uma representação do objeto formatado, mas não o objeto valor em sí. Se você quiser validar um valor como 1504,00 o seu campo precisa ser uma String ao invés de BigDecimal.

Saquei, mas o problema é a máscara:

jQuery("#real").maskMoney({symbol:"R$",decimal:",",thousands:"."}); 

Vai mandar com ponto e vírgula, ai não dá pra salvar no banco. Eu tava pensando em alguma anotação que retirasse o ponto do milhar e a virgula do decimal, colocando o ponto no lugar, isso poderia ser feito por anotação tb, senão vou ter que criar um método usando replace para formatar o valor corretamente antes de ser persistido.
Tenho até outro tópico sobre isso.
http://www.guj.com.br/posts/list/217654.java
Abraço

Guevara, você pode usar uma regex no próprio Bean Validator anotando a propriedade com @Regex e passando uma expressão regular que faça o trabalho.

Abraços

Oi Garcia!
Tô passando pra postar a solução:
Colocar no web.xml:

<context-param>  
     <param-name>br.com.caelum.vraptor.packages</param-name>      
     <param-value>br.com.caelum.vraptor.converter.l10n</param-value>  
 	</context-param>   

Vi essa dica postada pelo Lucas em outro tópico. :smiley:
Agora sim, posso usar a máscara JQuery para valores, ao digitar o valor ele é convertido de 2.500,00 para 2500.00, no formato que o banco espera receber.
Abraço!!

Ahh, agora eu entendi o que você queria, hehe :slight_smile:

Abraços