Professional Documents
Culture Documents
Introdução ao Seam
Application Components
Além das APIs e dos diversos componentes descritos na figura 1-1, Java EE também
fornece serviços de deployment, serviço de segurança em tempo de execução, e outros
que você precisa para criar aplicações eficazes. E Java EE fornece um conjunto de
melhorias em relação ao framework predecessor, o J2EE, por exemplo:
• As anotações do Java 5.0 estão integradas por toda a API no Java EE,
oferecendo a você a opção de utilizar as anotações tanto como informação
externa para deployment no formato XML ou embutidas no código.
• 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
programação mais fáceis em relação ao predecessor J2EE, permitindo a você
implementar boa parte dos componentes web, web service e de negócios
usando simples JavaBeans.
• EJB 3.0 elimina a necessidade por muitas das interfaces e outros artefatos
exigidos na maioria dos casos, pelas versões anteriores do EJB .
Mesmo com as melhorias apresentadas pelo Java EE, o time do JBOSS Seam
visualizou espaço para simplificar as coisas ainda mais. A Figura 1-2 descreve o
framework Seam entre duas camadas, a camada do código de sua aplicação e a camada
do framework Java EE.
CAPÍTULO 1 – INTRODUÇÃO AO SEAM 3
Application Components
Seam Framework
jBPM Conversação Regras JBoss
Modelo de Componente
JSP/
JSF EJB3/JPA JAX-WS ...
Servlets
conectar o bean com o nome do managed bean JSF através do arquivo faces-
config.xml.
O modelo de componente do Seam também suporta uma visão mais abrangente de
dependência por injeção, chamada de bijeção. A dependência por injeção padrão
envolve uma única inicialização da referência do bean dentro do componente,
geralmente feito por um tipo de container ou outro serviço runtime. A bijeção no Seam
estende este conceito para suportar o seguinte:
• Propagação das referências em dois sentidos: Um componente pode ter uma
injeção à referência feita pelo container, e o componente também pode realizar
uma injeção ao contexto.
• Atualizações dinâmicas: Ao invés de realizar a injeção das referências de uma
única vez, a bijeção é realizada a cada invocação 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 invo-
cados livremente.
• Múltiplos contextos: Dependências (de entrada e saída) podem ser estabelecidas
através de múltiplos contextos Seam em vez de serem obrigados a existir
dentro de um único contexto. Então um componente em escopo de sessão pode
efetuar uma injeção a um bean em escopo de requisição e também realizar uma
injeção-externa para beans com escopo de aplicação, por exemplo.
Tudo isto pode parecer um pouco esotérico neste ponto, mas o valor desses recursos
no modelo do Seam ficará claro quando eu mostrar alguns exemplos de código.
dados. Esta opção dará ao usuário um formulário de entrada de dados que apresenta
os atributos necessários, e durante a submissão de um novo dispositivo, o mesmo será
armazenado no banco de dados e atualizado na lista de dispositivos que serão
apresentados novamente.
Podemos representar o “desenho da solução” neste ponto com um “diagrama de
fluxo de página” e um diagrama de banco relacional. O fluxo de página para a primeira
interação do Catálogo de Dispositivos é apresentado na Figura 1-3 e a estrutura do
banco de dados na Figura 1-4:
Salvar
Adicionar
Dispositivo
Lista de
Dispositivos Formulário
de Entrada
Dispositivos
Tipo Char(3)
Desc Varchar(100)
Agora tudo o que temos que fazer é construir. Como referência, vamos primeiro ver
como o Catálogo de Dispositivos é no framework Vanilla Java EE.
@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;
}
@Id
@Column(name=”TYPE”)
public String getType() {
return mType;
}
Dica Prática Tenha cuidado com as palavras reservadas do SQL usadas como classe
entity bean EJB ou como nomes de propriedades. Mecanismos de
Persistência podem tentar mapeá-los diretamente para automaticamente
gerar as colunas/tabelas, resultando em uma Exceção SQL inesperada.
Observe que nomeou-se a propriedade do bean de dispositivo (GadgetBean)
como “descrição” ao invés 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 anotações EJB3 @Column
para mapear as propriedades em colunas em nosso modelo de banco de
dados, logo mesmo se nós auto gerássemos o esquema (como fazemos nos
códigos fornecidos como exemplo no pacote de código do livro), estarí-
amos seguros de não gerarmos o problema citado.
CAPÍTULO 1 – INTRODUÇÃO AO SEAM 7
@Stateless
public class GadgetAdminBean implements IGadgetAdminBean {
@PersistenceContext(unitName=”gadgetDatabase”)
private EntityManager mEntityManager;
Esta sessão EJB usa o padrão EJB 3.0 e chamadas Java Persistence API (JPA) para
implementar as funções exigidas. Nós as marcamos como session bean sem estado
usando a anotação @Stateless do EJB 3.0 na declaração da classe. Também usamos
8 PROJETOS PRÁTICOS COM JBOSS SEAM
<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}” />
CAPÍTULO 1 – INTRODUÇÃO AO SEAM 9
</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 ação addGadget deve nos trazer a segunda página no nosso fluxo, a página com
o formulário de entrada de dispositivos. A página JSF que implementa isto, a
addGadget.jsp, é apresentada na Listagem 1-4.
<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 PRÁTICOS COM JBOSS SEAM
</h:selectOneMenu>
</td>
</tr>
</table>
<h:commandButton type=”submit” value=”Create”
action=”#{gadgetAdmin.newGadget}” />
</h:form>
</f:view>
</body>
</html>
<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 não irá funcionar, pelo menos não do jeito
que você esperava. Em JSF, espera-se que os managed beans sejam simples JavaBeans,
e eles serão tratados assim em runtime pelo container JSF. Quando o bean gadget ou
gadgetAdmin, são criados e usados em tempo de execução, para estes beans o container
JSF não segue as regras dos componentes EJB. Ele não irá, por exemplo, usar o
container EJB para obter uma instância do GadgetAdminBean, como deveria para
qualquer bean de sessão. Ao contrário, ele tentará construir instâncias do
GadgetAdminBean diretamente, fora do container EJB e de todos os seus serviços. E