Validação de Campos no Vraptor3

40 respostas
mdbatera

É galera, estou adotando o vraptor 1000% rsrs

O vraptor3 já tem validação de CPF e CNPJ nele, ou alguma função direcionada a isso, que facilite a vida?

Abraços!

40 Respostas

yorgan

O VRaptor não faz esse tipo de validação, mas você pode facilmente integrar os validadores do Stella Core.

Segue o link: http://stella.caelum.com.br/

[]´s

Daniel

mdbatera

Beleza!! eu instalei o Stella, e ele já está ceitando as anotations, aí coloquei na minha classe Cliente:

e agora quero saber como sinaliso isso no meu ClienteController:

Detalhe que simulei um cadastro com o CPF válido ele jogou no banco numa boa, mas quando coloquei um cpf errado ele jogou uma:
exception

br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method

Valeu Velho!

yorgan

Receba no seu construtor o objeto Validator:

import br.com.caelum.vraptor.Validator;
.....
private Result result;
private Validator validator;
public ClienteController(Result result, Validator validator){
this.result = result;
this.validator= validator;
} 

....
//Para validar faça assim:
public void adiciona(Cliente cliente){
      validator.addAll(Hibernate.validate(cliente)); //valida e coloca as mensagens no request
      validator.onErrorUse(page()).of(SuaClasse.class).metodo(); //defina aqui a navegação para o caso de haver algum erro

      new ClienteDao().adiciona(cliente);
      result.include("mensagem", "Cliente cadastrado com sucesso");
      result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();

}

E para pegar os erros na JSP faça algo assim:

<ul>
      <c:forEach var="error" items="${errors}">
            <li><label class="erro">${error.message}</label></li>
      </c:forEach>
</ul>

Mais uma coisa, como você anotou como @Component o seu DAO, você pode recebe-lo no construtor do controller da mesma forma que fez com o Result.

[]´s

Daniel

yorgan

E utilize a tag Code para postar códigos.

[]´s
Daniel

mdbatera

Beleza, mas se ligue:

public void adiciona(Cliente cliente){
		validator.addAll(Hibernate.validate(cliente));
		validator.onErrorUse([b]page[/b]()).of(ClienteController.class).cadastracliente();
		new ClienteDao().adiciona(cliente);
		result.include("mensagem", "Cliente cadastrado com sucesso");
		result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();
		
	}

o eclipse fica dando pau alu no “page”.

yorgan

Esqueci de colocar o import dele:

import static br.com.caelum.vraptor.view.Results.page;
mdbatera

Rapaz isso é muito bom, funcionou beleza aqui, coisa divina! rsrsrs

Como faço pra tratar a mensagem?

aqui apareceu {cpf_invalid}.

Muito Obrigado mesmo!

yorgan

Anote o campo como:

G

Não, por favor, não use isso!!!

Ainda não foi atualizada a documentação, mas você deve agora fazer isso aqui:

Assim o vraptor faz as validações automaticas. O método Hibernate.validate está em depreciated (desde a 3.1.2).

mdbatera

Bem, realmente ele parou de grifar o nome Hibernate que estava grifando, e mesmo anotando na classi @NotNull, ele estava aceitando campos vazios, porém quando eu fiz a modificação que vc me mandou ele me deu um Haducken(erro), segue a stack trace:

br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
	br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.produtos.interceptor.LoginInterceptor.intercept(LoginInterceptor.java:30)
	br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)

root cause

java.lang.NullPointerException
	br.com.caelum.vraptor.validator.JSR303Validator.validate(JSR303Validator.java:67)
	br.com.caelum.vraptor.validator.DefaultValidator.validate(DefaultValidator.java:72)
	br.com.caelum.produtos.controller.ClienteController.adiciona(ClienteController.java:32)
	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	java.lang.reflect.Method.invoke(Unknown Source)
	br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.produtos.interceptor.LoginInterceptor.intercept(LoginInterceptor.java:30)
	br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)

Agora como ficou a action pra você da uma olhada:

public void adiciona(Cliente cliente){
		validator.validate(cliente); 
		validator.onErrorUse(page()).of(ClienteController.class).cadastracliente();
		new ClienteDao().adiciona(cliente);
		result.include("mensagem", "Cliente cadastrado com sucesso");
		result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();

Valeu…

G

Você está com uma versão do vraptor que está com problemas nesse componente.

Baixe esse jar aqui que tem um snapshot com a correção: http://oss.sonatype.org/content/repositories/snapshots/br/com/caelum/vraptor/3.1.3-SNAPSHOT/vraptor-3.1.3-20100519.161626-7.jar (créditos ao Lucas)

mdbatera

é só jogar no repositório???

G

Sim, e remova o jar antigo do vraptor.

mdbatera

Coloquei o jar e apaguei o anterior, mas o sisteminha não inicia?

coloca o nome do arquivo igual ao jar anterior que eu apaguei?

G

Não tenho como saber simplesmente com o “não funciona”. Qual a mensagem de erro? Alguma coisa no stacktrace?

Abraços

Lucas_Cavalcanti

mdbatera, se vc está usando só o Hibernate Validator 3, vc tem que tirar do classpath (WEB-INF/lib) os jars:

validation-api*.jar
hibernate-validator-4.*.jar

e vc só precisa tirar o vraptor-3.1.2.jar e colocar o snapshot que o garcia-jj falou

mdbatera

Ok!, resolvido,

como faço para validar o cpf e não gravar numeros iguais?

estou tentando usar o @UniqueConstraint(columnNames = { “cpf” }), mas o eclipse não aceita, está como se faltasse especificar algo.

{Vlw}

G

Conte para nós como você resolveu, assim ajuda alguém que no futuro tenha o mesmo problema.

Isso você resolve ou fazendo um select antes de incluir/editar ou então criando uma unique-key no JPA ou no banco de dados.

Você precisa ler melhor os erros. Provavelmente ele diz “annotation it’s not allowed here”. Vocẽ deve usar um @Table na sua entidade, abaixo de onde você declara @Entity assim:

Abraços

mdbatera

Tranquilo,

Na primeira vez que substitui o arquivo vraptor-3.1.2, pelo http://oss.sonatype.org/content/repositories/snaps…or-3.1.3-20100519.161626-7.jar, e testei, deu e problema porque não tinha apagado os arquivos:

# validation-api*.jar  
# hibernate-validator-4.*.jar

Assim que apaguei os arquivos e coloquei o snap, funcionou perfeitamente.

Muito Obrigado!

mdbatera

Bem, para evitar que os campos se repitam, eu apliquei na coluna da tabela:

ALTER IGNORE TABLE `cliente` ADD UNIQUE INDEX(email);

Agora o mysql evita que se repita registros, porém como trato isso no Hibernate/Vraptor?

Vlw

Lucas_Cavalcanti

o unique constraint no @Table ou @Column(unique=true) deveria ser suficiente… se vc estiver com a propriedade hibernate.hbm2ddl.auto = update no seu hibernate.cfg.xml ou no hibernate.properties

G

Se você apagou esses arquivos, o vraptor não ativa a validação.

Lucas_Cavalcanti

ativa sim, se vc estiver com o jar do hibernate validator 3…

mdbatera

Eu coloquei:

@Column(unique=true)
	@NotEmpty(message="Favor informar CPF")
	@CPF(message="CPF Inválido")
	private String cpf;

E no hibernate.properties:

hibernate.dialect org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost/fj21
hibernate.connection.username root
hibernate.connection.password
hibernate.hbm2ddl.auto = update

E o formulário registrou outro campo com o cpf igualzinho, o que pode ser??

Lucas_Cavalcanti

tem que ver se ele modificou a tabela mesmo… tire o “=”, deixe só:

hibernate.hbm2ddl.auto update
mdbatera

Anotei a classe,

@Column(unique=true)
@NotEmpty(message="Favor informar CPF")
@CPF(message="CPF Inválido")
private String cpf;

Consertei o properties,

hibernate.dialect org.hibernate.dialect.MySQLDialect
hibernate.connection.driver_class com.mysql.jdbc.Driver
hibernate.connection.url jdbc:mysql://localhost/fj21
hibernate.connection.username root
hibernate.connection.password
hibernate.hbm2ddl.auto update

e aí:

22:22:09,046 DEBUG [VRaptor             ] VRaptor received a new request
22:22:09,050 DEBUG [DefaultRequestExecution] executing stack  DefaultRequestExecution
22:22:09,068 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ResourceLookupInterceptor
22:22:09,069 DEBUG [DefaultResourceTranslator] trying to access /cliente/adiciona
22:22:09,069 DEBUG [DefaultResourceTranslator] found resource [DefaultResourceMethod: ClienteController.adicionaClienteController.adiciona(Cliente)]
22:22:09,071 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor FlashInterceptor
22:22:09,073 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor InterceptorListPriorToExecutionExtractor
22:22:09,075 DEBUG [InstantiatedInterceptorHandler] Invoking interceptor LoginInterceptor
22:22:09,075 DEBUG [InstantiatedInterceptorHandler] Invoking interceptor InstantiateInterceptor
22:22:09,086 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ParametersInstantiatorInterceptor
22:22:09,086 DEBUG [OgnlParametersProvider] Applying cliente.dataNascimento with [22/05/2010]
22:22:09,088 DEBUG [OgnlParametersProvider] Applying cliente.email with [[email removido]]
22:22:09,089 DEBUG [OgnlParametersProvider] Applying cliente.senha with [md]
22:22:09,089 DEBUG [OgnlParametersProvider] Applying cliente.cpf with [8105*****]
22:22:09,089 DEBUG [OgnlParametersProvider] Applying cliente.nome with [marcio]
22:22:09,089 DEBUG [OgnlParametersProvider] Applying cliente.login with [md]
22:22:09,090 DEBUG [ParanamerNameProvider] Found parameter names with paranamer for ClienteController.adiciona(Cliente) as [cliente]
22:22:09,090 DEBUG [ParametersInstantiatorInterceptor] Parameter values for [DefaultResourceMethod: ClienteController.adicionaClienteController.adiciona(Cliente)] are [br.com.caelum.produtos.modelo.Cliente@b00ec2]
22:22:09,098 DEBUG [ToInstantiateInterceptorHandler] Invoking interceptor ExecuteMethodInterceptor
22:22:09,098 DEBUG [ExecuteMethodInterceptor] Invoking ClienteController.adiciona(Cliente)
22:22:09,098 DEBUG [ValidatorLocator    ] Creating hibernate validator locator for br.com.caelum.produtos.modelo.Cliente
24/05/2010 22:22:09 org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet default threw exception
br.com.caelum.vraptor.InterceptionException: an exception was raised while executing resource method
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:86)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ParametersInstantiatorInterceptor.intercept(ParametersInstantiatorInterceptor.java:77)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InstantiateInterceptor.intercept(InstantiateInterceptor.java:42)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.produtos.interceptor.LoginInterceptor.intercept(LoginInterceptor.java:30)
	at br.com.caelum.vraptor.core.InstantiatedInterceptorHandler.execute(InstantiatedInterceptorHandler.java:47)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.InterceptorListPriorToExecutionExtractor.intercept(InterceptorListPriorToExecutionExtractor.java:46)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.FlashInterceptor.intercept(FlashInterceptor.java:81)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.interceptor.ResourceLookupInterceptor.intercept(ResourceLookupInterceptor.java:67)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:54)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.ToInstantiateInterceptorHandler.execute(ToInstantiateInterceptorHandler.java:56)
	at br.com.caelum.vraptor.core.DefaultInterceptorStack.next(DefaultInterceptorStack.java:65)
	at br.com.caelum.vraptor.core.DefaultRequestExecution.execute(DefaultRequestExecution.java:70)
	at br.com.caelum.vraptor.VRaptor$1.insideRequest(VRaptor.java:92)
	at br.com.caelum.vraptor.ioc.spring.SpringProvider.provideForRequest(SpringProvider.java:56)
	at br.com.caelum.vraptor.VRaptor.doFilter(VRaptor.java:89)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
	at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
	at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
	at java.lang.Thread.run(Unknown Source)
Caused by: org.hibernate.exception.ConstraintViolationException: could not insert: [br.com.caelum.produtos.modelo.Cliente]
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:94)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
	at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:64)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2176)
	at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2656)
	at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
	at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
	at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
	at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
	at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
	at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
	at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
	at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
	at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:563)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:551)
	at org.hibernate.impl.SessionImpl.save(SessionImpl.java:547)
	at br.com.caelum.produtos.dao.ClienteDao.adiciona(ClienteDao.java:20)
	at br.com.caelum.produtos.controller.ClienteController.adiciona(ClienteController.java:35)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at br.com.caelum.vraptor.interceptor.ExecuteMethodInterceptor.intercept(ExecuteMethodInterceptor.java:57)
	... 40 more
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '81056*******' for key 'cpf'
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
	at java.lang.reflect.Constructor.newInstance(Unknown Source)
	at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
	at com.mysql.jdbc.Util.getInstance(Util.java:381)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
	at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)
	at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)
	at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
	at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
	at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2648)
	at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2077)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2362)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2280)
	at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:2265)
	at org.hibernate.id.IdentityGenerator$GetGeneratedKeysDelegate.executeAndExtract(IdentityGenerator.java:94)
	at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:57)
	... 62 more
Lucas_Cavalcanti

bom, tá certo :wink: era esse erro que tinha que dar…
isso não é uma validação, é uma constraint do banco…

vc pode ou se prevenir desse erro, verificando se existe um cara com o mesmo cpf no banco, e adicionando um erro de validação se for o caso… ou dar um try…catch em ConstraintViolationException (se eu não me engano a exception q deu estende dessa) e adicionar o erro de validação ou dar outro tipo de erro

mdbatera

Seria isso? rsrs …

public void adiciona(Cliente cliente){
		try{
		validator.validate(cliente); 
		validator.onErrorUse(page()).of(ClienteController.class).cadastracliente();
		new ClienteDao().adiciona(cliente);
		result.include("mensagem", "Cliente cadastrado com sucesso");
		result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();			
		
           }catch (Exception e) {
			
		}
			
		
	}

Se puder me dar uma força!

Obrigado !

mdbatera

Já consegui Lucas obrigado!

Segue o codigo:

public void adiciona(Cliente cliente){
		try{
		validator.validate(cliente); 
		validator.onErrorUse(page()).of(ClienteController.class).cadastracliente();
		new ClienteDao().adiciona(cliente);
		result.include("mensagem", "Cliente cadastrado com sucesso");
		result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();						
		}catch (ConstraintViolationException e) {
			result.include("mensagem", "Usuário já registrado");
			result.use(Results.logic()).redirectTo(ClienteController.class).cadastracliente();
		}
		
	}

Abraços!

G

Esqueci que o Stella usa Hibernate Validator 3. :smiley:

mdbatera

Agora que fiz o cadastro certinho com validação e tal, gostaria de fazer aquele esquema de confirmar a inscrição por e-mail, sabe por onde começo?

Valeu

Lucas_Cavalcanti

vc vai ter que gerar um hash para o usuário (uma chave talvez aleatória), mandar um link pra ele com esse hash…

daí qdo ele clicar nesse link, vc compara pra ver se o hash eh o mesmo e ativa a conta dele

mdbatera

é, acho que terei que preferir mandar um e-mail pra ele informando senha e login, mas como é que inicio esse processo com o javamail no vraptor?! nunca fiz isso, tou perdidão!

Baixo a api do java mail, coloco no controller ou o vraptor já tem alguma coisa que facilite o processo?

Lucas_Cavalcanti

o código pra enviar emails é algo parecido com o que tá nesse link:

http://developer.apple.com/internet/java/examples/mailjava.html

só que vc pode fazer isso dentro de um controller do vraptor, e vc pode colocar esse código separado em uma classe que envia emails…

não tem nada de especial que vc tenha que fazer

mdbatera

Muito bom, mas utilizando esse essa classe, como eu chamo ele no controler?!

Ví que ela está escrevendo HTML e tudo, nem preciso disso, só que envie a menssagem mesmo.

Valeu!

package br.com.caelum.produtos.email;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class SendMail extends HttpServlet {

    /**
	 * *
	 */
	private static final long serialVersionUID = 1L;

	public void doPost(HttpServletRequest request,
                       HttpServletResponse response)
        throws IOException, ServletException
    {
        PrintWriter writer = response.getWriter();
        response.setContentType("text/html");
        writer.println("<html><head><title>Mail Example</title></head>");
        writer.println("<body bgcolor=\"white\">");
        writer.println("<h1>Mail Example</h1>");

        ///////// set this variable to be your SMTP host
 
       String mailHost = "your.smtp.server";

        ///////// set this variable to be your desired email recipient

        String to = "[email removido]";

        // these variables come from the mail form

        String from = request.getParameter("from");
        String subject = request.getParameter("subject");
        String body = request.getParameter("body");

        if ((from != null) && (to != null) && (subject != null)  && (body != null)) // we have mail to send
        {

        try {


            //Get system properties
            Properties props = System.getProperties();

            //Specify the desired SMTP server
            props.put("mail.smtp.host", mailHost);

            // create a new Session object
            Session session = Session.getInstance(props,null);

            // create a new MimeMessage object (using the Session created above)
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipients(Message.RecipientType.TO, new InternetAddress[] { new InternetAddress(to) });
            message.setSubject(subject);
            message.setContent(body, "text/plain");

            Transport.send(message);

            // it worked!
            writer.println("<b>Thank you.  Your message to " + to + " was successfully sent.</b>");

        } catch (Throwable t) {

            writer.println("<b>Unable to send message: <br><pre>");
            t.printStackTrace(writer);
            writer.println("</pre></b>");
        }


        }
        else
        {
            // no mail to send. print a blank mail form
            writer.println("<form action=\"/mine/mail\" method=\"POST\">");
            writer.println("<table border=\"0\">");
            writer.println("<tr><td>Message From: </td><td><input type=\"text\" name=\"from\"></td></tr>");
            writer.println("<tr><td>Subject: </td><td><input type=\"text\" name=\"subject\"></td></tr>");
            writer.println("<tr><td valign=\"top\">Message: </td><td><textarea name=\"body\" rows=\"10\" cols\"40\"></textarea></td></tr>");
            writer.println("<tr><td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"Send\"></td></tr>");
            writer.println("</table>");
            writer.println("</form>");
        }


        writer.println("</body>");
        writer.println("</html>");        

    }

    // doGet() just calls doPost()

    public void doGet(HttpServletRequest request,
                       HttpServletResponse response)
        throws IOException, ServletException
    {
        doPost(request, response);
    }
}
Lucas_Cavalcanti

o código de enviar email é o do meio (entre a parte de parsear os parâmetros e escrever o html, que o vraptor faz pra vc)
o controller seria algo do tipo:

@Resource
public class EmailController {

    public void envia(String from, String to, String subject,  String body) {
//Get system properties
            Properties props = System.getProperties();

            //Specify the desired SMTP server
            props.put("mail.smtp.host", mailHost);

            // create a new Session object
            Session session = Session.getInstance(props,null);

            // create a new MimeMessage object (using the Session created above)
            Message message = new MimeMessage(session);
            message.setFrom(new InternetAddress(from));
            message.setRecipients(Message.RecipientType.TO, new InternetAddress[] { new InternetAddress(to) });
            message.setSubject(subject);
            message.setContent(body, "text/plain");

            Transport.send(message);

    }

}

e vc precisa substituir o mailHost por um servidor SMTP qualquer (possivelmente instalado na sua máquina)

mdbatera

olha como ficou minha classe:

package br.com.caelum.produtos.controller;

import java.util.Properties;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;


public class EmailController {
	   
	public  void envia(String from, String to, String subject,  String body) {  
		   
		             Properties props = System.getProperties();  
		   
		             
		             props.put("mail.host", "smtp2.locaweb.com.br"); 
		   
		            
		             Session session = Session.getInstance(props,null);  
		  
		             Message message = new MimeMessage(session);  
		             
		             try{
		             message.setFrom(new InternetAddress(from));  
		             message.setRecipients(Message.RecipientType.TO, new InternetAddress[] { new InternetAddress(to) });  
		             message.setSubject(subject);  
		             message.setContent(body, "text/plain");  
		   
		             Transport.send(message);  
		             }catch (AddressException e) {
						
					}catch (MessagingException e) {
						
					}
		   
		     }  
}

Como disparo a mensagem assim que adiciono o usuario no meu controller ?

Rapaz, passei o dia tentando fazer um servidor smtp aqui, não indicaria algum programa que fizesse isso de maneira simples e direta!?, tentei configurar o Mercury do Xampp e nada, só queria poder testar minha aplicação… rsrsrs

G

Isso já não tem mais nada a ver com o vraptor.

Creio que o ideal é você ler a documentação do Javamail (http://java.sun.com/products/javamail/) e também postar as dúvidas referente a isso no respectivo subfórum (acho que Ferramentas, Frameworks e Utilitários).

Há também vários artigos sobre como criar classes para envio de emails, configurar servidor, etc…

http://www.google.com.br/search?q=javamail

Lucas_Cavalcanti

vc só precisa chamar esse método após adicionar o usuário…

só tome cuidado pq isso pode demorar ou falhar…

G

Há uma gambiarra que ví em um projeto que o pessoal fazia uma classe MailSender que estendia Thread, assim você pode disparar o email em background liberando a tela. Porém assim você não consegue mais saber se o tal email foi ou não enviado.

Caso o servidor de email esteja fora da rede na qual o projeto vai rodar o mais indicado é usar um processo em batch ou até um serviço de mensageria. Nos projetos que preciso de envio de emails normalmente faço o insert na base de dados com todos os dados do email. Depois um EJB Scheduler lê de tempos em tempos a tabela e tenta enviar os emails, gerando um log do envio.

Criado 24 de maio de 2010
Ultima resposta 27 de mai. de 2010
Respostas 40
Participantes 4