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

Oi pessoal!
Estou seguindo o tutorial (http://stella.caelum.com.br/frameworks-vraptor.html) para validar CPF usando o Stella, mas a anotação @Validate(params = “”) não existe.
Já adicionei os dois jar’s na /lib e dei refresh:
caelum-stella-hibernate-validator-1.2.jar
caelum-stella-core-1.2.jar
Na minha classe está assim:

@CPF
	private String cpf;

Na JSP está:

<label for="cpf">CPF</label>
	<input id="cpf" name="proprietario.cpf" type="text" maxlength="255" /><br />

Mas não valida nada, está gravando com CPF incorreto, achei que poderia ser pela falta do @Validate no método de adicionar o proprietário no Controller:

	public void adiciona(final Proprietario proprietario) { 
//codigos
}

Estou usando Hibernate 3.5.1, o jar dele está na /lib.
Abraço!! o/

O Stella somente valida usando Hibernate 3 Validator e Vraptor 2, mas não funciona com o Bean Validator, nem com Vraptor 3 e nem com o Hibernate Validator 4.

A alternativa é você criar um componente para fazer essa validação. O Lavieri fez isso e me mandou o jar, porém eu perdi.

Se você quer fazer validações usando o componente de validação do Vraptor 3 você pode usar uma API que eu andei escrevendo e que está no meu github. Devido a falta de tempo não fiz nenhum build, mas vou ver se faço isso agora mesmo, hehe.

Com essa API basta você anotar seu bean com @CPF, @CNPJ e afins, e quando você persistir o objeto ou chamar no Vrator o validation.validate(meuBean) as anotações serão validados.

http://github.com/garcia-jj/jsr303-br

Coloquei um binário lá: http://github.com/garcia-jj/jsr303-br/downloads

Vou aproveitar e atualizar o markdown. :oops:

Opa!! Valeu garcia! Não sabia que pro VRaptor 3 não funcionava, uma pena. =/
Já baixei o seu jar aqui, vou ver como funciona e já dou um retorno.
Abraço!

Tá mandando configurar o build path…

import com.github.jsr303br.CPF;

@CPF
	private String cpf;

Preciso adicioná-lo lá mesmo estando na /lib?

Quando você adiciona um jar dentro do seu projeto, você precisa dar um refresh na workspace (para sincronizar ela com o filesystem) e também precisa adicionar ao projeto.

Quando você tem um Dynamic Web Project e coloca um jar dentro do WEB-INF/lib o Eclipse automagiamente adiciona esse jar ao classpath, caso contrário precisa ser manual.

Então, já dei refresh e reiniciei o Tomcat, adicionei o jar ao buildpath e continua mandando configurar lá. =)

Vai lá no buildpath então e você se tem algum erro ou warning.

Está acusando pra configurar o BuilPath e esta mensagem:

Tem que ter o jar do bean validation. No vraptor tem esses jars em lib/optional/validation-api-1.0.0.GA.jar

Baixei o jar daqui:
http://repository.jboss.org/maven2/javax/validation/validation-api/1.0.0.GA/
Ai resolveu aquele erro. Anotei na classe @CPF e ao chamar a aplicação pelo browser surgem os erros:

root cause

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'JSR303ValidatorFactory': Unsatisfied dependency expressed through constructor argument with index 0 of type [javax.validation.ValidatorFactory]: : Error creating bean with name 'br.com.caelum.vraptor.validator.ValidatorFactoryCreator': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validatorFactoryCreator': Invocation of init method failed; nested exception is javax.validation.ValidationException: Unable to find a default provider; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'br.com.caelum.vraptor.validator.ValidatorFactoryCreator': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validatorFactoryCreator': Invocation of init method failed; nested exception is javax.validation.ValidationException: Unable to find a default provider
root cause

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'br.com.caelum.vraptor.validator.ValidatorFactoryCreator': FactoryBean threw exception on object creation; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'validatorFactoryCreator': Invocation of init method failed; nested exception is javax.validation.ValidationException: Unable to find a default provider
	org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:150)
root cause

javax.validation.ValidationException: Unable to find a default provider
	javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:264)

Têm que fazer algo mais??
Abraço!

O ideal é pegar os jars que tem no próprio vraptor.

Se você não está em um appserver com JEE6 você precisa também do Hibernate Validator 4x (tem tudo no vraptor/lib)

Vou baixar o último VRaptor de novo, pq no que eu tenho não existe esse jar dentro da /lib/optional.
guenta ai…

Agora sim, preenchi o form e tenho este erro agora:

root cause

javax.validation.ConstraintViolationException: validation failed for classes [br.com.imobiliaria.bean.Proprietario] during persist time for groups [javax.validation.groups.Default, ]
	org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:132)
	org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:71)
	org.hibernate.action.EntityIdentityInsertAction.preInsert(EntityIdentityInsertAction.java:159)
	org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:65)
	org.hibernate.engine.ActionQueue.execute(ActionQueue.java:268)

Preciso anotar o método do Controller com @ Valid?
import javax.validation.Valid;

Abraço!

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