Uma das desvantagens de usar VRaptor é que sempre temos que digitar as URIs duas vezes - no controller e na view:
@Resource
public class ProdutoController {
@Post("/produtos/{id}")
public void visualiza(Long id) {...}
}
<a href="<c:url value="/produtos/${produto.id}"/>">${produto.nome}</a>
Assim, durante o desenvolvimento você precisa lembrar qual é a URI correta do método, sem garantia nenhuma de que ela é a certa - se por algum motivo mudarmos o path do método visualiza todos os links para ele quebram silenciosamente.
Para quem programa em Rails, existe uma solução para isso, um helper que gera os links dado um controller e um método:
<% link_to "Um produto", :controller => "produtos", :action => "visualiza", :id => 4 %>
Num projeto que eu estou desenvolvendo em VRaptor + Scala, com o Scalate como template engine, conseguimos chegar nisso:
${linkTo[ProdutoController](_.visualiza(3))} => /produtos/3
E ainda ganhando checagem estática: o template não vai compilar se não existir o método visualiza em ProdutoController, que recebe um número como parâmetro. Isso é possível porque no ssp conseguimos executar qualquer método scala, com a sintaxe padrão do scala.
Mas será que algo parecido com isso é possível com JSP?
O primeiro problema é que usando a EL padrão do JSP você não pode executar qualquer método de um objeto, somente getters. Executar métodos só criando uma Tag, ou sobrescrevendo o ELResolver - ambas soluções bastante trabalhosas.
Semana passada eu estava pareando com o Otávio Garcia, que é um grande contribuidor do VRaptor e estava visitando a Caelum, e a gente resolveu tentar encontrar uma solução para isso.
Chegamos nessa solução, sem criar tags nem sobrescrever o resolver:
${linkTo[ProdutoController].visualiza[3]}
Será que isso funciona? Será que é possível fazer isso retornar a URI "/produtos/3"?
Tem idéia de como fazer isso funcionar? Como seria? No próximo post eu explico qual foi a nossa solução, com pitadas de magia negra e técnicas interessantes. ;)
Estive pensando nisso outro dia. Aguardo ansioso pelo próximo post. abraço
Cara, idéia interessante! Muito bom
Se a solução já pegar o contexto ficará ainda melhor. (: Parabéns pelo blog. o/
Sim, a idéia é já retornar a URI pronta pra ser usada =)
Beleza Lucas? Estive estudando um pouco de Python e Django esses tempos. Descobri no Django recursos muito interessantes que resolvem esses problemas no desenvolvimento e que poderiam ser usados tb no VRaptor, veja. Usando o mesmo exemplo de visualização, na html ficaria: Visualizar E na urls.py: url(r'^funcionario/detail/(?P\d+)/$', views.detail, name="detail_proprietario"), Ele usa urls (path) nomeadas, repare o "name", ou seja, basta chamar o nome da url ao invés de chamar pelo caminho exato na html. Com isto, o método detail pode ser alterado que não irá afetar os outros links que estiverem usando o mesmo método. Se quiser dar uma olhada: https://docs.djangoproject.com/en/dev/topics/http/urls/#naming-url-patterns Grande abraço!
Olá, É uma funcionalidade bem interessante, daria para fazer algo nesse estilo também. Abre uma issue pra isso por favor? http://github.com/caelum/vraptor/issues Abraço
Lucas, abri uma issue lá, veja se ficou legal: https://github.com/caelum/vraptor/issues/368 Abraço!!
ficou sim, valeu =)
[...] partes 1 e 2 conseguimos fazer com que isso funcionasse manualmente: ${linkTo[ProdutoController].adiciona} [...]
Oi Lucas. Poxa, eu ví esse código nascendo na tela do teu notebook lá no Starbucks. Realmente tu és um ninja dos códigos. Já adicionei ao meu reader. Abraço.