Posts Tagged ‘Seam’

Não era mais uma receita de bolo JSF!

Thursday, June 5th, 2008

É incrível como depois do post Utilizando AJAX com JSF de maneira eficiente muitos desenvolvedores tem utilizado o exemplo básico do post -que nada mais era do que uma prova de conceito- como receita de bolo para criar aplicações sérias. Talvez eu não tenha sido claro, mas o intuito do post não era demonstrar um passo-a-passo de como desenvolver uma aplicação com alguns conjuntos de componentes, mas sim passar o conceito de como aproveitar melhor os recursos oferecidos pela tecnologia para criar aplicações mais ricas e leves.

Eu tentei ao máximo deixar claro que não eram os componentes X, Y ou Z que me forneciam recursos para implementar o conceito, como está bem claro nos trechos do post abaixo:

Utilizar um conjunto de componentes ricos e um framework AJAX. (Neste caso eu optei pelo Richfaces/Ajax4jsf por ser bastante simples de usar e integrar, por ser estável e por ser bastante utilizado na comunidade, contudo, qualquer outro conjunto de componentes AJAX poderia ser utilizado, como Trinidad ou mesmo o IceFaces);

E este,

Eu não me prendi a utilização dos frameworks ou conjuntos de componentes utilizados pois este não era o intuito do post, isso é algo simples e acredito que a maioria dos leitores não tenham dificuldades em relação a isso. Além do mais é possível implementar isso não somente com o Richfaces/Ajax4jsf, mas com qualquer outro framework ou conjuntos de componentes AJAX, por exemplo, [...]

Não é necessário utilizar Richfaces/Ajax4jsf, Tomahawk e Facelets para aproveitar os recursos da tecnologia de forma eficiente, você poderá conseguir isso com qualquer outro framework ou conjunto de componentes que te permitam unir AJAX e JSF de maneira prática, sejam eles Trinidad, JBoss Seam, IceFaces, Ajax4jsf, ADF Faces e/ou JSFTemplating.

Mais claro que isso é impossível.. porém ainda não acabou, um fato engraçado é que alguns desenvolvedores chegaram a se queixar de que eu fui muito radical ao dizer para desenvolverem toda uma aplicação em uma única página. Eu em nenhum momento disse ou mesmo insinuei isto, o que eu disse foi:

A idéia principal tem por objetivo evitar escrever muitas páginas para representar cada view (tela), diminuindo assim o número de páginas no projeto, o número de regras de navegação no faces-config.xml, diminuindo o overhead no servidor e no cliente a cada refresh de página, [...]

Vocês não precisam e provavelmente não deveriam implementar suas aplicações seguindo o exemplo do post, ele é básico, ele serve como referência, possui uma implementação simples e não se preocupa com alguns requisitos não funcionais como a paginação sob demanda ou quais os objetos que deveriam permanecer entre as requisições. Além do mais o exemplo é um CRUD, e não uma interface com o usuário mais complexa no sistema.

Entendam uma vez por todas que não existe uma arquitetura de referência ou receita de bolo para desenvolver sistemas, cada sistema possui suas necessidades e peculiaridades, e estas devem ser estudadas e analisadas para se chegar a uma solução plausível.

O importante é que vocês compreendam o conceito, seus prós e contras e principalmente onde e quando utiliza-lo. Não se prendam ao framework ou conjunto de componentes, a maioria deles hoje em dia te fornecem os recursos necessários para implementar a idéia sem muitas dificuldades.

Enfim, estudem, entendam, aprimorem, façam testes e implementem o conceito onde for necessário, com os componentes e frameworks cabíveis e sempre com bom senso.

Aproveitando os beans do Spring em suas páginas JSF

Sunday, February 24th, 2008

Esses dias estava tendo uma conversa bem produtiva com um amigo de trabalho, Tarso Bessa, o cara é muito safo em desenvolvimento e sempre me aparece com umas idéias bem bacanas. Nessa conversa ele chegou com uma idéia bem interessante sobre aproveitarmos a integração do Spring com JSF, a idéia se resume em aproveitar o variable resolver do Spring nas páginas JSF, assim poderíamos acessar qualquer bean gerenciado pelo Spring (Service, DAO, Repository, whatever) nas páginas através de JSF EL sem a necessidade de intermediar o acesso à este bean com um managed bean do JSF.

O problema

O problema realmente surgiu enquanto o Tarso implementava um mecanismo de CRUD genérico para nossa aplicação, foi aí que começamos a discutir sobre o problema e em seguida a solução.

Na verdade, no projeto que estamos desenvolvendo nós utilizamos muitas combo-boxes (tr:SelectOneChoice pois utilizamos o Myfaces Trinidad) nas nossas páginas e ter que criar um ou mais métodos nos nossos managed beans somente para popular essas combos com dados trazidos diretamente do banco de dados -sem qualquer lógica-, além de ser uma tafera repetitiva, não era nada cômodo.

No final das contas só queríamos não escrever mais código repetitivo nos nossos managed beans (principalmente os que estendiam o nosso CRUD genérico) simplemente para podermos acessar nas páginas uma lista de objetos trazidos do banco de dados.

A solução

Com a integração do Spring com JSF é possível fazer injeção de dependências (DI) dos beans do Spring dentro dos managed beans da aplicação pelo faces-config.xml, algo como:

[faces-config.xml]

<managed-bean>
    <managed-bean-name>bacalhauBean</managed-bean-name>
    <managed-bean-class>bean.faces.BacalhauBean</managed-bean-class>
    <managed-bean-scope>request</managed-bean-scope>
    <managed-property>
        <property-name>someService</property-name>
        <property-class>model.service.SomeService</property-class>
        <value>#{someService}</value>
    </managed-property>
</managed-bean>

Imaginem que nós tenhamos um bean chamado “someService” configurado no spring-config.xml, ok?
Agora observem que o bean gerenciado pelo Spring é resolvido através da EL do JSF, #{someService}, então por que não utilizar-se disso para acessarmos diretamente este bean dentro das páginas? :D
Será isso que iremos fazer logo abaixo!

Imagine que nossa implementação da interface SomeService seja algo do tipo:

[SomeServiceImpl.java]

public class SomeServiceImpl implements SomerService {

    // outros métodos deste serviço

    public List<Foo> findAll() {
        // executa a pesquisa através de um DAO, ou repositório, whatever..
    }

    public List<Foo> getAll() {
        // faz chamada ao método findAll
        return this.findAll();
    }
}

Assim no código da página nós precisaríamos fazer apenas isto:

[foo.jsp]

<h:selectOneMenu id="fooId" value="#{bacalhauBean.fooId}">
    <t:selectItems value="#{someService.all}" var="o" itemValue="o.id" itemLabel="o.name" />
</h:selectOneMenu>

Observem que estou passando a lista de objetos para o componente através da EL #{someService.all} que reflete o método SomeServiceImpl.getAll() do bean gerenciado pelo Spring, atentem também que estou utilizando o componente t:selectItems do Myfaces Tomahawk para que eu possa iterar uma lista de objetos comuns, pois sem ele seria necessário passar uma lista de SelectItem’s, o que não ficaria legal nas nossas classes de serviços.

O melhor de tudo é que não há a necessidade de utilizar um managed bean para intermediar a lista de dados para o componente, o EL do JSF acha o bean “someService” no contexto do Spring e faz a chamada ao método para você (é necessário que o método comece com “get” para que a EL consiga executar corretamente, por isso criamos um método chamado getAll() na classe do SomeServiceImpl.java).

Graças ao variable resolver do Spring você poderá utilizar o #{someService.all} em qualquer componente que espere uma lista de objetos, como um h:dataTable, h:selectManyMenu ou qualquer outro. Além do mais você poderá obter um objeto qualquer como um entity, ou um mapa, ou uma lista ordenada e/ou filtrada diretamente dos beans gerenciados pelo Spring e utilizá-los nas tuas páginas sem dificuldades.

Uma coincidência é que enquanto o Tarso estava fazendo os testes e implementando a solução ele caiu naquele velho probleminha do selectOneMenu, não exatamente como no cenário que eu havia blogado, mas o problema e a solução foram a mesma, e acabamos resolvendo este problema rapidamente sem perder tempo. É como eu disse no final daquele post, “[...] quem não passou provavelmente irá passar algum dia.” :)

O mais engraçado..

O mais engraçado disso tudo é que já temos tudo isso pronto e muito melhor implementado com o JBoss Seam, o Seam estendeu a EL do JSF e com isso conseguimos acessar qualquer componente no seu contexto através de EL, como DAOs, repositorios, serviços etc, e o melhor é que a sua EL estendida nos fornece a possibilidade de executar métodos parametrizados, ou seja, com ele podemos ter algo como isto:

<h:commandButton action="#{hotelBooking.bookHotel(hotel, user)}" value="Book Hotel"/>

Simplesmente fantástico!
Enfim, para quem não tem o JBoss Seam no projeto, pode ter um pouco do gostinho dele com o Spring.

Concluindo..

Como achei o problema e a solução interessantes eu quis compartilhar com os pouquíssimos leitores deste blog, fica aí a dica senhores.
Valeu Tarso Bessa, valeu gente.