Você está na página 1de 10

CAPTULO 1

Introduo ao Seam

A primeira coisa a entender sobre o Seam que ele um framework. Na verdade


um framework que est acima do framework (Java EE), que por sua vez tambm fica
acima de outro framework (Java). Mas no se distraia com isso agora.
A palavra framework tem um amplo significado, podendo ter vrias interpretaes
dependendo de como usada (e de quem a est usando). No caso do Seam, interpretamos palavra framework sob o ponto de vista da tecnologia de sistemas: Ele molda
um conjunto de APIs e servios em um ambiente que facilita (ou simplifica) escrever
aplicaes web Java EE.
Um framework geralmente facilita fazer algo, simplificando atividades rotineiras e comuns, fornecendo utilitrios nativos que em outro caso voc mesmo teria que
escrever. Seam no diferente. Seam est baseado em Java EE, logo ele atende aos seus
deveres de framework de duas maneiras fundamentais:

Seam simplifica Java EE: Seam fornece um conjunto de atalhos e simplificaes do framework padro Java EE, tornando fcil e eficaz o uso de componentes web e de negcios Java EE.

Seam extende Java EE: Seam integra um conjunto de conceitos e ferramentas


ao framework Java EE. Estas extenses trazem novas funcionalidades para
dentro do framework Java EE.
Voc se familiarizar com o Seam neste captulo, examinando rapidamente cada
uma de suas caractersticas. No final deste captulo, so listados vrios servios e
utilitrios que o Seam fornece. Nos captulos que se seguem, voc ver estes servios
em ao, com exemplos de desenvolvimento de aplicaes.

PROJETOS PRTICOS COM JBOSS SEAM

SEAM SIMPLIFICA JAVA EE


O ambiente padro Java EE formado pelo Java Standard Edition (Java SE) com
todas as suas APIs (JDBC para acesso a banco de dados, JAXP para processamento de
XML etc.) que suportam todos os recursos da camada enterprise do Java EE (JSF/JSP/
servlets para desenvolvimento de componentes web, JAX-WS para web services etc).
Seus componentes de aplicao so construdos diretamente sobre o topo de todo este
framework, conforme a Figura 1-1.

Application Components

JSF

JSP/
Servlets

JAX-WS

EJB3/JPA

...

Java Enterprise Edition (Java EE)

JNDI

RMI

JAXP

JDBC

...

Figura 1-1 Framework padro Java EE.

Alm das APIs e dos diversos componentes descritos na figura 1-1, Java EE tambm
fornece servios de deployment, servio de segurana em tempo de execuo, e outros
que voc precisa para criar aplicaes eficazes. E Java EE fornece um conjunto de
melhorias em relao ao framework predecessor, o J2EE, por exemplo:

As anotaes do Java 5.0 esto integradas por toda a API no Java EE,
oferecendo a voc a opo de utilizar as anotaes tanto como informao
externa para deployment no formato XML ou embutidas no cdigo.

O Java Server Faces (JSF) 1.2, o Java API para XML baseados em Web Services
(JAX-WS) 2.0, as APIs Enterprise JavaBeans (EJB) 3.0 oferecem modelos de
programao mais fceis em relao ao predecessor J2EE, permitindo a voc
implementar boa parte dos componentes web, web service e de negcios
usando simples JavaBeans.

EJB 3.0 elimina a necessidade por muitas das interfaces e outros artefatos
exigidos na maioria dos casos, pelas verses anteriores do EJB .
Mesmo com as melhorias apresentadas pelo Java EE, o time do JBOSS Seam
visualizou espao para simplificar as coisas ainda mais. A Figura 1-2 descreve o
framework Seam entre duas camadas, a camada do cdigo de sua aplicao e a camada
do framework Java EE.

CAPTULO 1 INTRODUO AO SEAM

Application Components
Seam Framework
Conversao

jBPM

Regras JBoss

Modelo de Componente

JSP/
Servlets

JSF

EJB3/JPA

JAX-WS

...

Java Enterprise Edition (Java EE)

JNDI

RMI

JDBC

JAXP

...

Java Standard Edition (Java SE)

Figura 1-2 Seam Framework.

O Modelo de Componentes do Seam


As simplificaes fornecidas pelo Seam derivam principalmente do seu modelo ou
arquitetura de componentes este modelo de componente pode ser considerado, em
essncia, como uma extenso do modelo de componente utilizado pelos managed
beans do JSF, mas tambm pode ser usado para outras finalidades, alm de somente
a camada de componentes web, como voc ver nos captulos finais.
Um benefcio fundamental fornecido pelo modelo de componente do Seam o uso
direto de componentes EJB como beans acoplados as pginas JSF. O modelo padro
do JSF permite que Javabeans regulares ou comuns sejam utilizados como managed
beans, conforme a configurao do arquivo JSF faces-config.xml.Componentes EJB
podem ser invocados a partir de mtodos callback de managed beans, servindo como
uma fachada (faade) para o componente EJB. Seam fornece uma ponte entre o
modelo de componente do JSF e o modelo de componente do EJB, permitindo que voc
utilize um EJB diretamente como um managed bean JSF. Isto elimina a necessidade
por fachadas extras de beans quando tudo que voc necessita um nico EJB.
Outra simplificao oferecida pelo Seam a habilidade de usar cdigo de anotaes
para ligar diretamente beans aos nomes de componentes JSF ao invs de escrever
referncias do managed-bean no arquivo faces-config.xml.
O modelo de componente do Seam inclui anotaes que podem ser usadas para
conectar diretamente uma instncia de um bean com o nome do managed-bean JSF.
Quando o nome utilizado no JSF (uma de suas propriedades usada como valor de
um campo HTML por exemplo), a instncia do bean ser automaticamente inicializada,
se necessrio, e usada como um bean acoplado no JSF. No existe a necessidade de

PROJETOS PRTICOS COM JBOSS SEAM

conectar o bean com o nome do managed bean JSF atravs do arquivo facesconfig.xml.
O modelo de componente do Seam tambm suporta uma viso mais abrangente de
dependncia por injeo, chamada de bijeo. A dependncia por injeo padro
envolve uma nica inicializao da referncia do bean dentro do componente,
geralmente feito por um tipo de container ou outro servio runtime. A bijeo no Seam
estende este conceito para suportar o seguinte:

Propagao das referncias em dois sentidos: Um componente pode ter uma


injeo referncia feita pelo container, e o componente tambm pode realizar
uma injeo ao contexto.

Atualizaes dinmicas: Ao invs de realizar a injeo das referncias de uma


nica vez, a bijeo realizada a cada invocao do componente. Este ponto
chave no modelo de componente do Seam, j que os componentes possuem
estados, logo estes componentes e seus beans dependentes podem ser invocados livremente.

Mltiplos contextos: Dependncias (de entrada e sada) podem ser estabelecidas


atravs de mltiplos contextos Seam em vez de serem obrigados a existir
dentro de um nico contexto. Ento um componente em escopo de sesso pode
efetuar uma injeo a um bean em escopo de requisio e tambm realizar uma
injeo-externa para beans com escopo de aplicao, por exemplo.
Tudo isto pode parecer um pouco esotrico neste ponto, mas o valor desses recursos
no modelo do Seam ficar claro quando eu mostrar alguns exemplos de cdigo.

Rodando um Exemplo: Um Catlogo de Dispositivos


O exemplo que utilizado em boa parte do livro um catlogo online de
dispositivos de alta tecnologia (telefones celulares, computadores portteis, media
players etc.). Nos prximos captulos, esta aplicao ser construida a partir de uma
ferramenta simples de entrada de dados, e em seguida em algo um pouco mais
interessante; ser construido tambm solues para outros casos do mundo real,
usando os potenciais do framework Seam. Mas agora, ser apresentado inicialmente
uma aplicao bem simples que pode fazer somente duas coisas :

Mostrar uma lista de dispositivos eletrnicos contidos no catlogo.

Permitir o usurio entrar com um novo dispositivo no catlogo.


Neste ponto, o modelo de aplicao ser dolorosamente simples; um dispositivo
ir consistir de uma descrio (Ex: Acme Powertop X1 Laptop) e o tipo (Ex:
laptop). A informao sobre esses dispositivos ser armazenada e gerenciada em um
banco de dados relacional. O fluxo das pginas da interface de usurio tambm ser
igualmente simples: a pgina principal mostrar uma lista de dispositivos do banco
de dados e oferecer uma nica opo de adicionar um novo dispositivo no banco de

CAPTULO 1 INTRODUO AO SEAM

dados. Esta opo dar ao usurio um formulrio de entrada de dados que apresenta
os atributos necessrios, e durante a submisso de um novo dispositivo, o mesmo ser
armazenado no banco de dados e atualizado na lista de dispositivos que sero
apresentados novamente.
Podemos representar o desenho da soluo neste ponto com um diagrama de
fluxo de pgina e um diagrama de banco relacional. O fluxo de pgina para a primeira
interao do Catlogo de Dispositivos apresentado na Figura 1-3 e a estrutura do
banco de dados na Figura 1-4:
Salvar

Adicionar
Dispositivo

Lista de
Dispositivos

Formulrio
de Entrada

Figura 1-3 Fluxo de pgina do Catlogo de Dispositivos.


Dispositivos
Tipo

Char(3)

Desc

Varchar(100)

Figura 1-4 Banco do Catlogo de Dispositivo.

Agora tudo o que temos que fazer construir. Como referncia, vamos primeiro ver
como o Catlogo de Dispositivos no framework Vanilla Java EE.

O Catlogo de Dispositivos sem o Seam


O cdigo para este exemplo pode ser encontrado no pacote de cdigos para este
livro, em baixo do subdiretrio intro-JavaEE. No framework Java EE, sem o JBoss
Seam, a abordagem normal para a implementao de um Catalogo de Dispositivos
usar o JSF como um UI em conjunto com os EJBs trabalhando a persistncia e a lgica.
Para comear, vamos implementar um entity bean EJB 3.0 para representar o
dispositivo a ser armazenado na tabela de dispositivos. A Listagem 1-1 mostra o bean
de dispositivo. Este um entity bean que mapeado com a tabela de dispositivo atravs
da anotao EJB@Table. O bean tem duas propriedades persistentes: A propriedade
descrio que mapeada na coluna DESCR, e a propriedade tipo que mapeado na
coluna TYPE.

PROJETOS PRTICOS COM JBOSS SEAM


Listagem 1-1 Entity EJB Dispositivo (GADGET no cdigo)

@Entity
@Table(name=GADGET)
public class GadgetBean implements Serializable {
private String mDescription = ;
private String mType = ;
public GadgetBean() { }
@Id
@Column(name=DESCR)
public String getDescription() {
return mDescription;
}
public void setDescription(String desc) {
mDescription = desc;
}
@Id
@Column(name=TYPE)
public String getType() {
return mType;
}
public void setType(String t) {
mType = t;
}
}

Dica Prtica

Tenha cuidado com as palavras reservadas do SQL usadas como classe


entity bean EJB ou como nomes de propriedades. Mecanismos de
Persistncia podem tentar mape-los diretamente para automaticamente
gerar as colunas/tabelas, resultando em uma Exceo SQL inesperada.
Observe que nomeou-se a propriedade do bean de dispositivo (GadgetBean)
como descrio ao invs de desc. um nome maior para o tipo, mas
desc uma palavra reservada em alguns bancos de dados. Se voc decidir
auto-gerar o esquema, a propriedade chamada desc poderia ser mapeada
em uma coluna chamada DESC, e poderia gerar problemas. Estamos
sendo muito cuidadosos ao usar explicitamente anotaes EJB3 @Column
para mapear as propriedades em colunas em nosso modelo de banco de
dados, logo mesmo se ns auto gerssemos o esquema (como fazemos nos
cdigos fornecidos como exemplo no pacote de cdigo do livro), estaramos seguros de no gerarmos o problema citado.

CAPTULO 1 INTRODUO AO SEAM

Com o fim de implementar a funcionalidade que foi apresentada para o catlogo


de dispositivos, preciso estar apto a obter uma lista de todos os dispositivos
atualmente dentro do banco de dados, e preciso adicionar um novo dispositivo ao
banco de dados. Usando um padro tpico Session Faade para o EJB, foi criado o
EJB de sesso GadgetAdminBean para prover estas funes. O cdigo para isto,
apresentado na listagem 1-2:
Listagem 1-2 Sesso EJB GadgetAdminBean
@Stateless
public class GadgetAdminBean implements IGadgetAdminBean {
@PersistenceContext(unitName=gadgetDatabase)
private EntityManager mEntityManager;
/** Retrieve all gadgets from the catalog, ordered by description */
public List<GadgetBean> getAllGadgets() {
List<GadgetBean> gadgets = new ArrayList<GadgetBean>();
try {
Query q =
mEntityManager.createQuery( select g from GadgetBean +
g order by g.description);
List gList = q.getResultList();
Iterator i = gList.iterator();
while (i.hasNext()) {
gadgets.add((GadgetBean)i.next());
}
}
catch (Exception e) {
e.printStackTrace();
}
return gadgets;
}
/** Insert a new gadget into the catalog */
public void newGadget(GadgetBean g) {
try {
mEntityManager.persist(g);
}
catch (Exception e) {
e.printStackTrace();
}
}
}

Esta sesso EJB usa o padro EJB 3.0 e chamadas Java Persistence API (JPA) para
implementar as funes exigidas. Ns as marcamos como session bean sem estado
usando a anotao @Stateless do EJB 3.0 na declarao da classe. Tambm usamos

PROJETOS PRTICOS COM JBOSS SEAM

a anotao JPA @Persistence-Context para introduzir o EntityManager JPA em um


session bean, nos permitindo executar as operaes de persistncia necessrias para
consultar e inserir no banco de dados de dispositivos. Estamos referenciando uma
unidade de persistncia chamada de gadgetDatabase, logo precisaremos definir uma
unidade de persistncia com esse nome no arquivo de deployment persistence.xml
quando empacotarmos os EJBs.
O mtodo getAllGadgets() carrega um catlogo inteiro de dispositivos usando
uma consulta JPA criada a partir do EntityManager. O mtodo newGadget() persiste
um novo dispositivo usando o EntityManager. (na forma do bean de dispositivo
GadgetBean).
Estes dois EJBs parecem tomar conta de nossas atuais necessidades em termos de
operaes de persistncia, ento agora podemos mudar a nossa ateno para a UI. Para
implementar a UI que especificamos no fluxo de pgina desenhado anteriormente,
criamos duas pginas JSF, uma para cada uma das pginas especificadas. A primeira
mostra uma lista de dispositivos em um banco de dados junto com um link para criar
um novo dispositivo. Durante a construo destas pginas, vamos assumir que
podemos acessar a funcionalidade de persistncia que construmos anteriormente
atravs do managed bean JSF chamado gadgetAdmin. Nossa lista de Dispositivos
JSF apresentada na Listagem 1-3. Ela simplesmente utiliza um componente data
table JSF para interagir atravs dos dispositivos retornados da operao getAllGadgets()
no bean gadgetAdmin, mostrando cada dispositivo na linha do componente data
table. Ento, no p do data table ns geramos um link que invoca uma ao JSF
chamada addGadget.
Listagem 1-3 Pgina JSF de listagem de dispositivos
<%@ taglib uri=http://java.sun.com/jsf/html prefix=h%>
<%@ taglib uri=http://java.sun.com/jsf/core prefix=f%>
<html>
<head>
<title>Gadget List</title>
</head>
<body>
<f:view>
<h:messages/>
<! Show the current gadget catalog >
<h:dataTable value=#{gadgetAdmin.allGadgets} var=g>
<h:column>
<f:facet name=header>
<h:outputText value=Type />
</f:facet>
<h:outputText value=#{g.type} />

CAPTULO 1 INTRODUO AO SEAM

</h:column>
<h:column>
<f:facet name=header>
<h:outputText value=Description />
</f:facet>
<h:outputText value=#{g.description} />
</h:column>
</h:dataTable>
<h:form>
<! Link to add a new gadget >
<h:commandLink action=addGadget>
<h:outputText value=Add a new gadget />
</h:commandLink>
</h:form>
</f:view>
</body>
</html>

A ao addGadget deve nos trazer a segunda pgina no nosso fluxo, a pgina com
o formulrio de entrada de dispositivos. A pgina JSF que implementa isto, a
addGadget.jsp, apresentada na Listagem 1-4.
Listagem 1-4 Pgina JSF de entrada de dispositivos.
<%@ taglib uri=http://java.sun.com/jsf/html prefix=h%>
<%@ taglib uri=http://java.sun.com/jsf/core prefix=f%>
<html>
<head>
<title>Add a Gadget</title>
</head>
<body>
<f:view>
<h:form>
<table border=0">
<tr>
<td>Description:</td>
<td>
<h:inputText value=#{gadget.description}
required=true />
</td>
</tr>
<tr>
<td>Type:</td>
<td>
<h:selectOneMenu value=#{gadget.type}
required=true>
<f:selectItems value=#{gadgetAdmin.gadgetTypes} />

10

PROJETOS PRTICOS COM JBOSS SEAM

</h:selectOneMenu>
</td>
</tr>
</table>
<h:commandButton type=submit value=Create
action=#{gadgetAdmin.newGadget} />
</h:form>
</f:view>
</body>
</html>

Esta pgina gera um simples formulrio de entrada que questiona o usurio a


informar o tipo e a descrio de um novo dispositivo para o catalogo. O campo
descrio um simples campo de entrada de texto, enquanto o tipo um campo selectlist que ser preenchido com os valores permitidos vindos da enumerao GadgetTypes.
Ambos campos so limitados com as propriedades do novo managed bean chamado
gadget. Ao final de cada formulrio h o boto de submit que invoca a operao
newGadGet() no gadgetAdmin managed bean.
Neste ponto, como em qualquer aplicao JSF, precisaremos ligar os managed
beans JSF com as classes em nosso modelo. Podemos tentar associar o bean gadgetAdmin
com uma instncia de nossa sesso EJB GadgetAdminBean e o bean gadget com nossa
entity EJB GadgetBean, usando entradas em nosso faces-config.xml, como mostra a
listagem abaixo:
<faces-config>
<managed-bean>
<managed-bean-name>gadget</managed-bean-name>
<managed-bean-class>GadgetBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>gadgetAdmin</managed-bean-name>
<managed-bean-class>GadgetAdminBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
</faces-config>

Mas o que voc descobrir que isto no ir funcionar, pelo menos no do jeito
que voc esperava. Em JSF, espera-se que os managed beans sejam simples JavaBeans,
e eles sero tratados assim em runtime pelo container JSF. Quando o bean gadget ou
gadgetAdmin, so criados e usados em tempo de execuo, para estes beans o container
JSF no segue as regras dos componentes EJB. Ele no ir, por exemplo, usar o
container EJB para obter uma instncia do GadgetAdminBean, como deveria para
qualquer bean de sesso. Ao contrrio, ele tentar construir instncias do
GadgetAdminBean diretamente, fora do container EJB e de todos os seus servios. E

Você também pode gostar