Ontem fui na palestra do Nico Steppat (da Caelum) sobre JBoss Seam no RioJUG. A palestra foi interessante, mas infelizmente não deu tempo pra ele mostrar tudo, e eu não vi muita coisa além do que eu já sabia.
Entretanto, um ponto destacado por ele me deixou ligado em um recurso interessante. Como ele mencionou, o Seam busca ajudar bastante em aplicações que precisam de estado, como um carrinho de compras. A proposta é de ser uma camada de ligação entre componentes stateful do JSF e EJBs stateful.
JSF não é dos frameworks que eu mais goste, mas realmente essa característica utilizada pelo Seam faz sentido em alguns dos projetos que eu participei. Por exemplo, alguns casos de uso envolvem fluxos com algumas telas, e é necessário guardar os dados ao longo do fluxo de um caso de uso. Entretanto, muitas vezes não é necessário que os dados permaneçam disponíveis para outro caso de uso, então o escopo de sessão é maior do que esta necessidade específica.
Este escopo do qual estamos falando é o escopo de conversação, e eu já sabia que o JSF oferecia algo neste sentido, mas eu não tinha ainda parado pra pensar muito sobre isso. Os dados neste escopo têm o ciclo de vida igual ao de uma conversação, que mapeia bem o fluxo de um caso de uso.
No caso do Seam, ele faz uso deste escopo de conversação para 2 coisas principais. Ele consegue manter os dados vivos por vários requests sem usar o HttpSession, o que é positivo, pois sabemos que é difícil escalar o HttpSession. Além disso, ele resolve o problema de casos em que o usuário usa o back do browser e submete novamente os dados referentes a um fluxo que ele já havia concluído.
No último projeto que eu participei com formulários de mais de uma etapa, consegui resolver esse problema do back do browser com uma solução customizada simples. Quando eu criava as etapas eu criava um hash aleatório e associava a cada uma das etapas que o usuário fosse preencher. Dentro do formulário eu colocava um campo hidden contendo esse hash, e quando o usuário submetesse o formulário conseguiria identificar qual etapa ele estava preenchendo. No final da “conversação” eu limpava esses hashes das etapas que o usuário preencheu, e caso ele tentasse submeter novamente os dados, o hash não estaria mais presente e o submit não seria aceito.
Entretanto, neste projeto eu colocava os dados no HttpSession e destruía o HttpSession no final do fluxo. Nesta situação seria mais interessante usar esse escopo de conversação, pois eu deixaria de pendurar dados no HttpSession e pouparia recursos do servidor.
Felizmente eu verifiquei ontem mesmo que o Spring Web Flow também suporta esse escopo de conversação, e então fica para mim o dever de casa de conhecer o Web Flow e passar a utilizar essa abordagem. O Spring MVC é atualmente o meu framework web Java preferido, e foi ótimo saber que eu não precisaria de JSF para ter uma solução para este problema
Também estava na palestra ontem e achei interessante a solução de “conversação” pelos mesmos motivos.
Inclusive a questão de submeter o formulário mais de uma vez eu também resolvia com hash com input hidden.
Como nem programo em Java, surgiu uma dúvida em relação a ir e voltar dentro do fluxo, antes do end. Mas imagino que não seja um problema.
Abs
Diogo
Oi Diogo, em relação a ir e voltar dentro do fluxo não tem nenhum mistério não. Os dados que forem submetidos novamente são atualizados no escopo de conversação, e no final do fluxo ele são processados normalmente.