| Autor |
Mensagem |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/09/2010 01:07:32
|
victorwss
JWizard
![[Avatar]](/images/avatar/4ab232445f9b21b65dfdf6ea5f27f704.png)
Membro desde: 18/12/2007 14:46:00
Mensagens: 2409
Localização: São Paulo - SP
Offline
|
Olá, tenho uma dúvida avançada sobre o VRaptor. Não sei ao certo se estamos esbarrando em uma limitação dele ou se apenas o estamos usando de forma errada.
Aqui vai a controller inicial:Isso funciona perfeitamente. No entanto não estamos satisfeitos e gostaríamos que os parâmetros fossem do tipo Usuario. Lá vai a primeira tentativa:Isto falha miseravelmente. O VRaptor não pesquisa a entidade no banco de dados, o que ele faz é instanciar o Usuario e chamar os setters.
Esta outra tentativa é mais feliz:
E para que o VRaptor saiba como instanciar o usuário, usamos isso:E então, até aqui, a controller funciona como esperado.
No entanto, quando eu uso o metodo outroMetodo, que tem um redirectTo, o VRaptor gera umas URLs assim:
/meuprojeto/br.com.teste.Usuario@45f7e2/perfil
Apesar de a conversão de ida String->Usuario ter usado o Converter, a conversão de volta Usuario->String sempre usa o método toString().
Utilizar o método toString() sempre é muito restritivo, pois ele já é utilizado para outras finalidades.
Para contornar este problema, existem algumas soluções possíveis. Mas todas elas são meio gambiarrosas.
A primeira delas é criar um Router herdando de DefaultRouter e sobreescrever o método urlFor por um quase idêntico, mas com uma diferença:É substituído por:Este código é uma gambiarra grotesca, que consiste em consertar a URL errada que foi gerada.
Para tentar fazer um código menos gambiarroso, analisamos que a variável matches é do tipo Iterator<Route> e a implementação concreta de Route é FixedMethodStrategy.
O Iterator<Route> é criado pela classe PathAnnotationRoutesParser, que por sua vez utiliza a RouteBuilder. RouteBuilder instancia a FixedMethodStrategy, injetando nela uma instância de DefaultParametersControl.
O método fillUri(Object) de DefaultParametersControl utiliza o método toString() e é aí que é a origem do problema.
A classe PathAnnotationRoutesParser está fortemente acoplada a RouteBuilder, que por sua vez está fortemente acoplada a FixedMethodStrategy e a DefaultParametersControl, o que significa que substituir a implementação de alguma destas classes por outra coisa é algo difícil.
Uma outra possibilidade mais atraente para resolver isso sem precisar desta gambiarra seria criar uma espécie de decorator de Route e fazer o matcher conter instâncias apenas do decorator. Mas isso continua sendo algo trabalhoso.
Então vem a minha pergunta: Estamos usando o VRaptor de uma forma inadequada ou não prevista? Caso seja inadequada, eu devo me contentar em receber apenas Strings e números como parâmetros extraídos da URL e devo deixar coisas mais complexas apenas para dados de formulários? Caso contrário, gostaria de sugerir uma nova interface para um "Converter reverso", e então o meu converter ficaria assim:Essa interface hipotética ReverseConverter resolveria este tipo de problema.
This message was edited 1 time. Last update was at 01/09/2010 01:07:59
|
Victor Williams Stafusa da Silva
Bacharel em Ciência da Computação - UFMT // Especialista em Desenvolvimento Java - CEFET/MT // Doutorando em Ciência da Computação - IME-USP
SCJP 6.0 - 19/12/2007 - PASS - 88% // SCWCD 5 - 17/05/2008 - PASS - 79% // SCJA - 09/09/2008 - PASS - 96% // SCSNI - 30/06/2009 - PASS - 68% // SCBCD 5 - 31/05/2010 - PASS - 95%
Próximos: SCJD (encalhado com o projeto), SCEA parte I (estudando). Algum dia desses: SCMAD, OCA, SCEA e SCDJWS.
Computação: uma ciência holística e esotérica!
E então veio Deus a terra e disse aos homens: Não dividireis por zero.
XML is a giant step in no direction at all. (Erik Naggum)
Arquitetura de sistemas: Eu prefiro ser essa metamorfose ambulante do que ter aquela velha opinião formada sobre tudo.
Diga não as drogas: Não use java.util.Vector.
Cuidado: Este usuário pode ter temperamento agressivo.
Always code as if the person who will maintain your code is a maniac serial killer that knows where you live.
I am the maniac serial killer that knows where you live who will maintain your code.
É impossível falar de CMMI (Capability Maturity Model Integration) sem saber o que é CIMM (Capability Im-Maturity Model).
Se você escreve "concerteza", "concerteza" você andou matando aulas de português. |
|
|
 |
|
|
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/09/2010 09:42:26
|
dev.rafael
Virtual Machine Man
![[Avatar]](/images/avatar/0cba576cd16d0f399c78c557b4899a58.png)
Membro desde: 17/09/2007 01:35:27
Mensagens: 631
Offline
|
Cara, eu não tenho muita experiência com VRaptor mas, até onde eu me lembro, ele não requer conversão de objetos para
Strings (como JSF) posto que você mesmo renderiza a página usando JSP.
O código ai de cima não funciona?
Esquece isso. O que eu falei não tem nada a ver!!
This message was edited 1 time. Last update was at 01/09/2010 09:48:05
|
"A mente humana é limitada, mas a estupidez é ilimitada." Wilhelm Steinitz |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/09/2010 15:36:17
|
pbnf
JavaGuru
Membro desde: 18/06/2003 12:06:55
Mensagens: 228
Localização: De volta a Cuiabá-MT, 40º na sombra !!!
Offline
|
Olá Armadilha,
Como vc explicou muito bem o seu problema eu vou ser mais curto, leia http://vraptor.caelum.com.br/documentacao/resources-rest/
OBS:
- Não ha necessidade de colocar no @Path o contexto da aplicação.
Isto falha miseravelmente. O VRaptor não pesquisa a entidade no banco de dados, o que ele faz é instanciar o Usuario e chamar os setters.
- O vraptor não sabe que existe banco de dados, e o comportamento por padrão dele é instaciar o objeto e popular e te entregar pronto no controller.
This message was edited 2 times. Last update was at 01/09/2010 15:41:11
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/09/2010 16:08:17
|
Lucas Cavalcanti
GUJ Hacker
![[Avatar]](/images/avatar/5f6780632f5d27dd0cded5fc9361169e.jpg)
Membro desde: 08/07/2007 00:08:14
Mensagens: 6395
Offline
|
@victorwss
isso de usuario.login só usar os setters é o comportamento esperado do VRaptor mesmo. Ele não tem como saber qual é o seu banco de dados ou como vc quer buscar o Usuario no banco
De qqer forma achei muito interessante a sua abordagem de converters! Não tinha pensado nessa possibilidade, e acho que vale a pena fazer isso funcionar e escrever na documentação do VRaptor uma receita (http://vraptor.caelum.com.br/cookbook)
detalhes:
- o seu converter deveria ser request scoped se o seu dao for request scoped (escopo padrão).
- concordo que o acoplamento das classes PathAnnotationRoutesParser, RoutesBuilder e ParametersControl está bastante alta... criei uma issue para refatoração: http://github.com/caelum/vraptor/issues/issue/239
- vcs não estão usando errado, é só uma forma não prevista mesmo...
de qqer forma, vou tentar criar essa interface ReverseConverter e fazer ela funcionar, e já te mando um snapshot pra vc testar =)
Muito obrigado pelo Hack
|
--
Caelum
www.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/09/2010 16:42:17
|
garcia-jj
JWizard
Membro desde: 13/04/2009 22:11:50
Mensagens: 2715
Localização: Porto Alegre
Offline
|
Isto falha miseravelmente. O VRaptor não pesquisa a entidade no banco de dados, o que ele faz é instanciar o Usuario e chamar os setters.
Mas hein?!
Lucas Cavalcanti wrote:De qqer forma achei muito interessante a sua abordagem de converters! Não tinha pensado nessa possibilidade, e acho que vale a pena fazer isso funcionar e escrever na documentação do VRaptor uma receita ( http://vraptor.caelum.com.br/cookbook)
Eu também gostei, e nunca tinha pensado nessa prossibilidade. Porém acho que ao invés de ReverseConverter poderiamos alterar o atual converter para ser bidirecional, estilo o XmlAdapter do JAXB.
This message was edited 1 time. Last update was at 01/09/2010 16:44:46
|
http://github.com/garcia-jj
Não respondo dúvidas via MP. Use o fórum. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/09/2010 16:48:36
|
Lucas Cavalcanti
GUJ Hacker
![[Avatar]](/images/avatar/5f6780632f5d27dd0cded5fc9361169e.jpg)
Membro desde: 08/07/2007 00:08:14
Mensagens: 6395
Offline
|
garcia-jj wrote:
Eu também gostei, e nunca tinha pensado nessa prossibilidade. Porém acho que ao invés de ReverseConverter poderiamos alterar o atual converter para ser bidirecional, estilo o XmlAdapter do JAXB.
to criando um TwoWayConverter extends Converter
|
--
Caelum
www.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 01/09/2010 20:07:45
|
Lucas Cavalcanti
GUJ Hacker
![[Avatar]](/images/avatar/5f6780632f5d27dd0cded5fc9361169e.jpg)
Membro desde: 08/07/2007 00:08:14
Mensagens: 6395
Offline
|
criado o snapshot =)
https://oss.sonatype.org/content/repositories/snapshots/br/com/caelum/vraptor/3.2.0-SNAPSHOT/vraptor-3.2.0-20100901.225614-2.jar
o nome da interface é a TwoWayConverter (que estende Converter), pode testar pra mim por favor @victorwss ?
|
--
Caelum
www.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 03:26:35
|
victorwss
JWizard
![[Avatar]](/images/avatar/4ab232445f9b21b65dfdf6ea5f27f704.png)
Membro desde: 18/12/2007 14:46:00
Mensagens: 2409
Localização: São Paulo - SP
Offline
|
pbnf wrote:
- O vraptor não sabe que existe banco de dados, e o comportamento por padrão dele é instaciar o objeto e popular e te entregar pronto no controller.
Lucas Cavalcanti wrote:
isso de usuario.login só usar os setters é o comportamento esperado do VRaptor mesmo. Ele não tem como saber qual é o seu banco de dados ou como vc quer buscar o Usuario no banco
garcia-jj wrote:Mas hein?!
Eu sei que o VRaptor não conhece o banco e que aquilo não daria certo nunca. Acho que não me expressei direito, o que eu queria dizer é que a primeira ideia ingênua para resolver é aquela, mas ela falha pelo motivo óbvio que todos aqui sabem: O VRaptor não conhece o banco de dados e mesmo se conhecesse ele não teria informação suficiente para fazer aquilo, a semântica que ele usa é sempre instanciar o bean e chamar os setters e nunca fazer uma busca em algum lugar por um bean já existente. E é este um dos motivos pelo qual usamos os converters.
Lucas Cavacanti wrote:
- o seu converter deveria ser request scoped se o seu dao for request scoped (escopo padrão).
Obrigado. Você descobriu um bug obscuro na nossa aplicação que dificilmente iríamos perceber.
Lucas Cavalcanti wrote:
criado o snapshot =)
Obrigado. Vou brincar com ele um pouco e depois eu digo o que aconteceu.
Bem, uma observação que tenho que fazer, para que vocês fiquem cientes e coloquem no cookbook, é que se o bean for acessado na URL por duas ou mais formas diferentes de acordo com casos específicos (ex: em um lugar eu uso o id do usuário, em outro lugar o login, e em outro o CPF), é responsabilidade do converter lidar com isso, o que tende a ser bem complicado, e por este motivo deve ser fortemente recomendado que o acesso a um determinado bean na URL seja uniforme. Com algum tipo de converter mais complexo seria mais fácil suportar este caso, mas acho que não vale a pena. De qualquer forma gostaria que pensassem um pouco neste aspecto.
Pbnf, sei que te conheço pessoalmente, mas pelo seu nick não dá para saber quem você é. Poderia me dizer o teu nome real?
Obrigado a todos
|
Victor Williams Stafusa da Silva
Bacharel em Ciência da Computação - UFMT // Especialista em Desenvolvimento Java - CEFET/MT // Doutorando em Ciência da Computação - IME-USP
SCJP 6.0 - 19/12/2007 - PASS - 88% // SCWCD 5 - 17/05/2008 - PASS - 79% // SCJA - 09/09/2008 - PASS - 96% // SCSNI - 30/06/2009 - PASS - 68% // SCBCD 5 - 31/05/2010 - PASS - 95%
Próximos: SCJD (encalhado com o projeto), SCEA parte I (estudando). Algum dia desses: SCMAD, OCA, SCEA e SCDJWS.
Computação: uma ciência holística e esotérica!
E então veio Deus a terra e disse aos homens: Não dividireis por zero.
XML is a giant step in no direction at all. (Erik Naggum)
Arquitetura de sistemas: Eu prefiro ser essa metamorfose ambulante do que ter aquela velha opinião formada sobre tudo.
Diga não as drogas: Não use java.util.Vector.
Cuidado: Este usuário pode ter temperamento agressivo.
Always code as if the person who will maintain your code is a maniac serial killer that knows where you live.
I am the maniac serial killer that knows where you live who will maintain your code.
É impossível falar de CMMI (Capability Maturity Model Integration) sem saber o que é CIMM (Capability Im-Maturity Model).
Se você escreve "concerteza", "concerteza" você andou matando aulas de português. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 11:30:56
|
Lucas Cavalcanti
GUJ Hacker
![[Avatar]](/images/avatar/5f6780632f5d27dd0cded5fc9361169e.jpg)
Membro desde: 08/07/2007 00:08:14
Mensagens: 6395
Offline
|
victor, só um adendo:
qdo vc coloca @Path("/users/{user.id}") o VRaptor sabe que o id é número, por exemplo, e só deixa colocar números nessa parte da url. Se vc coloca @Path("/users/{user}") o VRaptor vai aceitar qqer coisa.
Então vc teria que falar que só pode aceitar números: @Path("/users/{user:\\d+}")...
Você quer escrever o cookbook, já que a idéia é sua? A gente coloca com o seu nome no site do VRaptor.
[]'s
|
--
Caelum
www.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 13:10:09
|
Paulo Silveira
Administrador
![[Avatar]](/images/avatar/a87ff679a2f3e71d9181a67b7542122c.jpg)
Membro desde: 07/08/2002 18:38:50
Mensagens: 4204
Localização: São Paulo
Offline
|
Oi Victor! Foi uma excelente ideia. Valeu Lucas pelas implementacao para permitir isso. Parabens aos dois.
|
http://blog.caelum.com.br twitter: @paulo_caelum
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 18:42:26
|
Spidey
Thread.start()
Membro desde: 27/08/2010 17:08:27
Mensagens: 30
Offline
|
Se não me engano, por um acaso trabalho com o victorwss, e foi com o código que ele também fez que eu to aprendendo VRaptor (além da documentação do site né, mas aprender por exemplo auxilia bastante).
De início eu achava que o VRaptor chamava o construtor correto. Será que não dá pra fazer isso sem utilizar um converter?
Pensei no próprio VRaptor identificando um campo numérico, por exemplo, e chamando um construtor.
Por exemplo, eu chamo
Outra coisa que podia rolar é usar um ${parametro#tipo}, de forma que o valor dessa variável seria usado na chamada do construtor em "new MinhaClasse(tipo);".
Não sei se fui claro, qualquer coisa eu tento explicar de outra forma.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 18:49:51
|
Lucas Cavalcanti
GUJ Hacker
![[Avatar]](/images/avatar/5f6780632f5d27dd0cded5fc9361169e.jpg)
Membro desde: 08/07/2007 00:08:14
Mensagens: 6395
Offline
|
tem como fazer isso habilitando o IOGI no VRaptor...
assim se vc tiver:
e fizer
ele vai instanciar usando o construtor, com o tipo certo (só vai aceitar numeros).
para habilitar o IOGI, coloque no web.xml:
e coloque o jar do iogi no WEB-INF/lib. Pode tirar o ognl do lib se quiser depois de fazer isso.
mais info: http://vraptor.caelum.com.br/documentacao/componentes-utilitarios-opcionais/
o problema do victor não era instanciar pelo construtor, e sim já carregar do banco.
This message was edited 1 time. Last update was at 02/09/2010 18:50:31
|
--
Caelum
www.caelum.com.br
 |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 21:08:56
|
Spidey
Thread.start()
Membro desde: 27/08/2010 17:08:27
Mensagens: 30
Offline
|
Como minha aplicação é simples, eu implementaria essa busca do banco direto no construtor do objeto, passa o id dele, chamo o dao e copio os campos objeto que o dao retorno pra instância.
|
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 21:25:49
|
victorwss
JWizard
![[Avatar]](/images/avatar/4ab232445f9b21b65dfdf6ea5f27f704.png)
Membro desde: 18/12/2007 14:46:00
Mensagens: 2409
Localização: São Paulo - SP
Offline
|
Lucas e Paulo, testei o TwoWayConverter e funcionou perfeitamente.
Posso sim escrever o cookbook. Mas não entendi essa de colocar regex na URL. Poderia explicar melhor? Eu pessoalmente preferiria colocar este tipo de validação no Converter.
This message was edited 1 time. Last update was at 02/09/2010 21:28:03
|
Victor Williams Stafusa da Silva
Bacharel em Ciência da Computação - UFMT // Especialista em Desenvolvimento Java - CEFET/MT // Doutorando em Ciência da Computação - IME-USP
SCJP 6.0 - 19/12/2007 - PASS - 88% // SCWCD 5 - 17/05/2008 - PASS - 79% // SCJA - 09/09/2008 - PASS - 96% // SCSNI - 30/06/2009 - PASS - 68% // SCBCD 5 - 31/05/2010 - PASS - 95%
Próximos: SCJD (encalhado com o projeto), SCEA parte I (estudando). Algum dia desses: SCMAD, OCA, SCEA e SCDJWS.
Computação: uma ciência holística e esotérica!
E então veio Deus a terra e disse aos homens: Não dividireis por zero.
XML is a giant step in no direction at all. (Erik Naggum)
Arquitetura de sistemas: Eu prefiro ser essa metamorfose ambulante do que ter aquela velha opinião formada sobre tudo.
Diga não as drogas: Não use java.util.Vector.
Cuidado: Este usuário pode ter temperamento agressivo.
Always code as if the person who will maintain your code is a maniac serial killer that knows where you live.
I am the maniac serial killer that knows where you live who will maintain your code.
É impossível falar de CMMI (Capability Maturity Model Integration) sem saber o que é CIMM (Capability Im-Maturity Model).
Se você escreve "concerteza", "concerteza" você andou matando aulas de português. |
|
|
 |
![[Post New]](/templates/default/images/icon_minipost_new.gif) 02/09/2010 21:36:19
|
Lucas Cavalcanti
GUJ Hacker
![[Avatar]](/images/avatar/5f6780632f5d27dd0cded5fc9361169e.jpg)
Membro desde: 08/07/2007 00:08:14
Mensagens: 6395
Offline
|
eh que é assim, suponha que user.id é um número
se o path eh @Path("/users/{user.id}"), a URI /users/banana dá 404 direto, nem passa por nada...
se vc colocar @Path("/users/{user}") tudo vai passar pelo converter
se vc colocar @Path("/users/{user:\\d+}") só vai bater URIs que sejam números /users/234, /users/1, etc... se for /users/asdf é 404 direto tb...
o que vc deveria fazer tb é: se o usuario com o id passado não existir no banco, dar 404 direto. Então a gente precisa ver um jeito fácil de fazer isso. Alguma sugestão?
|
--
Caelum
www.caelum.com.br
 |
|
|
 |
|
|