JBoss SeamIntrodução
O que é Jboss Seam?Segundo a definição da Palavra:     Seam = EmendaSeam não é um acrônimo (SEAM):    Stop Enterprise Application Masochism    Software for Enterprise Application Masterpieces
O que é Jboss Seam?Informações gerais:Criado por Gavin King (criador do Hibernate)Versão 1.0 Beta 1 em 18/09/2005Versão 1.0.0.GA lançada em 12/06/2006
O que é Jboss Seam?Versão atual de produção: 2.1.2.GAComunidade extremamente ativa: www.seamframework.orgMais de 1.000 usuários registrados no primeiro mêsAtualmente, mais de 5.000 usuários registrados
O que é Jboss Seam?De acordo com o site oficial : Seam é um framework para Java Enterprise (JavaEE)Seam não é simplesmente outro framework de IntegraçãoNão é também uma resposta ao Spring Framework.
O que é Jboss Seam?Componente unificado: Managed Beans (EJB3)Extensão dos contextos Java Servlet, com aadição do escopo “Conversation”Gerenciamento do PersistenceContextNão faz distinção entre os componentes da camada de apresentação e camada de negócios:business logic componentsVocê cria sua arquitetura e define suas camadas
O que é Jboss Seam? Integração entre  JSF e EJB 3.0 O JBoss Seam faz todo o “trabalho sujo” de integração entre JSF e EJB 3.0, deixando o desenvolvedor concentrado no domínio de negóciosO JBoss Seam foi feito para o JSF:Além do JSF, o JBoss Seam permite outras tecnologias  para a camada de apresentação:Wicket, Tapestry, GWT e Flex (GraniteDS e BlazeDS)Além de não depender do JSF para a camada de Apresentação, o JBoss Seam funciona com ou sem EJB 3.0
O que é Jboss Seam?Tipos de componentes Seam:JavaBeansEJB 3.0:Stateless Session BeansStateful Session BeansEntity BeansMessage-Driven Beans
O que é Jboss Seam?Virtualmente, qualquer classe Java pode se tornar umcomponente Seam@Name (“meuComponente”)public class meuComponente {......}
O que é Jboss Seam?Modelo unificado de componentes:Não há distinção entre componentes da camada deapresentação e componentes da camada de negócios:Não se faz necessário o uso de DTO/VO<h:form>    <h:inputText value="#{user.name}“ />    <h:inputText value="#{user.telefone}" /></h:form>@Entity@Name(“user”)public class User {    private String name;    private String telefone;
O que é Jboss Seam?Modelo unificado de componentes (continuação):O modelo de componentes do JBoss Seam permite autilização direta de POJOs como “backing beans” para aspáginas JSF:• Nada de cadastrar classes no faces-config.xml: <managed-bean>  <managed-bean-name>cadastro</managed-bean-name>  <managed-bean-class>demo.Cadastro</managed-bean-class>  <managed-bean-scope>session</managed-bean-scope> </managed-bean>
O que é Jboss Seam?Elimina camadas/artefatos “desnecessários”:VO/DTO, DAO, Service Locator, OpenSessionInView...VOCÊ monta a arquitetura da sua aplicação, define ascamadas e como elas vão interagir
O que é Jboss Seam?Integração com AJAXSuporte “out of the box” para frameworks open sourcebaseados em JSF:Adiciona suporte AJAX sem a necessidade de codificação de JavaScript pelo desenvolvedorICEfacesJBoss RichFaces:<h:inputText value="#{user.name}" required="true">    <f:validateLength maximum="30" minimum="3"/>    <rich:ajaxValidator/>    </h:inputText><br/>
O que é Jboss Seam?Possui uma camada de JavaScript remoto:• Acesso aos componentes Seam direto do JavaScript:Integração com:DojoGWTvar meuComp = Seam.Component.newInstance(“meuComp”);meuComp.setXXX(Valor);
O que é Jboss Seam?Estende os contextos definidos pela especificação de Servlets:request (event), page, session e application com dois novos contextos:ConversationBusiness process
O que é Jboss Seam?ConversationConceito chave no JBoss SeamA conversação representa uma “unidade de trabalho” doponto de vista do usuário:Geralmente associada a um Caso de UsoUm usuário pode ter várias conversações ao mesmo tempo:Normalmente em múltiplas janelas do browserFacilita a construção de “wizards”Facilita o uso de AJAX
O que é Jboss Seam?Conversation (continuação)Facilita ainda mais o uso do JPA:Evita a famigerada LIE (LazyInitializationException)Business processContexto Stateful (Banco de Dados)O usuário pode continuar a interação com o sistemamais tarde
O que é Jboss Seam?O JBoss Seam suporta o conceito de Inversão de Controle (IoC) ou Injeção de Dependências (DI), mas vai alémA injeção de dependências funciona bem no modelo de	arquitetura stateless, mas, em uma arquitetura stateful,	precisamos que a injeção de dependências seja	bidirecional:
O que é Jboss Seam?Bijeção (Injeção + Ejeção): Estende o modelo de IoC:• Dinâmica• Contextual• Bidirecional A bijeção ocorre:• Antes e depois das chamadas aos métodos
O que é Jboss Seam?Injection:Componente é recuperado de um contexto (ou criado,	dependendo da configuração) e injetado em outro	componente:@Inprivate User user;
Jboss Seam?Outjection:Um componente “ejeta/coloca” outro componente em um contexto:@Out Usuario user;Para criar um componente podemos usar@Factoryprivate void pesquisar() {....}
Configuração do SeamSeam servlet e listenerServlet que processa todas requisições Seam 	File: /WEB-INF/web.xml<servlet>  <servlet-name>Faces Servlet</servlet-name>  <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>  <load-on-startup>1</load-on-startup></servlet>< servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.seam</url-pattern></servlet-mapping>
Configuração do SeamListener, responsável por “startar” o seam e destruir as sessões e contexto de aplicação<listener><listener-class>org.jboss.seam.servlet.SeamListener</listener-class></listener>
ConfiguraçãoArquivos requeridos de configuração:/WEB-INF/faces.configconfiguração especifica JSF/WEB-INF/components.xmlconfiguração do Seamcolocado em META-INF
Configuração/WEB-INF/pages.xmlNavegação do SeamÉ opcional, mas recomendadoseam.propertiesConfigurações do Seam, geralmente vazio.Deve ser colocado em todo lugar que tiver algum componente Seam (@Name)
ConfiguraçãoConfiguração Facelets WEB-INF/faces-config.xml<application><view-handler>com.sun.facelets.FaceletViewHandler</view-handler></application>WEB-INF/web.xml<context-param>	<param-name>javax.faces.DEFAULT_SUFFIX</param-name>	<param-value>.xhtml</param-value></context-param>
ConfiguraçãoSeam FilterRequerido para controle de erro, progagação de conversação WEB-INF/web.xml<filter>	<filter-name>Seam Filter</filter-name>	<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>	</filter>	<filter-mapping>	<filter-name>Seam Filter</filter-name>	<url-pattern>/pattern>/*</url-pattern></filter-mapping>
ConfiguraçãoFiltro de tratamento de ErrosErros podem ser mapeados para uma página própria para errosFile: /WEB-INF/pages.xml<exception class="org.jboss.seam.framework.EntityNotFoundException">	<redirect view-id="/error.xhtml">	<message>Not found</message></redirect>
Exercício 1 Vamos criar nossa primeira aplicação em Jboss Seam ;-) Cadastro de usuários: igual a versão feita em JSF
Resultado do Exercício 1
Continuando...Validação:Onde colocar as regras de validação?Na camada de apresentação?Sim, precisamos informar os erros de validação para oUsuárioMas, também temos de garantir as regras/restriçõesna camada de persistência
ValidaçãoClientes que utilizem as classes de domínio podem	fazer um “bypass” da validação (Ex. Aplicação	Desktop, WebServices)“Bad design”: Regras de validação fazem parte do	objeto de domínio (Persistent Domain Objects)•   Melhor opção: colocar a validação nas classes de	domínio e reaproveitá-las na camada de apresentação	com a utilização de AJAX
ValidaçãoHibernate Validator:Vários validadores pré-definidos: Max, Min, Length,	Range, Size, Email, Future, Past, Pattern, Email,	CreditCard, etcFácil customização (Ex: @CPF, @StrongPassword)Funciona com qualquer implementação de JPA:Se utilizado com o Hibernate, gera a DDL com todas	as restrições definidas
ValidaçãoHibernate Validator:Esforço de padronização da especificação Bean ValidatorValidation (JSR 303)Validação na classe de domínio:
ValidaçãoIntegração do JSF/Facelets com o Hibernate Validator:O JBoss Seam leva a validação definida no objeto dedomínio para a camada de apresentação: Seam JSF Controls:<s:validate/>, <s:validateAll>
ValidaçãoLê a anotação (meta-informação) definida e a utilizacomo validador no JSF<s:decorate/>“Decora” o campo quando há algum erro de validação
Validação (Decorate)<ui:composition xmlns="http://www.w3.org/1999/xhtml"                xmlns:ui="http://java.sun.com/jsf/facelets"                xmlns:h="http://java.sun.com/jsf/html"                xmlns:f="http://java.sun.com/jsf/core"                xmlns:s="http://jboss.com/products/seam/taglib">                     <div>            <s:label styleClass="#{invalid?'error':''}">            <ui:insert name="label"/>            <s:span styleClass="required" rendered="#{required}">*</s:span>        </s:label>                <span class="#{invalid?'error':''}">            <h:graphicImage value="/img/error.gif" rendered="#{invalid}"/>            <s:validateAll>                <ui:insert/>            </s:validateAll>        </span>        <s:message styleClass="error"/>      </div>    </ui:composition>
Validação (Decorate)Para usar, basta colocar informar o decorate como um template<s:decorate template="edit.xhtml">        <ui:define name="label">Country:</ui:define>        <h:inputText value="#{location.country}" required="true"/</s:decorate>
Exercício 2Usando validação na tela criada anteriormente<s:decorate id="d1" template="layout/edit.xhtml">	<ui:define name="label">Nome:</ui:define>	<h:inputText id="username" value="#{pessoa.nome}" required="true" requiredMessage="Campo Obrigatório"/></s:decorate>
Validação (Ajax)Usando validação com ajax<s:decorate id="d1" template="layout/edit.xhtml">                     <ui:define name="label">Nome:</ui:define>    <h:inputText id="username" value="#{pessoa.nome}" required="true“>           <a4j:support event="onblur" reRender="d1"/></h:inputText></s:decorate>
Exercício 3Inserir validação no sistema, fazer testes com validações,testar também o <rich:beanValidator />Obs: Usando o rich:beanValidator não se faz necessário o uso do <s:validate>, <s:decorate><h:inputText id="telefone" value="#{pessoa.telefone}" required="true" requiredMessage="Obrigatrio"><rich:beanValidator summary=“Telefone Inválido" /></h:inputText><rich:message for="telefone"/>
Tabelas de DadosPara facilitar ainda mais, o Seam possui a anotação:“DataModel”@DataModelList<Pessoa> pessoas;Pode ser usado com: List, Map, Set ou Object[], assim como o JSF DataModel
Exercício 4Trocar o @Out por @Datamodel
Tabelas de DadosObtendo valores selecionados em uma tabela@DataModelSelectionPessoa pessoaSelecionada
Exercício 5	Usar o DataModelSelection para obter o objeto selecionadoCriar um método para apagar esse objeto
NavegaçãoStateful navigationPageflow é definido fora dos componentesValores de retorno das actions são avaliadosNavegação clássica: método da action que decide para onde irPageflow é definido para uma simples conversação
Navegação<page view-id="/cadastro.xhtml" >      <begin-conversation join="true"/>      <navigation>        <rule if-outcome="lista">          <redirect view-id="/cadastroPessoa.xhtml"/>        </rule>       </navigation></page>public String salvar() {                       public String salvar() {....                                                          ....return "lista";                                      return “/cadastroPessoa.xhtml";}                                                             }
Navegação<page view-id="/cadastroPessoa.xhtml">	<navigation from-action="#{cadastroPessoaAction.apagar()}">      <redirect view-id="/sucesso.xhtml"/>    </navigation></page>
Navegação<page view-id="/cadastroPessoa.xhtml">	<navigation from-action="#{cadastroPessoaAction.apagar()}">		<rule if-outcome="success">		   <redirect view-id="/sucesso.xhtml"/>		</rule>     </navigation></page><page view-id="/cadastro.xhtml" >	<action execute="#{cadastroPessoaAction.listar()}"/></page><page view-id="/cadastro.xhtml" >	<action if=“#{condicao}” execute="#{cadastroPessoaAction.listar()}"/></page>
Navegação<page view-id=“*/login.xhtml"><navigation from-action="#{identity.login}"><rule if="#{identity.loggedIn}">         <redirect view-id="/home.xhtml"/>      </rule></navigation></page><page view-id=“*/login.xhtml“    login-required="true”>	 .....</page>
Navegação<pages>	<page view-id="/search.xhtml"><param name="searchPattern" value="#{searchService.searchPattern}"/>	</page>...</pages>Metodo é executado antes da página ser renderizada.<page view-id="/entry.xhtml"action="#{entryAction.loadBlogEntry(blogEntry.id)}">	<param name="blogEntryId" value="#{blogEntry.id}”validator="#{Validator}" required="true"/></page>
NavegaçãoPode-se também obter o parâmetro na própria Action implementando um RequestParameter@RequestParameterprivate Long entryId;public void findEntry() {	blogentry = em.find(Blogentry.class, entryId);}
Exercício 6Fazer um exercício de navegação usando o pages.xmlCriar 3 páginas e navegar entre elas usando o pages.xmlUsar chamada de metodo direto no pages.xml
Contextos SeamStatelessEvent contextPage contextSessionBusinessApplication
Contextos SeamStateless: Mesmo conceito do Stateless do EJB criado justamente para integração com este tipo de EJB.Event context: Como o nome mesmo diz os objetos registrados neste contexto apenas vão estar disponíveis durante a execução de um determinado evento.Page context: Contexto já conhecido por todos que trabalham com aplicações web, está associado ao processo de renderização, carregamento, carregamento de uma página.
Contextos SeamConversation context: É um dos contextos que diferencia o Seam de qualquer outro framework existente no mercado, com este contexto podemos criar unidades de conversação e registrar nestas unidade todos os objetos e serviços que a aplicação vai necessitar usar quando a mesma estiver sendo executada sobre este contexto. Neste contexto mesmo outras instâncias da aplicação sendo acessadas em janelas diferentes não terão acesso aos artefatos registrados no contexto da outra, ou seja, a cada nova instância da aplicação em uma nova janela se caracteriza como uma instância independente assim uma não terá acesso as informações da outra mesmo sendo executadas na mesma instância do browser.
Contextos SeamSession context: Este também é muito conhecido por todos que trabalham com aplicações Em resumo este contexto inicia quando acessamos a primeira tela da aplicação e só será destruído quando fecharmos nosso browser ou fazermos um logoff implementado pela aplicação.
Contextos SeamApplication context: E por último o também já conhecido contexto de aplicação, tudo que registrarmos neste contexto fica disponível para todos que acessarem a mesma aplicação, ou seja, devemos registrar neste contexto somente serviços que serão acessados por todos e que são imutáveis pois este contexto só é atualizado no startup do servidor web.
Contextos SeamBusiness process context: Mais um contexto novo criado pelo Seam, este foi criado especialmente para trabalharmos com fluxos de trabalho (workflow), ele garante para nós que qualquer objeto ou serviço registrado neste contexto vai estar disponível até o fim do fluxo. O mesmo fica disponível para múltiplas interações e múltiplos usuários e seu estado é persistente, ou seja, se eu fechar a aplicação e no dia seguinte entrar novamente, os objetos registrados no fluxo em questão estarão ali com as informações deixadas pela última vez.
Contextos SeamContexto Padrão:Depende do tipo do componente:Stateless Session Beans?Default em contexto Stateless EntitiesDefault em contexto Conversation
Contextos Seam Message-Driven Beans?Padrão sem contexto Stateful Session Beans?Padrão em contexto de ConversaçãoJavaBeans?Padrão em contexto de evento
Contextos SeamIniciando e Encerrando uma ConversaçãoAnotação@Beginpublic void checkoutShoppingCart(){// ...@Endpublic void confirmCheckout(){
Contextos SeamNavegação (pages.xml)<page view-id="/messageList.jsp" action="#{conversation.begin}"/>Ou<page view-id="/messageList.jsp"><begin-conversation /><page><page view-id="/home.jsp"><end-conversation/><page>
Contextos SeamEm um link JSF<h:commandLink action="main" value="Select Hotel"><s:conversationPropagation type="begin"/></h:commandLink><h:commandLink action="main" value="Exit"><s:conversationPropagation type="end"/></h:commandLink>Em um Link Seam s:link<s:link view="/checkout.xhtml" propagation="begin"/><s:link view="/confirm.xhtml" propagation="end"/>
Contextos SeamPropagando a conversaçãoPropaga por padrãoPode ser finalizada<s:link view="/main.xhtml" propagation="none"/><h:commandLink action="main" value="Exit"><f:param name="conversationPropagation" value="none"/></h:commandLink><h:commandLink action="main" value="Exit"><s:conversationPropagation type="none"/></h:commandLink>
Exercícios 7Abrir e fechar conversaçãoTrocar contextos
EventosTipos de Eventos Page action  – ocorre antes que a página é carregadaPode ser definido para uma determinada páginaWEB-INF/pages.xml<pages>	<page view-id="/hello.jsp" action="#{helloWorld.sayHello}"/></pages>
EventosPode-se usar  “wildcard” para várias páginasWEB-INF/pages.xml<pages><page view-id="/hello/*" action="#{helloWorld.sayHello}"/></pages>
EventosPode-se também passar parâmetrosWEB-INF/pages.xml<pages>	<page view-id="/hello.jsp" action="#{helloWorld.sayHello}"><param name="firstName" value="#{person.firstName}"/>		<param name="lastName" value="#{person.lastName}"/>	</page></pages>
EventosPode-se também lançar um evento em uma Action@Name("helloWorld")public class HelloWorld {	public void sayHello() {		FacesMessages.instance().add("Hello World!");Events.instance().raiseEvent("hello");	}}
EventosPode-se também lançar um evento em uma Action@Name("helloWorld")public class HelloWorld {@RaiseEvent("hello")	public void sayHello() {		FacesMessages.instance().add("Hello World!");	}}
EventosCapturando os eventos@Name("helloListener")public class HelloListener {@Observer("hello")	public void sayHelloBack() {		FacesMessages.instance().add("Hello to you too!");	}}
Exercício 8Lançar e capturar eventos
ExceçõesO desenvolvedor determina como tratar uma exceçãoVia anotaçãoDeclarativamente em um arquivo XMLSeam  aplica todas regras de rollback das exceções EJB para os componentes JavaBeansSeam da um rollback em qualquer transação ativa quando ocorre uma exceção
ExceçõesCapturando exceções usando Annotações@Redirect(viewId="/failure.xhtml", end=true)@ApplicationException(rollback=true)public class UnrecoverableApplicationException extends RuntimeException { ... }
ExceçõesCapturando exceções usando XMLpages.xml<pages><exception class="javax.persistence.EntityNotFoundException">		<http-error error-code="404"/>	</exception>	<exception class="javax.persistence.PersistenceException">	<end-conversation/><redirect view-id="/error.xhtml">	<message>Database access failed</message>	</redirect></exception>
ExceçõesCapturando exceções usando XMLpages.xml<exception>	<end-conversation/>	<redirect view-id="/error.xhtml">	<message>Aconteceu um Erro ;-(</message>	</redirect></exception>
ExceçõesUsando EL nas ExceçõesExceções são adicionadas no contexto de conversação	org.jboss.seam.handledException <pages>	<exception class="org.jboss.seam.security.AuthorizationException">	<end-conversation/>	<redirect view-id="/error.xhtml">	<message severity="WARN">#{handledException.message}</message>	</redirect>	</exception></pages>
Exercício 9Vamos lancar e capturar algumas exceptionLançar Runtime e Exception para ver a diferençaCriar uma tela de erro customizadaObs: não esquecer de desabilitar :debug (component.xml)facelets.DEVELOPMENT (web.xml)
SegurançaO Seam Security API fornece uma multiplicidade de funções relacionadas com segurança para seu aplicativo, abrangendo áreas como: Autenticação - permite os usuários autenticar em qualquer fornecedor de segurança. (LDAP, JAAS..)Identity Management - uma API para gerenciar uma aplicação Seam, usuários e papéis em tempo de execução.
SegurançaAutorização - um framework extremamente abrangente, baseado em regras de permissõesPermission Management - um conjunto de componentes Seam para permitir uma fácil gestão da aplicação da política de segurança.CAPTCHA - para ajudar na prevenção de um software automatizado / scripts abusar seu sistema.
AutenticaçãoA autenticação fornecida pelo Seam é construída utilizando o JAAS (Java autenticação e autorização de serviço), e como tal, fornecer uma robusta e altamente configurável API para manipulação de autenticação do usuário. No entanto, para exigências menos complexas de autenticação, o Seam oferece um método mais simplificado de autenticação que esconde a complexidade do JAAS.
AutenticaçãoO método de autenticação simplificada fornecido pelo Seam utiliza um built-in JAAS login módulo:SeamLoginModule, que delega a autenticação para um de seus próprios componentes Seam. Este módulo de login já está configurado dentro Seam como parte de uma aplicação padrão e, como tal, não requer qualquer configuração adicional arquivos.Configurar esta forma simplificada de autenticação exige a configuração no arquivo: components.xml:	<security:identity authenticate-method="#{authenticator.authenticate}"/>
AutenticaçãoEscrevendo uma tela de Autenticação:<div>    <h:outputLabel for="name" value="Username"/>    <h:inputText id="name" value="#{credentials.username}"/></div><div>    <h:outputLabel for="password" value="Password"/>    <h:inputSecret id="password" value="#{credentials.password}"/></div><div>    <h:commandButton value="Login" action="#{identity.login}"/></div>
AutenticaçãoEscrevendo um método de Autenticação:@Name("authenticator") public class Authenticator {@In EntityManager entityManager; @In Credentials credentials; @In Identity identity;public boolean authenticate() {       try {          User user = (User) entityManager.createQuery(             "from User where username = :username and password = :password")             .setParameter("username", credentials.getUsername())             .setParameter("password", credentials.getPassword())             .getSingleResult();          if (user.getRoles() != null) {             for (UserRole mr : user.getRoles())                identity.addRole(mr.getName());          }          return true;       }       catch (NoResultException ex) {          return false;       }    } }
AutenticaçãoTratando possíveis exceções:<pages>   ...    <exception class="org.jboss.seam.security.NotLoggedInException">        <redirect view-id="/login.xhtml">            <message>You must be logged in to perform this action</message>        </redirect>    </exception>    <exception class="org.jboss.seam.security.AuthorizationException">        <end-conversation/>        <redirect view-id="/security_error.xhtml">            <message>You do not have the necessary security privileges to perform this action.</message>        </redirect>    </exception></pages>
AutenticaçãoRedirecionando os usuários após o logincomponent.xml<event type="org.jboss.seam.notLoggedIn">	<action expression="#{redirect.captureCurrentView}"/></event><event type="org.jboss.seam.postAuthenticate">	<action expression="#{redirect.returnToCapturedView}"/></event>    ...</pages>
AutenticaçãoVocê pode redirecionar o usuário sem autenticidade para uma página de login quando ele tentar acessar uma determinada página<pages login-view-id="/login.xhtml">    <page view-id="/members/*" login-required="true"/> 	    <page view-id="/cadatro.xhtml" login-required="true"/></pages>
AutorizaçãoHá uma série de mecanismos de autorização fornecida pelo Seam Security API para garantir o acesso aos componentes, métodos, e nas páginas. Componentes:@Restrict("#{s:hasRole('admin')}") public void delete() { Páginas:<h:form class="loginForm" rendered="#{not identity.loggedIn}"><page view-id="/reports.xhtml“><restrict>#{s:hasRole('admin')}</restrict></page><h:outputLink action="#{reports.salvar}" rendered="#{s:hasRole('manager')}">Salvar	</h:outputLink>
Exercício 10Vamos implementar a segurança na aplicaçãoCriar 2 perfis e alternar o acesso a botões e páginas
Obrigado ;-)

J boss seam

  • 1.
  • 2.
    O que éJboss Seam?Segundo a definição da Palavra: Seam = EmendaSeam não é um acrônimo (SEAM): Stop Enterprise Application Masochism Software for Enterprise Application Masterpieces
  • 3.
    O que éJboss Seam?Informações gerais:Criado por Gavin King (criador do Hibernate)Versão 1.0 Beta 1 em 18/09/2005Versão 1.0.0.GA lançada em 12/06/2006
  • 4.
    O que éJboss Seam?Versão atual de produção: 2.1.2.GAComunidade extremamente ativa: www.seamframework.orgMais de 1.000 usuários registrados no primeiro mêsAtualmente, mais de 5.000 usuários registrados
  • 5.
    O que éJboss Seam?De acordo com o site oficial : Seam é um framework para Java Enterprise (JavaEE)Seam não é simplesmente outro framework de IntegraçãoNão é também uma resposta ao Spring Framework.
  • 6.
    O que éJboss Seam?Componente unificado: Managed Beans (EJB3)Extensão dos contextos Java Servlet, com aadição do escopo “Conversation”Gerenciamento do PersistenceContextNão faz distinção entre os componentes da camada de apresentação e camada de negócios:business logic componentsVocê cria sua arquitetura e define suas camadas
  • 7.
    O que éJboss Seam? Integração entre  JSF e EJB 3.0 O JBoss Seam faz todo o “trabalho sujo” de integração entre JSF e EJB 3.0, deixando o desenvolvedor concentrado no domínio de negóciosO JBoss Seam foi feito para o JSF:Além do JSF, o JBoss Seam permite outras tecnologias  para a camada de apresentação:Wicket, Tapestry, GWT e Flex (GraniteDS e BlazeDS)Além de não depender do JSF para a camada de Apresentação, o JBoss Seam funciona com ou sem EJB 3.0
  • 8.
    O que éJboss Seam?Tipos de componentes Seam:JavaBeansEJB 3.0:Stateless Session BeansStateful Session BeansEntity BeansMessage-Driven Beans
  • 9.
    O que éJboss Seam?Virtualmente, qualquer classe Java pode se tornar umcomponente Seam@Name (“meuComponente”)public class meuComponente {......}
  • 10.
    O que éJboss Seam?Modelo unificado de componentes:Não há distinção entre componentes da camada deapresentação e componentes da camada de negócios:Não se faz necessário o uso de DTO/VO<h:form> <h:inputText value="#{user.name}“ /> <h:inputText value="#{user.telefone}" /></h:form>@Entity@Name(“user”)public class User { private String name; private String telefone;
  • 11.
    O que éJboss Seam?Modelo unificado de componentes (continuação):O modelo de componentes do JBoss Seam permite autilização direta de POJOs como “backing beans” para aspáginas JSF:• Nada de cadastrar classes no faces-config.xml: <managed-bean> <managed-bean-name>cadastro</managed-bean-name> <managed-bean-class>demo.Cadastro</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean>
  • 12.
    O que éJboss Seam?Elimina camadas/artefatos “desnecessários”:VO/DTO, DAO, Service Locator, OpenSessionInView...VOCÊ monta a arquitetura da sua aplicação, define ascamadas e como elas vão interagir
  • 13.
    O que éJboss Seam?Integração com AJAXSuporte “out of the box” para frameworks open sourcebaseados em JSF:Adiciona suporte AJAX sem a necessidade de codificação de JavaScript pelo desenvolvedorICEfacesJBoss RichFaces:<h:inputText value="#{user.name}" required="true"> <f:validateLength maximum="30" minimum="3"/> <rich:ajaxValidator/> </h:inputText><br/>
  • 14.
    O que éJboss Seam?Possui uma camada de JavaScript remoto:• Acesso aos componentes Seam direto do JavaScript:Integração com:DojoGWTvar meuComp = Seam.Component.newInstance(“meuComp”);meuComp.setXXX(Valor);
  • 15.
    O que éJboss Seam?Estende os contextos definidos pela especificação de Servlets:request (event), page, session e application com dois novos contextos:ConversationBusiness process
  • 16.
    O que éJboss Seam?ConversationConceito chave no JBoss SeamA conversação representa uma “unidade de trabalho” doponto de vista do usuário:Geralmente associada a um Caso de UsoUm usuário pode ter várias conversações ao mesmo tempo:Normalmente em múltiplas janelas do browserFacilita a construção de “wizards”Facilita o uso de AJAX
  • 17.
    O que éJboss Seam?Conversation (continuação)Facilita ainda mais o uso do JPA:Evita a famigerada LIE (LazyInitializationException)Business processContexto Stateful (Banco de Dados)O usuário pode continuar a interação com o sistemamais tarde
  • 18.
    O que éJboss Seam?O JBoss Seam suporta o conceito de Inversão de Controle (IoC) ou Injeção de Dependências (DI), mas vai alémA injeção de dependências funciona bem no modelo de arquitetura stateless, mas, em uma arquitetura stateful, precisamos que a injeção de dependências seja bidirecional:
  • 19.
    O que éJboss Seam?Bijeção (Injeção + Ejeção): Estende o modelo de IoC:• Dinâmica• Contextual• Bidirecional A bijeção ocorre:• Antes e depois das chamadas aos métodos
  • 20.
    O que éJboss Seam?Injection:Componente é recuperado de um contexto (ou criado, dependendo da configuração) e injetado em outro componente:@Inprivate User user;
  • 21.
    Jboss Seam?Outjection:Um componente“ejeta/coloca” outro componente em um contexto:@Out Usuario user;Para criar um componente podemos usar@Factoryprivate void pesquisar() {....}
  • 22.
    Configuração do SeamSeamservlet e listenerServlet que processa todas requisições Seam File: /WEB-INF/web.xml<servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup></servlet>< servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.seam</url-pattern></servlet-mapping>
  • 23.
    Configuração do SeamListener,responsável por “startar” o seam e destruir as sessões e contexto de aplicação<listener><listener-class>org.jboss.seam.servlet.SeamListener</listener-class></listener>
  • 24.
    ConfiguraçãoArquivos requeridos deconfiguração:/WEB-INF/faces.configconfiguração especifica JSF/WEB-INF/components.xmlconfiguração do Seamcolocado em META-INF
  • 25.
    Configuração/WEB-INF/pages.xmlNavegação do SeamÉopcional, mas recomendadoseam.propertiesConfigurações do Seam, geralmente vazio.Deve ser colocado em todo lugar que tiver algum componente Seam (@Name)
  • 26.
  • 27.
    ConfiguraçãoSeam FilterRequerido paracontrole de erro, progagação de conversação WEB-INF/web.xml<filter> <filter-name>Seam Filter</filter-name> <filter-class>org.jboss.seam.servlet.SeamFilter</filter-class> </filter> <filter-mapping> <filter-name>Seam Filter</filter-name> <url-pattern>/pattern>/*</url-pattern></filter-mapping>
  • 28.
    ConfiguraçãoFiltro de tratamentode ErrosErros podem ser mapeados para uma página própria para errosFile: /WEB-INF/pages.xml<exception class="org.jboss.seam.framework.EntityNotFoundException"> <redirect view-id="/error.xhtml"> <message>Not found</message></redirect>
  • 29.
    Exercício 1 Vamoscriar nossa primeira aplicação em Jboss Seam ;-) Cadastro de usuários: igual a versão feita em JSF
  • 30.
  • 31.
    Continuando...Validação:Onde colocar asregras de validação?Na camada de apresentação?Sim, precisamos informar os erros de validação para oUsuárioMas, também temos de garantir as regras/restriçõesna camada de persistência
  • 32.
    ValidaçãoClientes que utilizemas classes de domínio podem fazer um “bypass” da validação (Ex. Aplicação Desktop, WebServices)“Bad design”: Regras de validação fazem parte do objeto de domínio (Persistent Domain Objects)• Melhor opção: colocar a validação nas classes de domínio e reaproveitá-las na camada de apresentação com a utilização de AJAX
  • 33.
    ValidaçãoHibernate Validator:Vários validadorespré-definidos: Max, Min, Length, Range, Size, Email, Future, Past, Pattern, Email, CreditCard, etcFácil customização (Ex: @CPF, @StrongPassword)Funciona com qualquer implementação de JPA:Se utilizado com o Hibernate, gera a DDL com todas as restrições definidas
  • 34.
    ValidaçãoHibernate Validator:Esforço depadronização da especificação Bean ValidatorValidation (JSR 303)Validação na classe de domínio:
  • 35.
    ValidaçãoIntegração do JSF/Faceletscom o Hibernate Validator:O JBoss Seam leva a validação definida no objeto dedomínio para a camada de apresentação: Seam JSF Controls:<s:validate/>, <s:validateAll>
  • 36.
    ValidaçãoLê a anotação(meta-informação) definida e a utilizacomo validador no JSF<s:decorate/>“Decora” o campo quando há algum erro de validação
  • 37.
    Validação (Decorate)<ui:composition xmlns="http://www.w3.org/1999/xhtml"                xmlns:ui="http://java.sun.com/jsf/facelets"                xmlns:h="http://java.sun.com/jsf/html"                xmlns:f="http://java.sun.com/jsf/core"                xmlns:s="http://jboss.com/products/seam/taglib">                     <div>            <s:label styleClass="#{invalid?'error':''}">            <ui:insert name="label"/>            <s:span styleClass="required" rendered="#{required}">*</s:span>        </s:label>                <span class="#{invalid?'error':''}">            <h:graphicImage value="/img/error.gif" rendered="#{invalid}"/>            <s:validateAll>                <ui:insert/>            </s:validateAll>        </span>        <s:message styleClass="error"/>      </div>    </ui:composition>
  • 38.
    Validação (Decorate)Para usar,basta colocar informar o decorate como um template<s:decorate template="edit.xhtml">        <ui:define name="label">Country:</ui:define>        <h:inputText value="#{location.country}" required="true"/</s:decorate>
  • 39.
    Exercício 2Usando validaçãona tela criada anteriormente<s:decorate id="d1" template="layout/edit.xhtml"> <ui:define name="label">Nome:</ui:define> <h:inputText id="username" value="#{pessoa.nome}" required="true" requiredMessage="Campo Obrigatório"/></s:decorate>
  • 40.
    Validação (Ajax)Usando validaçãocom ajax<s:decorate id="d1" template="layout/edit.xhtml"> <ui:define name="label">Nome:</ui:define> <h:inputText id="username" value="#{pessoa.nome}" required="true“> <a4j:support event="onblur" reRender="d1"/></h:inputText></s:decorate>
  • 41.
    Exercício 3Inserir validaçãono sistema, fazer testes com validações,testar também o <rich:beanValidator />Obs: Usando o rich:beanValidator não se faz necessário o uso do <s:validate>, <s:decorate><h:inputText id="telefone" value="#{pessoa.telefone}" required="true" requiredMessage="Obrigatrio"><rich:beanValidator summary=“Telefone Inválido" /></h:inputText><rich:message for="telefone"/>
  • 42.
    Tabelas de DadosParafacilitar ainda mais, o Seam possui a anotação:“DataModel”@DataModelList<Pessoa> pessoas;Pode ser usado com: List, Map, Set ou Object[], assim como o JSF DataModel
  • 43.
    Exercício 4Trocar o@Out por @Datamodel
  • 44.
    Tabelas de DadosObtendovalores selecionados em uma tabela@DataModelSelectionPessoa pessoaSelecionada
  • 45.
    Exercício 5 Usar oDataModelSelection para obter o objeto selecionadoCriar um método para apagar esse objeto
  • 46.
    NavegaçãoStateful navigationPageflow édefinido fora dos componentesValores de retorno das actions são avaliadosNavegação clássica: método da action que decide para onde irPageflow é definido para uma simples conversação
  • 47.
    Navegação<page view-id="/cadastro.xhtml" > <begin-conversation join="true"/> <navigation> <rule if-outcome="lista"> <redirect view-id="/cadastroPessoa.xhtml"/> </rule> </navigation></page>public String salvar() { public String salvar() {.... ....return "lista"; return “/cadastroPessoa.xhtml";} }
  • 48.
  • 49.
    Navegação<page view-id="/cadastroPessoa.xhtml"> <navigation from-action="#{cadastroPessoaAction.apagar()}"> <ruleif-outcome="success"> <redirect view-id="/sucesso.xhtml"/> </rule> </navigation></page><page view-id="/cadastro.xhtml" > <action execute="#{cadastroPessoaAction.listar()}"/></page><page view-id="/cadastro.xhtml" > <action if=“#{condicao}” execute="#{cadastroPessoaAction.listar()}"/></page>
  • 50.
    Navegação<page view-id=“*/login.xhtml"><navigation from-action="#{identity.login}"><ruleif="#{identity.loggedIn}"> <redirect view-id="/home.xhtml"/> </rule></navigation></page><page view-id=“*/login.xhtml“ login-required="true”> .....</page>
  • 51.
    Navegação<pages> <page view-id="/search.xhtml"><param name="searchPattern"value="#{searchService.searchPattern}"/> </page>...</pages>Metodo é executado antes da página ser renderizada.<page view-id="/entry.xhtml"action="#{entryAction.loadBlogEntry(blogEntry.id)}"> <param name="blogEntryId" value="#{blogEntry.id}”validator="#{Validator}" required="true"/></page>
  • 52.
    NavegaçãoPode-se também obtero parâmetro na própria Action implementando um RequestParameter@RequestParameterprivate Long entryId;public void findEntry() { blogentry = em.find(Blogentry.class, entryId);}
  • 53.
    Exercício 6Fazer umexercício de navegação usando o pages.xmlCriar 3 páginas e navegar entre elas usando o pages.xmlUsar chamada de metodo direto no pages.xml
  • 54.
    Contextos SeamStatelessEvent contextPagecontextSessionBusinessApplication
  • 55.
    Contextos SeamStateless: Mesmoconceito do Stateless do EJB criado justamente para integração com este tipo de EJB.Event context: Como o nome mesmo diz os objetos registrados neste contexto apenas vão estar disponíveis durante a execução de um determinado evento.Page context: Contexto já conhecido por todos que trabalham com aplicações web, está associado ao processo de renderização, carregamento, carregamento de uma página.
  • 56.
    Contextos SeamConversation context:É um dos contextos que diferencia o Seam de qualquer outro framework existente no mercado, com este contexto podemos criar unidades de conversação e registrar nestas unidade todos os objetos e serviços que a aplicação vai necessitar usar quando a mesma estiver sendo executada sobre este contexto. Neste contexto mesmo outras instâncias da aplicação sendo acessadas em janelas diferentes não terão acesso aos artefatos registrados no contexto da outra, ou seja, a cada nova instância da aplicação em uma nova janela se caracteriza como uma instância independente assim uma não terá acesso as informações da outra mesmo sendo executadas na mesma instância do browser.
  • 57.
    Contextos SeamSession context:Este também é muito conhecido por todos que trabalham com aplicações Em resumo este contexto inicia quando acessamos a primeira tela da aplicação e só será destruído quando fecharmos nosso browser ou fazermos um logoff implementado pela aplicação.
  • 58.
    Contextos SeamApplication context:E por último o também já conhecido contexto de aplicação, tudo que registrarmos neste contexto fica disponível para todos que acessarem a mesma aplicação, ou seja, devemos registrar neste contexto somente serviços que serão acessados por todos e que são imutáveis pois este contexto só é atualizado no startup do servidor web.
  • 59.
    Contextos SeamBusiness processcontext: Mais um contexto novo criado pelo Seam, este foi criado especialmente para trabalharmos com fluxos de trabalho (workflow), ele garante para nós que qualquer objeto ou serviço registrado neste contexto vai estar disponível até o fim do fluxo. O mesmo fica disponível para múltiplas interações e múltiplos usuários e seu estado é persistente, ou seja, se eu fechar a aplicação e no dia seguinte entrar novamente, os objetos registrados no fluxo em questão estarão ali com as informações deixadas pela última vez.
  • 60.
    Contextos SeamContexto Padrão:Dependedo tipo do componente:Stateless Session Beans?Default em contexto Stateless EntitiesDefault em contexto Conversation
  • 61.
    Contextos Seam Message-DrivenBeans?Padrão sem contexto Stateful Session Beans?Padrão em contexto de ConversaçãoJavaBeans?Padrão em contexto de evento
  • 62.
    Contextos SeamIniciando eEncerrando uma ConversaçãoAnotação@Beginpublic void checkoutShoppingCart(){// ...@Endpublic void confirmCheckout(){
  • 63.
    Contextos SeamNavegação (pages.xml)<pageview-id="/messageList.jsp" action="#{conversation.begin}"/>Ou<page view-id="/messageList.jsp"><begin-conversation /><page><page view-id="/home.jsp"><end-conversation/><page>
  • 64.
    Contextos SeamEm umlink JSF<h:commandLink action="main" value="Select Hotel"><s:conversationPropagation type="begin"/></h:commandLink><h:commandLink action="main" value="Exit"><s:conversationPropagation type="end"/></h:commandLink>Em um Link Seam s:link<s:link view="/checkout.xhtml" propagation="begin"/><s:link view="/confirm.xhtml" propagation="end"/>
  • 65.
    Contextos SeamPropagando aconversaçãoPropaga por padrãoPode ser finalizada<s:link view="/main.xhtml" propagation="none"/><h:commandLink action="main" value="Exit"><f:param name="conversationPropagation" value="none"/></h:commandLink><h:commandLink action="main" value="Exit"><s:conversationPropagation type="none"/></h:commandLink>
  • 66.
    Exercícios 7Abrir efechar conversaçãoTrocar contextos
  • 67.
    EventosTipos de EventosPage action – ocorre antes que a página é carregadaPode ser definido para uma determinada páginaWEB-INF/pages.xml<pages> <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"/></pages>
  • 68.
    EventosPode-se usar “wildcard” para várias páginasWEB-INF/pages.xml<pages><page view-id="/hello/*" action="#{helloWorld.sayHello}"/></pages>
  • 69.
    EventosPode-se também passarparâmetrosWEB-INF/pages.xml<pages> <page view-id="/hello.jsp" action="#{helloWorld.sayHello}"><param name="firstName" value="#{person.firstName}"/> <param name="lastName" value="#{person.lastName}"/> </page></pages>
  • 70.
    EventosPode-se também lançarum evento em uma Action@Name("helloWorld")public class HelloWorld { public void sayHello() { FacesMessages.instance().add("Hello World!");Events.instance().raiseEvent("hello"); }}
  • 71.
    EventosPode-se também lançarum evento em uma Action@Name("helloWorld")public class HelloWorld {@RaiseEvent("hello") public void sayHello() { FacesMessages.instance().add("Hello World!"); }}
  • 72.
    EventosCapturando os eventos@Name("helloListener")publicclass HelloListener {@Observer("hello") public void sayHelloBack() { FacesMessages.instance().add("Hello to you too!"); }}
  • 73.
    Exercício 8Lançar ecapturar eventos
  • 74.
    ExceçõesO desenvolvedor determinacomo tratar uma exceçãoVia anotaçãoDeclarativamente em um arquivo XMLSeam aplica todas regras de rollback das exceções EJB para os componentes JavaBeansSeam da um rollback em qualquer transação ativa quando ocorre uma exceção
  • 75.
    ExceçõesCapturando exceções usandoAnnotações@Redirect(viewId="/failure.xhtml", end=true)@ApplicationException(rollback=true)public class UnrecoverableApplicationException extends RuntimeException { ... }
  • 76.
    ExceçõesCapturando exceções usandoXMLpages.xml<pages><exception class="javax.persistence.EntityNotFoundException"> <http-error error-code="404"/> </exception> <exception class="javax.persistence.PersistenceException"> <end-conversation/><redirect view-id="/error.xhtml"> <message>Database access failed</message> </redirect></exception>
  • 77.
    ExceçõesCapturando exceções usandoXMLpages.xml<exception> <end-conversation/> <redirect view-id="/error.xhtml"> <message>Aconteceu um Erro ;-(</message> </redirect></exception>
  • 78.
    ExceçõesUsando EL nasExceçõesExceções são adicionadas no contexto de conversação org.jboss.seam.handledException <pages> <exception class="org.jboss.seam.security.AuthorizationException"> <end-conversation/> <redirect view-id="/error.xhtml"> <message severity="WARN">#{handledException.message}</message> </redirect> </exception></pages>
  • 79.
    Exercício 9Vamos lancare capturar algumas exceptionLançar Runtime e Exception para ver a diferençaCriar uma tela de erro customizadaObs: não esquecer de desabilitar :debug (component.xml)facelets.DEVELOPMENT (web.xml)
  • 80.
    SegurançaO Seam SecurityAPI fornece uma multiplicidade de funções relacionadas com segurança para seu aplicativo, abrangendo áreas como: Autenticação - permite os usuários autenticar em qualquer fornecedor de segurança. (LDAP, JAAS..)Identity Management - uma API para gerenciar uma aplicação Seam, usuários e papéis em tempo de execução.
  • 81.
    SegurançaAutorização - umframework extremamente abrangente, baseado em regras de permissõesPermission Management - um conjunto de componentes Seam para permitir uma fácil gestão da aplicação da política de segurança.CAPTCHA - para ajudar na prevenção de um software automatizado / scripts abusar seu sistema.
  • 82.
    AutenticaçãoA autenticação fornecidapelo Seam é construída utilizando o JAAS (Java autenticação e autorização de serviço), e como tal, fornecer uma robusta e altamente configurável API para manipulação de autenticação do usuário. No entanto, para exigências menos complexas de autenticação, o Seam oferece um método mais simplificado de autenticação que esconde a complexidade do JAAS.
  • 83.
    AutenticaçãoO método deautenticação simplificada fornecido pelo Seam utiliza um built-in JAAS login módulo:SeamLoginModule, que delega a autenticação para um de seus próprios componentes Seam. Este módulo de login já está configurado dentro Seam como parte de uma aplicação padrão e, como tal, não requer qualquer configuração adicional arquivos.Configurar esta forma simplificada de autenticação exige a configuração no arquivo: components.xml: <security:identity authenticate-method="#{authenticator.authenticate}"/>
  • 84.
    AutenticaçãoEscrevendo uma telade Autenticação:<div>    <h:outputLabel for="name" value="Username"/>    <h:inputText id="name" value="#{credentials.username}"/></div><div>    <h:outputLabel for="password" value="Password"/>    <h:inputSecret id="password" value="#{credentials.password}"/></div><div>    <h:commandButton value="Login" action="#{identity.login}"/></div>
  • 85.
    AutenticaçãoEscrevendo um métodode Autenticação:@Name("authenticator") public class Authenticator {@In EntityManager entityManager; @In Credentials credentials; @In Identity identity;public boolean authenticate() {       try {          User user = (User) entityManager.createQuery(             "from User where username = :username and password = :password")             .setParameter("username", credentials.getUsername())             .setParameter("password", credentials.getPassword())             .getSingleResult();          if (user.getRoles() != null) {             for (UserRole mr : user.getRoles())                identity.addRole(mr.getName());          }          return true;       }       catch (NoResultException ex) {          return false;       }    } }
  • 86.
  • 87.
    AutenticaçãoRedirecionando os usuáriosapós o logincomponent.xml<event type="org.jboss.seam.notLoggedIn"> <action expression="#{redirect.captureCurrentView}"/></event><event type="org.jboss.seam.postAuthenticate"> <action expression="#{redirect.returnToCapturedView}"/></event>    ...</pages>
  • 88.
    AutenticaçãoVocê pode redirecionaro usuário sem autenticidade para uma página de login quando ele tentar acessar uma determinada página<pages login-view-id="/login.xhtml">    <page view-id="/members/*" login-required="true"/>  <page view-id="/cadatro.xhtml" login-required="true"/></pages>
  • 89.
    AutorizaçãoHá uma sériede mecanismos de autorização fornecida pelo Seam Security API para garantir o acesso aos componentes, métodos, e nas páginas. Componentes:@Restrict("#{s:hasRole('admin')}") public void delete() { Páginas:<h:form class="loginForm" rendered="#{not identity.loggedIn}"><page view-id="/reports.xhtml“><restrict>#{s:hasRole('admin')}</restrict></page><h:outputLink action="#{reports.salvar}" rendered="#{s:hasRole('manager')}">Salvar </h:outputLink>
  • 90.
    Exercício 10Vamos implementara segurança na aplicaçãoCriar 2 perfis e alternar o acesso a botões e páginas
  • 91.