Você está na página 1de 147

TREINAMENTOS

Desenvolvimento Web Avanado com JSF2, EJB3.1 e CDI

Desenvolvimento Web Avanado com JSF2, EJB3.1 e CDI

29 de abril de 2011

www.k19.com.br

ii

Sumrio
1 Introduo a EJB 1.1 Por que utilizar EJB? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 EJB Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stateless Session Beans 2.1 Session Beans . . . . . . . . . . . . 2.2 Caracterizando os SLSBs . . . . . . 2.2.1 Servio de Cmbio . . . . . 2.2.2 Dicionrio . . . . . . . . . 2.2.3 Consulta de CEP . . . . . . 2.3 SLSB - EJB 3.0 . . . . . . . . . . . 2.4 SLSB - EJB 3.1 . . . . . . . . . . . 2.5 Cliente Java Web Local - EJB 3.0 . 2.6 Exerccios . . . . . . . . . . . . . . 2.7 Cliente Java Web Local - EJB 3.1 . 2.8 Exerccios . . . . . . . . . . . . . . 2.9 Cliente Java SE Remoto . . . . . . 2.10 Exerccios . . . . . . . . . . . . . . 2.11 Ciclo de Vida . . . . . . . . . . . . 2.11.1 Estados . . . . . . . . . . . 2.11.2 NO EXISTE -> PRONTO 2.11.3 PRONTO -> PRONTO . . . 2.11.4 PRONTO -> NO EXISTE 2.11.5 Escalabilidade e Pool . . . . 2.11.6 Callbacks . . . . . . . . . . 2.12 Exerccios . . . . . . . . . . . . . . Stateful Session Beans 3.1 Caracterizando os SFSBs . . 3.1.1 Carrinho de Compras 3.1.2 Prova Digital . . . . 3.1.3 TrackList . . . . . . 3.2 SFSB - EJB 3.0 . . . . . . . 3.3 SFSB - EJB 3.1 . . . . . . . 3.4 Exerccios . . . . . . . . . . 1 1 2 2 3 3 3 3 4 4 4 5 6 7 18 18 24 25 29 30 30 30 30 31 31 32 33 33 33 34 34 35 36 36

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

iii

SUMRIO 3.5 Ciclo de Vida . . . . . . . . . . . . . . . . . . . . . 3.5.1 Estados . . . . . . . . . . . . . . . . . . . . 3.5.2 NO EXISTE -> PRONTO . . . . . . . . . 3.5.3 PRONTO -> PASSIVADO . . . . . . . . . . 3.5.4 PASSIVADA -> PRONTO . . . . . . . . . . 3.5.5 PRONTO -> NO EXISTE . . . . . . . . . 3.5.6 PASSIVADO -> PRONTO -> NO EXISTE 3.5.7 Callbacks . . . . . . . . . . . . . . . . . . . Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

SUMRIO . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 42 43 43 43 43 44 44 46 47 47 47 47 48 48 49 50 54 54 54 55 56 57 57 57 61 61 62 63 66 66 67 67 68 71 71 71 72 72 72 73 74 74 iv

3.6 4

Singleton Session Beans 4.1 Caracterizando os Singleton Session Beans 4.1.1 Nmero de usurios conectados . . 4.1.2 Sistema de chat . . . . . . . . . . . 4.1.3 Trnsito Colaborativo . . . . . . . . 4.2 Implementao . . . . . . . . . . . . . . . 4.2.1 Singleton Session Beans Locais . . 4.3 Exerccios . . . . . . . . . . . . . . . . . . 4.4 Ciclo de Vida . . . . . . . . . . . . . . . . 4.4.1 Estados . . . . . . . . . . . . . . . 4.4.2 NO EXISTE -> PRONTO . . . . 4.4.3 PRONTO -> NO EXISTE . . . . 4.4.4 Callbacks . . . . . . . . . . . . . . Persistncia 5.1 Data Sources . . . . . . . . . . . . . . . 5.2 Exerccios . . . . . . . . . . . . . . . . . 5.3 persistence.xml . . . . . . . . . . . . . . 5.4 Entity Beans . . . . . . . . . . . . . . . . 5.5 Entity Classes e Mapeamento . . . . . . . 5.6 Exerccios . . . . . . . . . . . . . . . . . 5.7 Entity Managers . . . . . . . . . . . . . . 5.7.1 Obtendo Entity Managers . . . . 5.8 Entity Manager Factories . . . . . . . . . 5.8.1 Obtendo Entity Manager Factories 5.9 Exerccios . . . . . . . . . . . . . . . . . Transaes 6.1 ACID . . . . . . . . . . . . . . . . . . 6.2 Transao Local ou Distribuda . . . . . 6.3 JTA e JTS . . . . . . . . . . . . . . . . 6.4 Container Managed Transactions - CMT 6.4.1 Atributo Transacional . . . . . . 6.4.2 Rollback com SessionContext . 6.4.3 Rollback com Exceptions . . . 6.5 Bean Managed Transactions - BMT . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

. . . . . . . .

www.k19.com.br

SUMRIO 6.6 7

SUMRIO

Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 81 81 81 84 85 89 89 90 90 90 91 93 93 94 94 95 95 96 96 97 97 97 107 107 108 108 108 117 117 118 118 119 119 125 126 126 126 127 127

Segurana 7.1 Realms . . . . . . . . . . . . 7.2 Exerccios . . . . . . . . . . . 7.3 Autenticao - Aplicaes Web 7.4 Exerccios . . . . . . . . . . . 7.5 Autorizao - Aplicaes EJB 7.5.1 @RolesAllowed . . . 7.5.2 @PermitAll . . . . . . 7.5.3 @DenyAll . . . . . . 7.5.4 @RunAs . . . . . . . 7.6 Exerccios . . . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

Interceptadores 8.1 Interceptor Methods . . . . . . . . 8.2 Internal Interceptors . . . . . . . . 8.3 External Interceptors . . . . . . . 8.3.1 Method-Level Interceptors 8.3.2 Class-Level Interceptors . 8.3.3 Default Interceptors . . . 8.4 Excluindo Interceptadores . . . . 8.5 Invocation Context . . . . . . . . 8.6 Ordem dos Interceptadores . . . . 8.7 Exerccios . . . . . . . . . . . . . Scheduling 9.1 Timers . . . . . . . . 9.2 Mtodos de Timeout 9.3 Timers Automticos . 9.4 Exerccios . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

10 Contexts and Dependency Injection - CDI 10.1 Managed Beans . . . . . . . . . . . . 10.2 Producer Methods and Fields . . . . . 10.3 EL Names . . . . . . . . . . . . . . . 10.4 beans.xml . . . . . . . . . . . . . . . 10.5 Exerccios . . . . . . . . . . . . . . . 10.6 Escopos e Contextos . . . . . . . . . 10.7 Injection Points . . . . . . . . . . . . 10.7.1 Bean Constructors . . . . . . 10.7.2 Field . . . . . . . . . . . . . 10.7.3 Initializer methods . . . . . . 10.8 Exerccios . . . . . . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

11 Projeto 129 11.1 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 v K19 Treinamentos

SUMRIO

SUMRIO

www.k19.com.br

vi

Captulo 1 Introduo a EJB


1.1 Por que utilizar EJB?

Muitos sistemas corporativos so construdos seguindo a arquitetura denida pelo padro Enterprise JavaBeans (EJB). Ao utilizar essa arquitetura, as aplicaes ganham certos benefcios. Transaes: A arquitetura EJB dene um suporte sosticado para utilizao de transaes. Esse suporte integrado com a Java Transaction API (JTA) e oferece inclusive a possibilidade de realizar transaes distribudas. Segurana: Suporte para realizar autenticao e autorizao de maneira transparente. Os desenvolvedores das aplicaes no precisam implementar a lgica de segurana pois ela faz parte da arquitetura EJB. Remotabilidade: Aplicaes EJB podem ser acessadas remotamente atravs de diversos protocolos de comunicao. Consequentemente, possvel desenvolver aplicaes clientes de diversos tipos. Em particular, aplicaes EJB podem ser expostas como Web Services. Multithreading e Concorrncia: A arquitetura EJB permite que os sistemas corporativos possam ser acessados por mltiplos usurios simultaneamente de maneira controlada para evitar problemas de concorrncia. Persistncia: Facilidades para utilizar os servios dos provedores de persistncia que seguem a especicao JPA. Gerenciamento de Objetos: Mecanismos de injeo de dependncias e controle de ciclo de vida so oferecidos aos objetos que formam uma aplicao EJB. O mecanismo de controle de ciclo de vida pode garantir acesso a uma quantidade varivel de usurios. Integrao: A arquitetura EJB fortemente integrada com os componentes da plataforma Java EE. Podemos, por exemplo, facilmente integrar uma aplicao JSF com uma aplicao EJB. 1

Introduo a EJB

1.2

EJB Container

As aplicaes EJB executam dentro de um EJB Container pois ele o responsvel pela implementao de vrios recursos oferecidos a essas aplicaes. H diversas implementaes de EJB Container disponveis no mercado que podemos utilizar. Neste curso, utilizaremos a implementao do Glasssh V3. A seguir, vamos instalar e congurar o Glasssh V3.

1.3

Exerccios

1. Na rea de Trabalho, entre na pasta K19-Arquivos e copie glasssh-3.0.1-with-hibernate.zip para o seu Desktop. Descompacte este arquivo na prpria rea de Trabalho. 2. Ainda na rea de Trabalho, entre na pasta glassshv3/glasssh/bin e execute o script startserv para executar o glasssh. 3. Verique se o glasssh est executando atravs de um navegador acessando a url: http://localhost:8080. 4. Pare o glasssh executando o script stopserv que est na mesma pasta do script startserv. 5. No eclipse, abra a view servers e clique com o boto direito no corpo dela. Escolha a opo new e congure o glasssh. 6. Execute o glasssh pela view servers e verique se ele est funcionando acessando atravs de um navegador a url: http://localhost:8080. 7. Pare o glasssh pela view servers.

www.k19.com.br

Captulo 2 Stateless Session Beans


2.1 Session Beans

Um sistema corporativo composto por muitos processos ou tarefas. Por exemplo, um sistema bancrio possui processos especcos para realizar transferncias, depsitos, saques, emprstimos, cobranas, entre outros. Esses procedimentos so chamados de regras de negcio. Cada aplicao possui as suas prprias regras de negcio j que elas so consequncia imediata do contexto da aplicao. Utilizando a arquitetura EJB, as regras de negcio so implementadas em componentes especcos que so chamados de Session Beans. O EJB Container administra esses componentes oferecendo diversos recursos a eles.

2.2

Caracterizando os SLSBs

Stateless Session Bean o primeiro tipo de Session Bean. Muitas vezes, utilizaremos a sigla SLSB para fazer referncia a esse tipo de componente. A ideia fundamental por trs dos SLSBs a no necessidade de manter estado entre as execues das regras de negcio que eles implementam.

2.2.1

Servio de Cmbio

Para exemplicar, suponha uma regra de negcio para converter valores monetrios entre moedas diferentes. Por exemplo, converter 100 reais para o valor correspondente em dlar americano. Poderamos, implementar essa regra de negcio em um nico mtodo.
1 2 3 public double converte(double valor, String moeda1, String moeda2) { // lgica da converso monetria }

Devemos perceber que uma execuo do mtodo CONVERTE () no depende das execues anteriores. Em outras palavras, o mtodo CONVERTE () no precisa manter estado entre as chamadas. 3

Stateless Session Beans

2.2.2

Dicionrio

Outro exemplo, suponha a implementao de um dicionrio de portugus. Dado uma palavra, o dicionrio deve devolver a denio dela. Podemos criar um mtodo para implementar essa regra de negcio.
1 2 3 public String getDefinicao(String palavra) { // lgica do dicionario }

Novamente, perceba que as chamadas ao mtodo getDenicao() so totalmente independentes. Dessa forma, no necessrio guardar informaes referentes s chamadas anteriores.

2.2.3

Consulta de CEP

Mais um exemplo, dado uma localidade podemos consultar o CEP correspondente. Podemos criar um mtodo para implementar essa regra de negcio.
1 2 3 public String consultaCEP(String estado, String cidade, String logradouro, int numero) { // lgica da consulta do CEP }

Como cada consulta de CEP independe das consultas anteriores, no necessrio manter dados entre uma consulta e outra. Em outras palavras, no necessrio manter estado.

2.3

SLSB - EJB 3.0

O primeiro passo para implementar um SLSB denir a sua interface de utilizao atravs de uma interface Java. Por exemplo, suponha um SLSB que implementa algumas operaes matemticas bsicas. Uma possvel interface de utilizao para esse SLSB seria:
1 2 3 4 5 6 public interface Calculadora { double soma(double a, double b); double subtrai(double a, double b); double multiplica(double a, double b); double divide(double a, double b); }

Aps denir a interface de utilizao, o segundo passo seria implementar as operaes do SLSB atravs de uma classe Java. www.k19.com.br 4

Stateless Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class CalculadoraBean implementes Calculadora { public double soma(double a, double b){ return a + b; } public double subtrai(double a, double b) { return a - b; } public double multiplica(double a, double b) { return a * b; } public double divide(double a, double b) { return a / b; } }

O terceiro passo especicar o tipo de Session Bean que queremos utilizar. No caso da calculadora, o tipo seria SLSB. Essa denio realizada atravs da anotao @Stateless.
1 2 3 4 @Stateless public class CalculadoraBean implementes Calculadora { ... }

Por m, necessrio denir se o SLSB poder ser acessado remotamente ou apenas localmente. Quando o acesso a um SLSB local, ele s pode ser acessado por aplicaes que estejam no mesmo servidor de aplicao que ele. Caso contrrio, quando o acesso a um SLSB remoto, ele pode ser acessado tanto por aplicaes que estejam no mesmo servidor de aplicao quanto aplicaes que no estejam. A denio do tipo de acesso realizada atravs das anotaes: @Local e @Remote.
1 2 3 4 5 @Stateless @Remote(Calculadora.class) public class CalculadoraBean implementes Calculadora { ... }

1 2 3 4 5

@Stateless @Local(Calculadora.class) public class CalculadoraBean implementes Calculadora { ... }

2.4

SLSB - EJB 3.1

Na verso 3.1, quando o acesso a um SLSB local, no mais necessrio denir uma interface Java nem utilizar a anotao @L OCAL. Ento, bastaria implementar uma classe Java com a anotao @S TATELESS. 5 K19 Treinamentos

Stateless Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Stateless public class CalculadoraBean { public double soma(double a, double b){ return a + b; } public double subtrai(double a, double b) { return a - b; } public double multiplica(double a, double b) { return a * b; } public double divide(double a, double b) { return a / b; } }

2.5

Cliente Java Web Local - EJB 3.0

Como vimos os session beans so utilizados para implementar as regras negcio das nossas aplicaes. Em particular, os stateless session beans so utilizados para implementar as regras de negcio que no necessitam manter estado. Contudo, alm das regras de negcio, devemos nos preocupar com a interface dos usurios. Hoje em dia, na maioria dos casos, essa interface web. A seguir, vamos implementar um sistema que realiza operaes matemticas bsicas para exemplicar a utilizao da arquitetura EJB em conjunto com as tecnologias Java para desenvolvimento de interfaces web. Suponha que todo o sistema (session beans e a camada web) esteja no mesmo servidor de aplicao. A seguinte interface Java ser utilizada para denir as operaes de um SLSB.
1 2 3 public interface Calculadora { double soma(double a, double b); }

Depois de denir a interface, devemos implementar as operaes do SLSB atravs de uma classe Java com as anotaes apropriadas.
1 2 3 4 5 6 7 @Stateless @Local(Calculadora.class) public class CalculadoraBean implements Calculadora { public double soma(double a, double b) { return a + b; } }

Perceba que o acesso local foi denido para esse SLSB pois ele ser acessado por uma camada web no mesmo servidor de aplicao. Nesse momento, o SLSB est pronto. O prximo passo implementar a camada web. A interface que dene as operaes do SLSB precisa estar no classpath da camada web. J a classe que implementa as operaes no www.k19.com.br 6

Stateless Session Beans precisa estar no classpath da camada web. Suponha que a camada web da nossa aplicao utiliza apenas Servlets. Podemos injetar, atravs da anotao @EJB, o SLSB em uma Servlet.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

@WebServlet("/soma") public class SomaServlet extends HttpServlet { @EJB private Calculadora calculadora; protected void service(HttpServletRequest req, HttpServletResponse res) { double a = Double.parseDouble(request.getParameter("a")); double b = Double.parseDouble(request.getParameter("b")); double resultado = this.calculadora.soma(a, b); PrintWriter out = response.getWriter(); out.println("<html><body><p>"); out.println("Soma: " + resultado); out.println("</p></body></html>"); } }

Agora, suponha que a camada web utilize JSF. Podemos injetar o SLSB em um Managed Bean tambm atravs da anotao @EJB.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

@ManagedBean public class CalculadoraMB { @EJB private Calculadora calculadora; private double a; private double b; private double resultado; public void soma() { this.resultado = this.calculadora.soma(a,b); } // GETTERS AND SETTERSs }

2.6

Exerccios

1. Crie um EJB project no eclipse. Voc pode digitar CTRL+3 em seguida new EJB project e ENTER. Depois, siga exatamente as imagens abaixo. 7 K19 Treinamentos

Stateless Session Beans

www.k19.com.br

Stateless Session Beans

OBS: Trs projetos sero criados:

calculadora: As classes que implementam os SLSB devem ser colocadas nesse projeto. calculadoraClient: As interfaces que denem as operaes dos SLSB devem ser colocadas nesse projeto. calculadoraEAR: Esse projeto empacota todos os mdulos do nosso sistema.

2. Crie um Dynamic Web Project no eclipse para implementar a camada web. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo. 9 K19 Treinamentos

Stateless Session Beans

www.k19.com.br

10

Stateless Session Beans

11

K19 Treinamentos

Stateless Session Beans

www.k19.com.br

12

Stateless Session Beans

OBS: O mdulo web j est vinculado ao projeto calculadoraEAR.

3. Adicione o projeto calculadoraClient como dependncia do projeto calculadoraWeb. Abra as propriedades do projeto calculadoraWeb. Voc pode selecionar o projeto calculadoraWeb e digitar ALT+ENTER. Depois, siga as imagens abaixo. 13 K19 Treinamentos

Stateless Session Beans

www.k19.com.br

14

Stateless Session Beans

4. No projeto calculadoraClient, adicione um pacote chamado sessionbeans e acrescente nele uma interface Java chamada Calculadora.
1 2 3 4 5 package sessionbeans; public interface Calculadora { double soma(double a, double b); }

5. No projeto calculadora, adicione um pacote chamado sessionbeans e acrescente nele uma classe Java chamada CalculadoraBean.
1 2 3 4 5 6 7 8 9 package sessionbeans; @Stateless @Local(Calculadora.class) public class CalculadoraBean implements Calculadora { public double soma(double a, double b) { return a + b; } }

15

K19 Treinamentos

Stateless Session Beans 6. No projeto calculadoraWeb, adicione um pacote chamado managedbeans acrescenta nele uma classe Java chamada CalculadoraMB.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package managedbeans; import javax.ejb.EJB; import javax.faces.bean.ManagedBean; import sessionbeans.Calculadora; @ManagedBean public class CalculadoraMB { @EJB private Calculadora calculadora; private double a; private double b; private double resultado; public void soma() { this.resultado = this.calculadora.soma(a, b); } // GETTERS AND SETTERS }

7. Crie uma simples tela na aplicao web para utilizar o Manager Bean. Adicione o arquivo soma.xhtml na pasta WebContent do projeto calculadoraWeb com o seguinte contedo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Calculadora - Soma</title> </h:head> <h:body> <h:form> <h:outputLabel value="Valor A: "/> <h:inputText value="#{calculadoraMB.a}" ></h:inputText> <h:outputLabel value="Valor B: "/> <h:inputText value="#{calculadoraMB.b}" ></h:inputText> <h:commandButton action="#{calculadoraMB.soma}" value="soma"/> <h:outputLabel value="Resultado: "/> <h:outputText value="#{calculadoraMB.resultado}"/> </h:form> </h:body> </html>

8. Adicione o projeto calculadoraEAR no glasssh. Clique com o boto direito no glaswww.k19.com.br 16

Stateless Session Beans ssh da view Servers e escolha a opo Add and Remove. Depois, siga as imagens abaixo.

17

K19 Treinamentos

Stateless Session Beans 9. Acesse a url http://localhost:8080/calculadoraWeb/soma.xhtml e teste o funcionamento da aplicao.

2.7

Cliente Java Web Local - EJB 3.1

Como dito anteriormente, na verso 3.1, quando o acesso a um SLSB local, no mais necessrio denir uma interface Java nem utilizar a anotao @L OCAL. Alm disso, as regras de empacotamento foram simplicadas. Os Session Beans podem ser empacotados no mdulo web. Isso simplica bastante o funcionamento das IDEs como o eclipse. Perceberemos essa diferena o exerccio seguinte.

2.8

Exerccios

10. Crie um Dynamic Web Project no eclipse para implementar a camada web. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo.

www.k19.com.br

18

Stateless Session Beans

19

K19 Treinamentos

Stateless Session Beans

www.k19.com.br

20

Stateless Session Beans

11. No projeto dadoWeb, adicione um pacote chamado sessionbeans e acrescente nele uma classe Java chamada LancadorDeDadoBean.

1 2 3 4 5 6 7 8 9 10 11 12 13 14

package sessionbeans; import java.util.Random; import javax.ejb.Stateless; @Stateless public class LancadorDeDadoBean { private Random gerador = new Random(); public int lanca(){ return this.gerador.nextInt(5) + 1; } }

12. No projeto dadoWeb, adicione um pacote chamado managedbeans acrescenta nele uma classe Java chamada DadoMB. 21 K19 Treinamentos

Stateless Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package managedbeans; import javax.ejb.EJB; import javax.faces.bean.ManagedBean; import sessionbeans.LancadorDeDadoBean; @ManagedBean public class DadoMB { @EJB private LancadorDeDadoBean lancadorDeDadoBean; private int resultado; public void lancaDado(){ this.resultado = this.lancadorDeDadoBean.lanca(); } public int getResultado() { return resultado; } public void setResultado(int resultado) { this.resultado = resultado; } }

13. Crie uma simples tela na aplicao web para utilizar o Manager Bean. Adicione o arquivo dado.xhtml na pasta WebContent do projeto dadoWeb com o seguinte contedo.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Lanador de dado</title> </h:head> <h:body> <h:form> <h:commandButton action="#{dadoMB.lancaDado}" value="Lana o Dado"/> <h:outputLabel value="Resultado: "/> <h:outputText value="#{dadoMB.resultado}"/> </h:form> </h:body> </html>

14. Adicione o projeto dadoWeb no glasssh. Clique com o boto direito no glasssh da view Servers e escolha a opo Add and Remove. Depois, siga as imagens abaixo. www.k19.com.br 22

Stateless Session Beans

23

K19 Treinamentos

Stateless Session Beans

15. Acesse a url http://localhost:8080/dadoWeb/dado.xhtml e teste o funcionamento da aplicao.

2.9

Cliente Java SE Remoto

Vimos os SLSBs sendo acessados localmente por aplicaes web implantadas no mesmo servidor de aplicao. Contudo, eles podem ser acessados remotamente, ou seja, podem ser acessados por aplicaes fora do mesmo servidor de aplicao. Inclusive, um SLSB pode ser acessado por aplicaes Java SE. Quando o acesso local, podemos injetar um SLSB atravs da anotao @EJB no componente que necessita dos servios implementados pelo SLSB. Agora, quando o acesso remoto, no temos o recurso de injeo de dependncia. Dessa forma, os SLSBs devem ser obtidos de outra maneira. Todo SLSB implantado em um servidor de aplicao recebe um nome. Toda aplicao fora desse servidor de aplicao pode utilizar esse nome para obter a referncia remota do SLSB. Antes da verso 3.1, os nomes dos Session Beans no eram padronizados. Consequentemente, cada servidor de aplicao possua uma regra diferente para nomear os Session Beans. A partir da verso 3.1, os nomes foram padronizados e portanto so portveis (iguais em todos os servidores de aplicao). Consulte a especicao para conhecer as regras de nomenclatura http://jcp.org/en/jsr/detail?id=318. Uma aplicao Java remota deve acessar o servio de nomes (JNDI) do servidor de aplicao no qual o SLSB que ela deseja utilizar est implantado. O trecho de cdigo Java para fazer uma consulta por um SLSB no JNDI teria o seguinte padro. www.k19.com.br 24

Stateless Session Beans


1 2 3 InitialContext ic = new InitialContext(); StatelessSessionBean statelessSessionBean = (StatelessSessionBean) ic.lookup("java:global/aplicacaoWeb/StatelessSessionBean");

Uma vez com a referncia do SLSB, a aplicao pode chamar as operaes normalmente como se o Session Bean estivesse local. Contudo, importante ressaltar que as chamadas so remotas e portanto mais demoradas.

2.10

Exerccios

16. Adicione uma interface Java no pacote sessionbeans chamada LancadorDeDado.

1 2 3 4 5

package sessionbeans; public interface LancadorDeDado { public int lanca(); }

17. Altere a classe LancadorDeDadoBean do projeto dadoWeb.

1 2 3 4 5 6 7 8 9

@Stateless @Remote(LancadorDeDado.class) public class LancadorDeDadoBean implements LancadorDeDado{ private Random gerador = new Random(); public int lanca(){ return this.gerador.nextInt(5) + 1; } }

18. Crie um Java project no eclipse. Voc pode digitar CTRL+3 em seguida new Java project e ENTER. Depois, siga exatamente as imagens abaixo. 25 K19 Treinamentos

Stateless Session Beans

19. Adicione as bibliotecas do Glasssh necessrias para a consulta ao servio de nomes. Abra as propriedades do projeto dadoJavaSE. Voc pode selecionar o projeto dadoJavaSE e digitar ALT+ENTER. Depois, siga as imagens abaixo.

www.k19.com.br

26

Stateless Session Beans

20. Adicione o projeto dadoWeb como dependncia do projeto dadoJavaSE. Abra as pro27 K19 Treinamentos

Stateless Session Beans priedades do projeto dadoJavaSE. Voc pode selecionar o projeto dadoJavaSE e digitar ALT+ENTER. Depois, siga as imagens abaixo

www.k19.com.br

28

Stateless Session Beans

21. No projeto dadoJavaSE, adicione um pacote chamado testes acrescenta nele uma classe Java chamada TesteDeAcesso.
1 2 3 4 5 6 7 8 public class TesteDeAcesso { public static void main(String[] args) throws Exception{ InitialContext ic = new InitialContext(); LancadorDeDado lancadorDeDado = (LancadorDeDado) ic.lookup("java:global/dadoWeb /LancadorDeDadoBean"); System.out.println(lancadorDeDado.lanca()); } }

Execute e conra o resultado no console

2.11

Ciclo de Vida

As instncias dos SLSBs so administradas pelo EJB Container. Devemos entender o de ciclo de vida desses objetos para utilizar corretamente a tecnologia EJB. Trs aspectos fundamentais dos SLSBs nos ajudam a entender o ciclo de vida das instncias. 1. Uma nica instncia de um SLSB pode atender chamadas de diversos clientes. 2. Uma instncia de um SLSB no atende duas chamadas ao mesmo tempo. Em outras palavras, ela processa uma chamada de cada vez. 3. O EJB Container pode criar vrias instncias do mesmo SLSB para atender mais rapidamente as chamadas dos clientes. 29 K19 Treinamentos

Stateless Session Beans

2.11.1

Estados

O ciclo de vida das instncias de um SLSB possui apenas dois estados. 1. NO EXISTE 2. PRONTO

2.11.2

NO EXISTE -> PRONTO

Antes de ser criada, dizemos que uma instncia de um SLSB se encontra no estado NO EXISTE. Obviamente, nesse estado, uma instncia no pode atender chamadas dos clientes. De acordo com a quantidade de chamadas e critrios de cada servidor de aplicao, o EJB Container pode criar novas instncias de um SLSB. Cada instncia criada passa para o estado PRONTO. No estado PRONTO, uma instncia est apta a receber uma chamada.

2.11.3

PRONTO -> PRONTO

Quando uma chamada realizada, o EJB Container seleciona uma instncia entre as que estejam no estado PRONTO para realizar o atendimento. Enquanto, uma instncia est atendendo uma chamada ela no pode atender outras chamadas. Depois de nalizar o atendimento, a instncia volta para o estado PRONTO podendo receber outra chamada.

2.11.4

PRONTO -> NO EXISTE

Novamente, de acordo com a quantidade de chamadas e critrios de cada servidor de aplicao, o EJB Container pode destruir instncias que estejam no estado PRONTO. Essas instncias voltam para o estado NO EXISTE.

www.k19.com.br

30

Stateless Session Beans

2.11.5

Escalabilidade e Pool

As caractersticas dos SLSBs favorecem a escalabilidade da aplicao pois, de acordo com a demanda, o EJB Container cria novas instncias e cada instncia pode atender vrios clientes. O EJB Container administra as instncias criadas atravs de um Pool. Cada servidor de aplicaes oferece conguraes especcas para melhorar a ecincia no atendimento das chamadas. Por exemplo, o Glasssh permite que uma quantidade mxima de instncias de um determinado SLSB seja denido pela aplicao.

2.11.6

Callbacks

Podemos associar lgicas especcas nas transies de estado no ciclo de vida dos SLSBs. @PostConstruct Podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia logo aps ela ser criada. Esse registro realizado atravs da anotao @PostConstruct.
1 2 3 4 5 6 7 8 9 10 @Stateless public class CalculadoraBean { @PostConstruct public void inicializando() { System.out.println("Mais uma calculadora criada...") } // METODOS DE NEGOCIO }

O EJB Container utiliza o construtor sem argumentos para criar uma instncia de um SLSB. Depois de chamar o construtor sem argumentos, o EJB Container injeta eventuais dependncias na instncia criada. Por m, os mtodos anotados com @P OST C ONSTRUCT so executados. @PreDestroy Tambm podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia imediatamente antes dela ser destruda. Esse registro realizado atravs da anotao @PreDestroy.
1 2 3 4 5 6 7 8 9 10 @Stateless public class CalculadoraBean { @PreDestroy public void destruindo() { System.out.println("Mais uma calculadora ser destruda...") } // METODOS DE NEGOCIO }

31

K19 Treinamentos

Stateless Session Beans

2.12

Exerccios

22. Adicione mtodos de callbacks na classe LancadorDeDadoBean do projeto dadoWeb.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Stateless @Remote(LancadorDeDado.class) public class LancadorDeDadoBean implements LancadorDeDado { private Random gerador = new Random(); @PostConstruct public void inicializando(){ System.out.println("Mais um lanador de dado criado..."); } @PreDestroy public void destruindo() { System.out.println("Mais um lanador de dado ser destrudo..."); } public int lanca(){ return this.gerador.nextInt(5) + 1; } }

23. Adicione um teste no pacote testes do projeto dadoJavaSE para fazer consultas em paralelo ao SLSB que lana moedas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class TesteCicloDeVidaSLSB { public static void main(String[] args) throws Exception { InitialContext ic = new InitialContext(); for (int i = 0; i < 100; i++) { final LancadorDeDado lancadorDeDado = (LancadorDeDado) ic .lookup("java:global/dadoWeb/LancadorDeDadoBean"); Thread thread = new Thread(new Runnable() { @Override public void run() { for(int i = 0; i < 100; i++) { System.out.println(lancadorDeDado.lanca()); } } }); thread.start(); } } }

Reinicie o Glasssh depois execute o teste e observe o console para conferir as mensagens dos mtodos de callback 24. Pare o Glasssh e observe o console para conferir as mensagens dos mtodos de callback.

www.k19.com.br

32

Captulo 3 Stateful Session Beans


3.1 Caracterizando os SFSBs

Stateful Session Bean o segundo tipo de Session Bean. Muitas vezes, utilizaremos a sigla SFSB para fazer referncia a esse tipo de componente. A ideia fundamental por trs dos SFSBs a necessidade de manter estado entre as execues das regras de negcio que eles implementam.

3.1.1

Carrinho de Compras

Para exemplicar, suponha o funcionamento de um carrinho de compras de uma loja virtual. As regras de negcio do carrinho podem ser implementas atravs de alguns mtodos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class CarrinhoBean { public void adiciona(Produto produto) { // lgica para adicionar produto } public void remove(Produto produto) { // lgica para remover produto } public void finalizaCompra(){ // lgica para finalizar a compra } }

H duas necessidades fundamentais no exemplo do carrinho de compras que devemos observar. Primeiro, uma instncia da classe C ARRINHO B EAN no deve atender vrios clientes para no misturar produtos escolhidos por clientes diferentes. Segundo, os produtos adicionados devem ser mantidos entre as chamadas dos mtodos da classe C ARRINHO B EAN. Em outras palavras, necessrio manter o estado do carrinho. Provavelmente, o estado do carrinho, ou seja, os produtos adicionados seria mantido em uma lista ou em um conjunto. 33

Stateful Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class CarrinhoBean { private Set<Produto> produtos = new HashSet<Produto>(); public void adiciona(Produto produto) { this.produtos.add(produto); } public void remove(Produto produto) { this.produtos.remove(produto); } public void finalizaCompra(){ // lgica para finalizar a compra } }

3.1.2

Prova Digital

Outro exemplo, suponha o funcionamento de um sistema para aplicar provas que permita que os usurios respondam as questes em qualquer ordem ou modiquem respostas j realizadas antes de nalizar a prova. As resposta poderiam ser mantidas em um mapa.
1 2 3 4 5 6 7 8 9 10 11 class ProvaBean { private Map<Integer, Character> respostas = new HashMap<Integer, Character>(); public void responde(Integer questao, Character resposta) { this.respostas.put(questao, resposta); } public void finaliza(){ // lgica para finalizar a prova } }

Uma instncia da classe P ROVA B EAN no pode atender dois clientes para no misturar as respostas de dois usurios diferentes. Alm disso, as respostas j realizadas devem ser mantidas entre as chamadas.

3.1.3

TrackList

Mais um exemplo, suponha o funcionamento de um player de vdeo que permite que os usurios selecionem um conjunto de vdeos para assistir.
1 2 3 4 5 6 7 8 9 10 11 class ListaDeVideos { private List<Video> videos = new ArrayList<Video>(); public void adiciona(Video video) { this.videos.add(video); } public void embaralha() { Collections.shuffle(this.videos); } }

www.k19.com.br

34

Stateful Session Beans Novamente, cada instncia da classe L ISTA D E V IDEOS deve ser exclusiva para um cliente e os vdeos adicionados devem ser mantidos entre as chamadas dos mtodos.

3.2

SFSB - EJB 3.0

O primeiro passo para implementar um SFSB denir a sua interface de utilizao atravs de uma interface Java. Por exemplo, suponha um SFSB que o funcionamento do carrinho de compras. Uma possvel interface de utilizao para esse Session Bean seria:
1 2 3 4 public interface Carrinho { void adiciona(Produto produto); void remove(Produto produto); }

Aps denir a interface de utilizao, o segundo passo seria implementar as operaes do SFSB atravs de uma classe Java.
1 2 3 4 5 6 7 8 9 10 11 12 public class CarrinhoBean implements Carrinho { private Set<Produto> produtos = new HashSet<Produto>(); public void adiciona(Produto produto) { this.produtos.add(produto); } public void remove(Produto produto) { this.produtos.remove(produto); } }

O terceiro passo especicar o tipo de Session Bean que queremos utilizar. No caso do carrinho, o tipo seria SFSB. Essa denio realizada atravs da anotao @Stateful.
1 2 3 4 @Stateful public class CarrinhoBean implements Carrinho { ... }

Por m, necessrio denir se o SFSB poder ser acessado remotamente ou apenas localmente. Quando o acesso a um SLSB local, ele s pode ser acessado por aplicaes que estejam no mesmo servidor de aplicao que ele. Caso contrrio, quando o acesso a um SLSB remoto, ele pode ser acessado tanto por aplicaes que estejam no mesmo servidor de aplicao quanto aplicaes que no estejam. A denio do tipo de acesso realizada atravs das anotaes: @Local e @Remote.
1 2 3 4 5 @Stateful @Remote(Carrinho.class) public class CarrinhoBean implements Carrinho { ... }

35

K19 Treinamentos

Stateful Session Beans


1 2 3 4 5 @Stateful @Local(Carrinho.class) public class CarrinhoBean implements Carrinho { ... }

3.3

SFSB - EJB 3.1

Na verso 3.1, quando o acesso a um SFSB local, no mais necessrio denir uma interface Java nem utilizar a anotao @L OCAL. Ento, bastaria implementar uma classe Java com a anotao @S TATEFUL.

1 2 3 4 5 6 7 8 9 10 11 12 13

@Stateful public class CarrinhoBean { private Set<Produto> produtos = new HashSet<Produto>(); public void adiciona(Produto produto) { this.produtos.add(produto); } public void remove(Produto produto) { this.produtos.remove(produto); } }

3.4

Exerccios

1. Crie um Dynamic Web Project no eclipse para implementar o funcionamento do carrinho de compras. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo. www.k19.com.br 36

Stateful Session Beans

37

K19 Treinamentos

Stateful Session Beans

www.k19.com.br

38

Stateful Session Beans

39

K19 Treinamentos

Stateful Session Beans

2. Crie um pacote chamado sessionbeans e adicione a seguinte classe.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

package sessionbeans; import java.util.HashSet; import java.util.Set; import javax.ejb.Stateful; @Stateful public class CarrinhoBean { private Set<String> produtos = new HashSet<String>(); public void adiciona(String produto){ this.produtos.add(produto); } public void remove(String produto){ this.produtos.remove(produto); } public Set<String> getProdutos() { return produtos; } }

3. Crie um pacote chamado managedbeans e adicione a seguinte classe. www.k19.com.br 40

Stateful Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package managedbeans; import java.util.ArrayList; import java.util.List; import javax.ejb.EJB; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import sessionbeans.CarrinhoBean; @ManagedBean @SessionScoped public class CarrinhoMB { @EJB private CarrinhoBean carrinhoBean; private String produto; public List<String> getProdutos(){ return new ArrayList<String>(this.carrinhoBean.getProdutos()); } public void adiciona(){ this.carrinhoBean.adiciona(this.produto); } public void remove(String produto){ this.carrinhoBean.remove(produto); } public void setProduto(String produto) { this.produto = produto; } public String getProduto() { return produto; } }

4. Adicione o arquivo produtos.xhtml na pasta WebContent do projeto carrinhoWeb com o seguinte contedo. 41 K19 Treinamentos

Stateful Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"> <h:head> <title>Carrinho de Compras</title> </h:head> <h:body> <h:form> <h:outputLabel value="Produto: "/> <h:inputText value="#{carrinhoMB.produto}"/> <h:commandButton action="#{carrinhoMB.adiciona}" value="Adiciona no carrinho"/> <hr/> <h:outputLabel value="Produtos no carrinho:"/> <h:dataTable value="#{carrinhoMB.produtos}" var="p"> <h:column> <h:outputText value="#{p}"/> </h:column> <h:column> <h:commandLink action="#{carrinhoMB.remove(p)}" value="remove" /> </h:column> </h:dataTable> </h:form> </h:body> </html>

5. Adicione o projeto carrinhoWeb no glasssh e teste a aplicao acessando a url http: //localhost:8080/carrinhoWeb/produtos.xhtml. 6. (Opcional) Faa o carrinho de compras permitir que os produtos sejam cadastrados com quantidade. Por exemplo, o usurio pode adicionar 5 canetas no seu carrinho.

3.5

Ciclo de Vida

As instncias dos SFSBs so administradas pelo EJB Container. Devemos entender o de ciclo de vida desses objetos para utilizar corretamente a tecnologia EJB. Para entender mais facilmente o ciclo de vida das instncias dos SFSBs, devemos sempre ter em mente que cada instncia atende apenas um cliente.

3.5.1

Estados

O ciclo de vida das instncias de um SFSB possui trs estados. 1. NO EXISTE 2. PRONTO 3. PASSIVADO www.k19.com.br 42

Stateful Session Beans

3.5.2

NO EXISTE -> PRONTO

Antes de ser criada, dizemos que uma instncia de um SFSB se encontra no estado NO EXISTE. Obviamente, nesse estado, uma instncia no pode atender as chamadas do seu cliente. Quando um cliente recebe por injeo ou recupera por lookup um SFSB, o EJB Container cria uma nova instncia desse SFSB para atender exclusivamente esse cliente. Nesse instante, logo aps ser criada, a instncia se encontra no estado PRONTO e pode atender as chamadas do seu respectivo cliente.

3.5.3

PRONTO -> PASSIVADO

Uma instncia de um SFSB ca ociosa enquanto no estiver processando uma chamada do seu cliente. Para no consumir a memria do computador, depois de um certo tempo de ociosidade, o EJB Container pode transferir o contedo de uma instncia ociosa para dispositivos secundrios de armazenamento (hard disk). Esse processo de transferncia chamado de passivao. Aps ser passivada, a instncia ociosa se encontrar no estado PASSIVADO. Outros fatores alm da ociosidade podem levar o EJB Container decidir passivar instncias dos SFSBs. Por exemplo, quando um certo limite de instncias no estado PRONTO (ocupando memria) for atingido.

3.5.4

PASSIVADA -> PRONTO

Se o cliente de uma instncia passivada realizar uma chamada a ela, o EJB Container realizar automaticamente o processo de ativao. Esse processo consiste na transferncia do contedo da instncia passivada para a memria principal novamente. Aps ser ativada, a instncia se encontrar no estado PRONTO e apta a atender a chamada realizada.

3.5.5

PRONTO -> NO EXISTE

Em determinadas situaes, uma instncia de um SFSB pode no ser mais til. Em outras palavras, o cliente correspondente pode no precisar mais dela. Por exemplo, quando o cliente de um carrinho de compras naliza a compra, a instncia que representa o carrinho pode ser destruda (no compensa reaproveitar o mesmo carrinho para outro cliente). O EJB Container o responsvel por destruir uma instncia de um SFSB que no mais til. Por outro lado, a aplicao responsvel por determinar quando uma instncia se torna intil. Adicionando um mtodo de negcio anotado com @Remove a aplicao declara que aps a execuo desse mtodo a instncia no mais necessria. No exemplo do carrinho de compras, poderamos denir um mtodo para implementar a lgica de nalizar compra e anot-lo com @R EMOVE. Dessa forma, logo aps a execuo desse mtodo a instncia seria destruda pelo EJB Container. 43 K19 Treinamentos

Stateful Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Stateful public class CarrinhoBean { private Set<String> produtos = new HashSet<String>(); public void adiciona(String produto){ this.produtos.add(produto); } public void remove(String produto){ this.produtos.remove(produto); } public Set<String> getProdutos() { return produtos; } @Remove public void finalizaCompra(){ // lgica para finalizar compra } }

3.5.6

PASSIVADO -> PRONTO -> NO EXISTE

Uma instncia pode ser passivada porque cou ociosa quando estava no estado PRONTO. Ou seja, o respectivo cliente no realizou nenhuma chamada durante um grande perodo de tempo. Da mesma maneira, quando passivada, uma instncia pode no receber uma chamada do seu cliente durante um grande perodo de tempo. Nesses casos, o EJB Container pode assumir que o cliente no chamar mais a instncia passivada e portanto ela no mais til. Quando uma instncia passivada no mais til, o EJB Container ativa e depois a destri.

3.5.7

Callbacks

Podemos associar lgicas especcas nas transies de estado no ciclo de vida dos SFSBs. www.k19.com.br 44

Stateful Session Beans @PostConstruct Podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia logo aps ela ser criada. Esse registro realizado atravs da anotao @PostConstruct.
1 2 3 4 5 6 7 8 9 10 @Stateless public class CarrinhoBean { @PostConstruct public void inicializando() { System.out.println("Mais um carrinho criado..."); } // METODOS DE NEGOCIO }

O EJB Container utiliza o construtor sem argumentos para criar uma instncia de um SLSB. Depois de chamar o construtor sem argumentos, o EJB Container injeta eventuais dependncias na instncia criada. Por m, os mtodos anotados com @P OST C ONSTRUCT so executados. @PreDestroy Tambm podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia imediatamente antes dela ser destruda. Esse registro realizado atravs da anotao @PreDestroy.
1 2 3 4 5 6 7 8 9 10 @Stateless public class CarrinhoBean { @PreDestroy public void destruindo() { System.out.println("Mais um carrinho ser destrudo..."); } // METODOS DE NEGOCIO }

@PrePassivate Tambm podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia imediatamente antes dela ser passivada. Esse registro realizado atravs da anotao @PrePassivate.
1 2 3 4 5 6 7 8 9 10 @Stateless public class CarrinhoBean { @PrePassivate public void passivando() { System.out.println("Mais um carrinho ser passivado..."); } // METODOS DE NEGOCIO }

45

K19 Treinamentos

Stateful Session Beans @PostActivate Tambm podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia imediatamente depois dela ser ativada. Esse registro realizado atravs da anotao @PostActivate.
1 2 3 4 5 6 7 8 9 10 @Stateless public class CarrinhoBean { @PostActivate public void ativando() { System.out.println("Mais um carrinho foi ativado..."); } // METODOS DE NEGOCIO }

3.6

Exerccios

7. Implemente uma aplicao com interface web para aplicar provas.

www.k19.com.br

46

Captulo 4 Singleton Session Beans


4.1 Caracterizando os Singleton Session Beans

Singleton Session Bean o terceiro tipo de Session Bean. Este tipo de Session Bean surgiu na verso 3.1 da especicao Enterprise Java Beans. A ideia fundamental por trs desse tipo de Session Bean a necessidade de compartilhar dados transientes entre todos os usurios de uma aplicao EJB.

4.1.1

Nmero de usurios conectados

Para exemplicar, suponha que seja necessrio contabilizar a nmero de usurios conectados aplicao. Esse servio pode ser implementado atravs de uma classe.
1 2 3 4 5 6 7 8 9 10 11 12 class ContadorDeUsuariosBean { private int contador = 0; public void adiciona() { this.contador++; } public int getContador() { return this.contador; } }

Uma nica instncia da classe C ONTADOR D E U SUARIOS B EAN deve ser criada para contabilizar corretamente o nmero de usurios conectados. Alm disso, o contador de usurios conectados no precisa ser persistido entre duas execues da aplicao.

4.1.2

Sistema de chat

Outro exemplo, suponha o funcionamento de um sistema de chat no qual as salas so criadas dinamicamente pelos usurios durante a execuo. Podemos denir alguns mtodos para implementar esse sistema. 47

Singleton Session Beans


1 2 3 4 5 6 7 8 9 10 11 class ChatBean { private Set<String> salas = new HashSet<String>(); public void criaSala(String sala) { this.salas.add(sala); } public List<String> listaSalas(){ return new ArrayList<String>(this.salas); } }

As salas so criadas dinamicamente e todos os usurios compartilham todas as salas. Se o sistema cair por qualquer que seja o motivo no necessrio guardar as salas pois na prxima execuo novas salas sero criadas pelos usurios. Uma nica instncia da classe C HAT B EAN deve ser criada.

4.1.3

Trnsito Colaborativo

Mais um exemplo, suponha um sistema colaborativo para informar o grau de congestionamento nas vias de uma cidade. As regras desse sistema poderiam ser implementadas atravs de alguns mtodos.
1 2 3 4 5 6 7 8 9 10 11 12 13 class TransitoBean { private Map<String,List<Integer>> vias = new HashMap<String,List<Integer>>(); public void registra(String via, Integer velocidade) { if(this.vias.containsKey(via)) { this.vias.get(via).add(velocidade); } } public List<Integer> getVelocidadesRegistradas(String via) { return this.vias.get(via); } }

Os dados sobre o trnsito so fornecidos pelos usurios e todos podem consultar as mesmas informaes. A princpio, no necessrio manter esses dados persistidos.

4.2

Implementao

Para implementar um Singleton Session Bean podemos denir uma interface Java com as assinaturas dos mtodos desejados. Por exemplo, suponha que um Singleton Session Bean ser utilizado para implementar um sistema de chat.
1 2 3 4 public interface Chat { void criaSala(String sala); List<String> listaSalas(); }

Aps denir a interface de utilizao, o segundo passo seria implementar as operaes do Session Bean atravs de uma classe Java. www.k19.com.br 48

Singleton Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 public class ChatBean implements Chat { private Set<String> salas = new HashSet<String>(); public void criaSala(String sala) { this.salas.add(sala); } public List<String> listaSalas(){ return new ArrayList<String>(this.salas); } }

O terceiro passo especicar o tipo de Session Bean que queremos utilizar. No caso do chat, o tipo seria Singleton. Essa denio realizada atravs da anotao @Singleton.
1 2 3 4 @Singleton public class ChatBean implements Chat { ... }

Por m, necessrio denir se o Session Bean poder ser acessado remotamente ou apenas localmente. Quando o acesso a um Session Bean local, ele s pode ser acessado por aplicaes que estejam no mesmo servidor de aplicao que ele. Caso contrrio, quando o acesso a um Session Bean remoto, ele pode ser acessado tanto por aplicaes que estejam no mesmo servidor de aplicao quanto aplicaes que no estejam. A denio do tipo de acesso realizada atravs das anotaes: @Local e @Remote.
1 2 3 4 5 @Singleton @Remote(Chat.class) public class ChatBean implements Chat { ... }

1 2 3 4 5

@Singleton @Local(Chat.class) public class ChatBean implements Chat { ... }

4.2.1

Singleton Session Beans Locais

Quando o acesso a um Singleton Session Bean local, no necessrio denir uma interface Java nem utilizar a anotao @L OCAL. Ento, bastaria implementar uma classe Java com a anotao @S INGLETON. 49 K19 Treinamentos

Singleton Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 @Singleton public class ChatBean { private Set<String> salas = new HashSet<String>(); public void criaSala(String sala) { this.salas.add(sala); } public List<String> listaSalas(){ return new ArrayList<String>(this.salas); } }

4.3

Exerccios

1. Crie um Dynamic Web Project no eclipse para implementar o funcionamento de um sistema de chat. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo.

www.k19.com.br

50

Singleton Session Beans

51

K19 Treinamentos

Singleton Session Beans

2. Crie um pacote chamado sessionbeans e adicione a seguinte classe.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

package sessionbeans; import java.util.HashSet; import java.util.Set; import javax.ejb.Singleton; @Singleton public class ChatBean { private Set<String> salas = new HashSet<String>(); public void criaSala(String sala) { this.salas.add(sala); } public List<String> listaSalas(){ return new ArrayList<String>(this.salas); } }

3. Crie um pacote chamado managedbeans e adicione a seguinte classe. www.k19.com.br 52

Singleton Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package managedbeans; import java.util.List; import javax.ejb.EJB; import javax.faces.bean.ManagedBean; import sessionbeans.ChatBean; @ManagedBean public class ChatMB { @EJB private ChatBean chatBean; private String sala; public void adicionaSala() { this.chatBean.criaSala(this.sala); } public List<String> getSalas() { return this.chatBean.listaSalas(); } public void setSala(String sala) { this.sala = sala; } public String getSala() { return sala; } }

4. Adicione o arquivo chat.xhtml na pasta WebContent do projeto chatWeb com o seguinte contedo. 53 K19 Treinamentos

Singleton Session Beans


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Chat</title> </h:head> <h:body> <h:form> <h:outputLabel value="Nova Sala: "/> <h:inputText value="#{chatMB.sala}"/> <h:commandButton value="Criar" action="#{chatMB.adicionaSala}"/> <hr/> <h:dataTable value="#{chatMB.salas}" var="sala"> <h:column> <h:outputText value="#{sala}" /> </h:column> </h:dataTable> </h:form> </h:body> </html>

5. Adicione o projeto chatWeb no glasssh e teste a aplicao acessando a url http: //localhost:8080/chatWeb/chat.xhtml atravs de dois navegadores. 6. (Opcional) Implemente a remoo de salas.

4.4

Ciclo de Vida

As instncias dos Singleton Session Beans so administradas pelo EJB Container. Devemos entender o de ciclo de vida desses objetos para utilizar corretamente a tecnologia EJB. Para entender mais facilmente o ciclo de vida das instncias dos Singleton Session Beans, devemos sempre ter em mente que o EJB Container cria apenas uma instncia de cada Session Bean desse tipo.

4.4.1

Estados

O ciclo de vida das instncias dos Singleton Session Beans possui dois estados. 1. NO EXISTE 2. PRONTO

4.4.2

NO EXISTE -> PRONTO

Antes de ser criada, dizemos que uma instncia de um Singleton Session Bean se encontra no estado NO EXISTE. Obviamente, nesse estado, uma instncia no pode atender as chamadas dos clientes da aplicao. www.k19.com.br 54

Singleton Session Beans O EJB Container cria apenas uma instncia para cada Singleton Session Bean. Por padro, o EJB Container quem decide quando a criao da instncia de um Singleton Session Bean deve ser realizada. Contudo, possvel determinar que essa criao seja realizada na inicializao da aplicao atravs da anotao @Startup.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Singleton @Startup class ContadorDeUsuariosBean { private int contador = 0; public void adiciona() { this.contador++; } public int getContador() { return this.contador; } }

Quando a instncia de um Singleton Session Bean criada, ela passa para do estado NO EXISTE para o estado PRONTO e pode atender as chamadas dos clientes da aplicao.

4.4.3

PRONTO -> NO EXISTE

Quando a aplicao nalizada, o EJB Container destri as instncias dos Singleton Session Beans. Dessa forma, elas passam do estado PRONTO para o NO EXISTE.

55

K19 Treinamentos

Singleton Session Beans

4.4.4

Callbacks

Podemos associar lgicas especcas nas transies de estado no ciclo de vida dos Singleton Session Beans. @PostConstruct Podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia logo aps ela ser criada. Esse registro realizado atravs da anotao @PostConstruct.
1 2 3 4 5 6 7 8 9 10 @Singleton class ContadorDeUsuariosBean { @PostConstruct public void inicializando() { System.out.println("Contador de usurios criado..."); } // METODOS DE NEGOCIO }

O EJB Container utiliza o construtor sem argumentos para criar a instncia de um Singleton Session Bean. Depois de chamar o construtor sem argumentos, o EJB Container injeta eventuais dependncias na instncia criada. Por m, os mtodos anotados com @P OST C ONSTRUCT so executados. @PreDestroy Tambm podemos registrar um mtodo de instncia no EJB Container para que ele o execute em cada instncia imediatamente antes dela ser destruda. Esse registro realizado atravs da anotao @PreDestroy.
1 2 3 4 5 6 7 8 9 10 @Singleton class ContadorDeUsuariosBean { @PreDestroy public void destruindo() { System.out.println("Contador de usurios ser destrudo..."); } // METODOS DE NEGOCIO }

www.k19.com.br

56

Captulo 5 Persistncia
5.1 Data Sources

Aplicaes Java se comunicam com banco de dados atravs de conexes JDBC. Para estabelecer uma conexo JDBC, algumas informaes como usurio, senha e base de dados so necessrias. As conguraes relativas s conexes JDBC podem ser denidas nas aplicaes ou nos servidores de aplicao. Quando denidas em uma aplicao sero utilizadas somente por essa aplicao. Quando denidas em um servidor de aplicao podem ser utilizadas em diversas aplicaes. Em um servidor de aplicao, as conguraes JDBC so denidas em componentes chamados Data Sources. A criao de Data Sources depende do servidor de aplicao utilizado. Em particular, no Glasssh, os Data Sources podem ser criados atravs da interface de administrao. Os Data Sources permitem que uma nica congurao JDBC seja utilizada por diversas aplicaes. Eles tambm permitem que outros tipos de conguraes sejam compartilhadas. Por exemplo, a congurao de um Connection Pool. Alm disso, atravs de Data Sources podemos utilizar o servio de transaes dos servidores de aplicao. Esse servio denido pela especicao Java Transaction API (JTA).

5.2

Exerccios

1. Copie o arquivo mysql-connector-java-5.1.13-bin.jar que se encontra na pasta K19Arquivos/MySQL-Connector-JDBC da rea de Trabalho para a pasta glassshv3/glasssh/lib tambm da rea de Trabalho. 2. Atravs do MySQL Query Browser, apague a base de dados k22 caso ela exista. Depois, crie uma base de dados chamada k22. 3. Com o Glasssh inicializado, abra a interface de administrao acessando a url localhost: 4848. Siga os passos abaixo: 57

Persistncia

4. Dena os seguintes valores para as seguintes propriedades: DatabaseName: k22 Password: root ServerName: localhost URL: jdbc:mysql://localhost:3306/k22 url: jdbc:mysql://localhost:3306/k22 user: root www.k19.com.br 58

Persistncia Depois, clique em nish.

5. Para testar o Connection Pool K19, siga os passos abaixo:

59

K19 Treinamentos

Persistncia

OBS: A mensagem Ping Succeeded deve aparecer.

6. Agora vamos criar o Data Source. Siga os passos abaixo:

www.k19.com.br

60

Persistncia

5.3

persistence.xml

Em um ambiente Java EE, diversas conguraes relativas persistncia so realizadas nos Data Sources. Contudo, algumas conguraes ainda devem ser realizadas pelas aplicaes. A especicao JPA determina que cada aplicao contenha um arquivo de conguraes chamado persistence.xml dentro de uma pasta chamada META-INF no classpath da aplicao. No arquivo persistece.xml podemos denir qual Data Source ser utilizado pela aplicao.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="K19" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/K19</jta-data-source> <properties> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect. MySQL5InnoDBDialect"/> </properties> </persistence-unit> </persistence>

5.4

Entity Beans

As regras de negcio de uma aplicao EJB so implementadas nos Session Beans. Por outro lado, os dados da aplicao que devem ser persistidos so armazenados em objetos cha61 K19 Treinamentos

Persistncia mados Entity Beans. So exemplos de Entity Beans que poderiam formar uma aplicao: clientes produtos pedidos funcionrios fornecedores

5.5

Entity Classes e Mapeamento

Os Entity Beans so denidos por classes java (Entity Classes). As Entity Classes devem ser mapeadas para tabelas no banco de dados atravs de anotaes ou XML. As principais anotaes de mapeamento so: @Entity a principal anotao do JPA. Ela que deve aparecer antes do nome de uma classe. E deve ser denida em todas as classes que tero objetos persistidos no banco de dados. As classes anotadas com @E NTITY so mapeadas para tabelas. Por conveno, as tabelas possuem os mesmos nomes das classes. Mas, podemos alterar esse comportamento utilizando a anotao @TABLE. Os atributos declarados em uma classe anotada com @E NTITY so mapeados para colunas na tabela correspondente classe. Outra vez, por conveno, as colunas possuem os mesmos nomes dos atributos. E novamente, podemos alterar esse padro utilizando para isso a anotao @C OLUMN. @Id Utilizada para indicar qual atributo de uma classe anotada com @E NTITY ser mapeado para a chave primria da tabela correspondente classe. Geralmente o atributo anotado com @I D do tipo L ONG. @GeneratedValue Geralmente vem acompanhado da anotao @I D. Serve para indicar que o valor de um atributo que compe uma chave primria deve ser gerado pelo banco no momento em que um novo registro inserido. Supondo uma aplicao que administra livros e autores. As seguintes classes so exemplos de Entity Classes mapeadas com anotaes que poderiam ser utilizadas no contexto dessa aplicao:
1 2 3 4 5 6 7 8 9 10 11 12 @Entity public class Livro { @Id @GeneratedValue private Long id; private String nome; private Double preco; // GETTERS AND SETTERS }

www.k19.com.br

62

Persistncia
1 2 3 4 5 6 7 8 9 10 11 12 13 @Entity public class Autor { @Id @GeneratedValue private Long id; private String nome; @ManyToMany private List<Livro> livros; // GETTERS AND SETTERS }

Consulte a apostila do curso Persistncia com JPA 2 para obter detalhes sobre o mapeamento das Entity Classes http://www.k19.com.br/downloads/apostilas-java.

5.6

Exerccios

7. Crie um Dynamic Web Project no eclipse chamado persistenciaWeb. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo.

63

K19 Treinamentos

Persistncia

www.k19.com.br

64

Persistncia

8. Adicione uma pasta chamada META-INF na pasta src do projeto persistenciaWeb. 9. Faa as conguraes de persistncia adicionando o arquivo persistence.xml na pasta META-INF.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="K19" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/K19</jta-data-source> <properties> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect. MySQL5InnoDBDialect"/> </properties> </persistence-unit> </persistence>

10. Crie um pacote chamado entidades no projeto persistenciaWeb e adicione nesse pacote uma Entity Class para denir os livros de uma editora. 65 K19 Treinamentos

Persistncia
1 2 3 4 5 6 7 8 9 10 11 12 @Entity public class Livro { @Id @GeneratedValue private Long id; private String nome; private Double preco; // GETTERS AND SETTERS }

11. Adicione no pacote entidades uma Entity Class para denir autores dos livros de uma editora.
1 2 3 4 5 6 7 8 9 10 11 12 13 @Entity public class Autor { @Id @GeneratedValue private Long id; private String nome; @ManyToMany private List<Livro> livros = new ArrayList<Livro>(); // GETTERS AND SETTERS }

12. Adicione o projeto persistenciaWeb no glasssh. Clique com o boto direito no glasssh da view Servers e escolha a opo Add and Remove.

5.7

Entity Managers

Os Entity Managers so objetos que administram os Entity Beans. As principais responsabilidade dos Entity Managers so: Recuperar as informaes armazenadas no banco de dados. Montar Entity Beans com os dados obtidos do banco de dados atravs de consultas. Sincronizar o contedo dos Entity Beans com os registros das tabelas do banco de dados. Consulte a apostila do curso Persistncia com JPA 2 para obter detalhes sobre o funcionamento dos Entity Managers http://www.k19.com.br/downloads/apostilas-java.

5.7.1

Obtendo Entity Managers

Em um ambiente Java SE, o controle da criao e do fechamento dos Entity Managers responsabilidade das aplicaes. Uma aplicao Java SE deve chamar, explicitamente, o mtodo CREATE E NTITY M ANAGER () em uma Entity Manager Factory para obter um novo Entity Manager ou o mtodo CLOSE () em um Entity Manager para fech-lo.
1 EntityManager manager = factory.createEntityManager();

www.k19.com.br

66

Persistncia
1 manager.close();

Por outro lado, em um ambiente Java EE, o gerenciamento dos Entity Managers pode ser atribudo ao servidor de aplicao. Nesse caso, para uma aplicao Java EE obter um Entity Manager, ela pode utilizar o recurso de Injeo de Dependncia oferecido pelo servidor de aplicao. Por exemplo, dentro de um Session Bean, podemos pedir a injeo de um Entity Manager atravs da anotao @PersistenceContext.
1 2 3 4 5 6 7 8 @Stateless public class CalculadoraBean { @PersisteceContext private EntityManager manager; // Resto do cdigo }

5.8

Entity Manager Factories

As Entity Managers Factories so objetos responsveis pela criao de Entity Managers de acordo com as conguraes denidas no arquivo PERSISTENCE . XML, nos Data Sources e atravs das anotaes de mapeamento nas Entity Classes.

5.8.1

Obtendo Entity Manager Factories

Em um ambiente Java SE, uma Entity Manager Factory obtida atravs do mtodo esttico createEntityManagerFactory() da classe Persistence.
1 EntityManagerFactory factory = Persistence.createEntityManagerFactory("unidade");

O mtodo createEntityManagerFactory() deve ser chamado apenas uma vez a cada execuo da aplicao. No necessrio cham-lo mais do que uma vez porque a aplicao no necessita de mais do que uma Entity Manager Factory e o custo de criao desse objeto alto. Por outro lado, em um ambiente Java EE, o controle sobre a criao das Entity Manager Factories responsabilidade do servidor de aplicao. Inclusive, o servidor de aplicao evita a criao de fbricas desnecessrias. Se uma aplicao Java EE deseja obter a Entity Manager Factory criada pelo servidor de aplicao, ela deve utilizar a anotao @PersistenceUnit para pedir a injeo desse objeto.
1 2 3 4 5 6 7 8 @Stateless public class CalculadoraBean { @PersisteceUnit private EntityManagerFactory factory; // Resto do cdigo }

Em geral, as aplicaes Java EE no necessitam interagir diretamente com as Entity Manager Factories. Na verdade, o comum utilizar diretamente os Entity Managers que so obtidos com a anotao @P ERSISTECE C ONTEXT.
1 2 @Stateless public class CalculadoraBean {

67

K19 Treinamentos

Persistncia
3 4 5 6 7 8

@PersisteceContext private EntityManager manager; // Resto do cdigo }

5.9

Exerccios

13. Crie um pacote chamado sessionbeans no projeto persistenciaWeb e adicione nesse pacote um SLSB para funcionar como repositrio de livros.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Stateless public class LivroRepositorio { @PersistenceContext private EntityManager manager; public void adiciona(Livro livro) { this.manager.persist(livro); } public List<Livro> getLivros() { TypedQuery<Livro> query = this.manager.createQuery( "select x from Livro x", Livro.class); return query.getResultList(); } }

14. Crie um pacote chamado managedbeans no projeto persistenciaWeb e adicione nesse pacote um Managed Bean para oferecer algumas aes para as telas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @ManagedBean public class LivroMB { @EJB private LivroRepositorio repositorio; private Livro livro = new Livro(); private List<Livro> livrosCache; public void adiciona(){ this.repositorio.adiciona(this.livro); this.livro = new Livro(); this.livrosCache = null; } public List<Livro> getLivros(){ if(this.livrosCache == null){ this.livrosCache = this.repositorio.getLivros(); } return this.livrosCache; } public Livro getLivro() { return livro; } public void setLivro(Livro livro) { this.livro = livro; } }

www.k19.com.br

68

Persistncia 15. Crie uma tela para cadastrar livros. Adicione na pasta WebContent um arquivo chamado livros.xhtml com o seguinte contedo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Livros</title> </h:head> <h:body> <h1>Novo Livro</h1> <h:form> <h:outputLabel value="Nome: "/> <h:inputText value="#{livroMB.livro.nome}"/> <h:outputLabel value="Preo: "/> <h:inputText value="#{livroMB.livro.preco}"/> <h:commandButton action="#{livroMB.adiciona}" value="Salvar"/> </h:form> <h1>Lista de Livros</h1> <h:dataTable value="#{livroMB.livros}" var="livro"> <h:column> <h:outputText value="#{livro.nome}"/> </h:column> <h:column> <h:outputText value="#{livro.preco}"/> </h:column> </h:dataTable> </h:body> </html>

16. (Opcional) Implemente a remoo e alterao de livros. 17. (Opcional) Implemente a adio, listagem, remoo e alterao de autores.

69

K19 Treinamentos

Persistncia

www.k19.com.br

70

Captulo 6 Transaes
Geralmente, uma aplicao realiza diversas tarefas diferentes. Tambm comum e muitas vezes necessrio dividir as tarefa em pequenos passos. Da surge o conceito de transao. Uma transao um conjunto de passos que devem ser executados em uma ordem especca para que uma determinada tarefa seja realizada. Tipicamente, as transaes modicam informaes armazenadas em resources (bases de dados, las de mensagens, sistemas corporativos de informao - EIS, entre outros).

6.1

ACID

Alm da restrio natural de ordem, as transaes possuem outras quatro propriedades fundamentais: Atomicidade, Consistncia, Isolamento e Durabilidade. A sigla ACID utilizada para indicar a existncia dessas propriedades. Atomicidade: Todos os passos de uma transao devem ser executados com sucesso para que a prpria transao seja executada com sucesso. Se algum passo falhar a transao falhar e todos os passos realizados at o momento da falha sero desfeitos. Consistncia: No pode existir inconsistncia nos dados da aplicao nem antes nem depois da execuo de uma transao. Ou seja, uma transao leva a aplicao de um estado consistente para outro estado consistente. Isolamento: Alteraes realizadas por uma transao no nalizada no podem afetar operaes que no fazem parte da transao. Durabilidade: Aps a conrmao de uma transao, as modicaes realizadas por ela devem ser reetidas nos resources mesmo que acontea uma falha de hardware.

6.2

Transao Local ou Distribuda

Quando as alteraes realizadas por uma transao afetam apenas um resource (bases de dados, las de mensagens, sistemas corporativos de informao - EIS, entre outros), dizemos que a transao local. Caso contrrio, se dois ou mais resources so modicados por uma nica transao ela dita distribuda. 71

Transaes

6.3

JTA e JTS

Todo servidor de aplicao Java EE deve oferecer suporte para as aplicaes utilizarem transaes. As especicaes relacionadas a esse tpico so: Java Transaction API - JTA e Java Transaction Service - JTS. Os documentos dessas especicaes podem ser obtidos atravs do site: www.jcp.org. A especicao Enterprise Java Beans (EJB) fortemente integrada com as especicaes JTA e JTS, simplicando bastante o trabalho dos desenvolvedores de aplicao EJB que no precisam em momento nenhum lidar diretamente com JTS e muito pouco com JTA. Na arquitetura EJB, as aplicaes podem gerenciar as transaes de dois modos:

Container Managed Transactions - CMT Bean Managed Transactions - BMT

6.4

Container Managed Transactions - CMT

Quando optamos pelo gerenciamento CMT, a responsabilidade de abrir, conrmar ou abortar transaes atribuda ao EJB Container. Contudo, a aplicao deve indicar ao EJB Container atravs de conguraes quando ele deve abrir, conrmar ou abortar transaes. Podemos denir o modo CMT individualmente para cada Session Bean da nossa aplicao atravs da anotao @TransactionManagement.
1 2 3 4 5 @Stateful @TransactionManagement(TransactionManagementType.CONTAINER) public class CarrinhoBean { ... }

O modo CMT padro. Dessa forma, tecnicamente, no necessrio acrescentar a anotao @T RANSACTION M ANAGEMENT. Mas, podemos adicion-la com o intuito de explicitar a opo de gerenciamento transacional.

6.4.1

Atributo Transacional

O EJB Container abre, conrma, aborta ou suspende transaes de acordo com o atributo transacional de cada mtodo dos Session Beans em modo CMT. O atributo transacional de um mtodo pode ser denido com um dos seguintes valores: REQUIRED, REQUIRES_NEW, SUPPORTS, MANDATORY, NOT_SUPPORTED e NEVER. O comportamento do EJB Container o seguinte: www.k19.com.br 72

Transaes Atributo Transacional REQUIRED REQUIRED REQUIRES_NEW REQUIRES_NEW SUPPORTS SUPPORTS MANDATORY MANDATORY NOT_SUPPORTED NOT_SUPPORTED NEVER NEVER J existia uma transao aberta? NO SIM NO SIM NO SIM NO SIM NO SIM NO SIM O que o EJB Container faz? Abre uma nova transao Usa a transao que j estava aberta Abre uma nova transao Abre uma transao e Suspende a que estava aberta No faz nada Usa a transao que j estava aberta Lana EJBTransactionRequiredException Usa a transao que j estava aberta No faz nada Suspende a que estava aberta No faz nada Lana EJBException

O atributo transacional de um mtodo pode ser denido pela anotao @TransactionAttribute.


1 2 3 4 @TransactionAttribute(TransactionAttributeType.REQUIRED) public void adiciona(String produto){ ... }

Quando queremos que todos os mtodos de um Session Bean possuam o mesmo atributo transacional, devemos anotar a classe com @T RANSACTIONATTRIBUTE.
1 2 3 4 5 6 @Stateful @TransactionManagement(TransactionManagementType.CONTAINER) @TransactionAttribute(TransactionAttributeType.REQUIRED) public class CarrinhoBean { ... }

Caso nenhum atributo transacional seja denido explicitamente, o EJB Container utilizar por padro o REQUIRED.

6.4.2

Rollback com SessionContext

Quando algum erro identicado pela aplicao, ela pode marcar a transao corrente para rollback atravs do SET ROLLBACKO NLY () do Session Context que pode ser obtido atravs de injeo com a anotao @R ESOURCE. 73 K19 Treinamentos

Transaes
1 2 3 4 5 6 7 8 9 10 11 12 13 @Stateful public class CarrinhoBean { @Resource private SessionContext context; public void adiciona(String produto){ if(produto == null){ context.setRollbackOnly(); } ... } }

6.4.3

Rollback com Exceptions

Quando exceptions ocorrem, transaes podem ser abortadas pelo EJB Container. Devemos entender a classicao das exceptions para saber quando as transaes sero abortadas. Na arquitetura EJB, as exceptions so classicadas em dois grupos: System Exceptions: Todas Unchecked Exceptions e as JAVA . RMI .R EMOTE E XCEPTION, por padro, so consideradas System Exceptions. Application Exceptions: Todas Checked Exceptions exceto as JAVA . RMI .R EMOTE E XCEPTION, por padro, so consideradas Application Exceptions. Por padro, quando um mtodo de um Session Bean lana uma System Exception, o EJB Container aborta a transao corrente. Por outro lado, quando uma Application Exception lanada, o EJB Container no aborta a transao corrente. Podemos utilizar a anotao @ApplicationException para alterar a classicao de uma System Exception.
1 2 3 4 @ApplicationException public class ValorNegativoException extends RuntimeException { }

A mesma anotao pode alterar o comportamento padro para rollback das Application Exceptions.
1 2 3 4 @ApplicationException(rollback=true) public class ValorNegativoException extends RuntimeException { }

6.5

Bean Managed Transactions - BMT

Quando optamos pelo gerenciamento BMT, a responsabilidade de abrir, conrmar ou abortar transaes atribuda a aplicao. Podemos denir o modo BMT individualmente para cada Session Bean da nossa aplicao atravs da anotao @TransactionManagement. www.k19.com.br 74

Transaes
1 2 3 4 5 @Stateful @TransactionManagement(TransactionManagementType.BEAN) public class CarrinhoBean { ... }

No modo BMT, devemos injetar um UserTransaction atravs da anotao @R ESOURCE. Esse objeto permite que a aplicao abra, conrme ou aborte transaes.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18

@Stateful @TransactionManagement(TransactionManagementType.BEAN) public class CarrinhoBean { @Resource private UserTransaction ut; public void adiciona(Produto p) { try { ut.begin(); // IMPLEMENTACAO ut.commit(); } catch(ProdutoInvalidoException e) { ut.rollback(); } catch (Exception e) { e.printStackTrace(); } } }

O modo BMT permite um controle maior sobre as transaes. Contudo, o modo CMT mais simples de utilizar e mais fcil de manter.

6.6

Exerccios

1. Crie um Dynamic Web Project no eclipse chamado transacoesWeb. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo. 75 K19 Treinamentos

Transaes

www.k19.com.br

76

Transaes

77

K19 Treinamentos

Transaes 2. Adicione uma pasta chamada META-INF na pasta src do projeto transacoesWeb. 3. Faa as conguraes de persistncia adicionando o arquivo persistence.xml na pasta META-INF.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="K19" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/K19</jta-data-source> <properties> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect. MySQL5InnoDBDialect"/> </properties> </persistence-unit> </persistence>

4. Crie um pacote chamado entidades no projeto transacoesWeb e adicione nesse pacote uma Entity Class para denir os produtos de uma loja.
1 2 3 4 5 6 7 8 9 10 11 12 @Entity public class Produto { @Id @GeneratedValue private Long id; private String nome; private double preco; // GETTERS AND SETTERS }

5. Crie um pacote chamado sessionbeans no projeto transacoesWeb e adicione nesse pacote um SLSB para funcionar como repositrio de produtos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Stateless public class ProdutoRepositorio { @PersistenceContext private EntityManager manager; @Resource private SessionContext context; public void adiciona(Produto produto) { this.manager.persist(produto); if(produto.getPreco() < 0){ this.context.setRollbackOnly(); } } public List<Produto> getProdutos() { TypedQuery<Produto> query = this.manager.createQuery(

www.k19.com.br

78

Transaes
19 20 21 22 23 "select x from Produto x", Produto.class); return query.getResultList(); } }

6. Crie um pacote chamado managedbeans no projeto transacoesWeb e adicione nesse pacote um Managed Bean para oferecer algumas aes para as telas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @ManagedBean public class ProdutoMB { @EJB private ProdutoRepositorio repositorio; private Produto produto = new Produto(); private List<Produto> produtosCache; public void adiciona(){ this.repositorio.adiciona(this.produto); this.produto = new Produto(); this.produtosCache = null; } public List<Produto> getProdutos(){ if(this.produtosCache == null){ this.produtosCache = this.repositorio.getProdutos(); } return this.produtosCache; } public void setProduto(Produto produto) { this.produto = produto; } public Produto getProduto() { return produto; } }

7. Adicione o projeto persistenciaWeb no glasssh. Clique com o boto direito no glasssh da view Servers e escolha a opo Add and Remove.

8. Crie uma tela para adicionar produtos. 79 K19 Treinamentos

Transaes
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Produtos</title> </h:head> <h:body> <h1>Novo Produto</h1> <h:form> <h:outputLabel value="Nome: "/> <h:inputText value="#{produtoMB.produto.nome}"/> <h:outputLabel value="Preo: "/> <h:inputText value="#{produtoMB.produto.preco}"/> <h:commandButton action="#{produtoMB.adiciona}" value="Salvar"/> </h:form> <h1>Lista de Produtos</h1> <h:dataTable value="#{produtoMB.produtos}" var="produto"> <h:column> <h:outputText value="#{produto.nome}"/> </h:column> <h:column> <h:outputText value="#{produto.preco}"/> </h:column> </h:dataTable> </h:body> </html>

9. Adicione alguns produtos e observe que produtos com preo negativo no so persistidos devido ao rollback.

www.k19.com.br

80

Captulo 7 Segurana
Para muitas aplicaes, a segurana um aspecto obrigatrio. Da segurana podemos extrair dois processos fundamentais: Autenticao e Autorizao. O processo de autenticao consiste na identicao dos usurios atravs de algum tipo de certicado (usurio e senha). J o processo de autorizao determina o que cada usurio autenticado pode acessar dentro da aplicao. Na plataforma Java, esses dois processos so padronizados pela especicao JAAS (Java Authentication and Authorization Service).

7.1

Realms

Em um ambiente Java EE, para realizar o processo de autenticao, devemos criar um ou mais Realms. Um Realm uma base de dados na qual os usurios de uma ou mais aplicaes esto cadastrados. Infelizmente, as conguraes necessrias para criar um Realm no so padronizadas, ou seja, cada servidor de aplicao as realiza da sua prpria maneira. Veremos no exerccio como criar um Realm no Glasssh.

7.2

Exerccios

1. Com o Glasssh inicializado, abra a interface de administrao acessando a url localhost: 4848. Siga os passos abaixo: 81

Segurana

2. Adicione um usurio chamado K19 dentro de um grupo chamado admin com a senha K19. Siga os passos abaixo: www.k19.com.br 82

Segurana

83

K19 Treinamentos

Segurana

3. Repita o processo do exerccio anterior e cadastre os seguintes usurios: Usurio keizo afk Grupo admin users Senha keizo afk

7.3

Autenticao - Aplicaes Web

Geralmente, o processo de autenticao realizado na camada web. Portanto, vamos restringir a nossa discusso a esse tipo de aplicao. A maior parte das conguraes referentes ao processo de autenticao que as aplicaes web devem realizar so denidas no arquivo web.xml. Contudo, alguns servidores de aplicao www.k19.com.br 84

Segurana exigem conguraes extras. Veremos no exerccio como congurar uma aplicao web no Glasssh para realizar o processo de autenticao.

7.4

Exerccios

4. Crie um Dynamic Web Project no eclipse chamado segurancaWeb. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo.

85

K19 Treinamentos

Segurana

www.k19.com.br

86

Segurana

87

K19 Treinamentos

Segurana

5. Acrescente no arquivo sun-web.xml do projeto segurancaWeb o seguinte trecho de cdigo logo aps o elemento CONTEXT- ROOT.

1 2 3 4 5 6 7 8 9

<security-role-mapping> <role-name>ADMIN</role-name> <group-name>admin</group-name> </security-role-mapping> <security-role-mapping> <role-name>USERS</role-name> <group-name>users</group-name> </security-role-mapping>

Essa congurao especca do Glasssh. Os grupos so utilizados pelo Glasssh e os roles pela aplicao.

6. Acrescente no arquivo web.xml do projeto segurancaWeb o seguinte trecho de cdigo dentro do elemento WEB - APP. www.k19.com.br 88

Segurana
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <login-config> <auth-method>BASIC</auth-method> <realm-name>K19-Realm</realm-name> </login-config> <security-constraint> <web-resource-collection> <web-resource-name>resources</web-resource-name> <url-pattern>/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <role-name>ADMIN</role-name> <role-name>USERS</role-name> </auth-constraint> </security-constraint>

7. Adicione o arquivo index.xhtml na pasta WebContent do projeto segurancaWeb com seguinte contedo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Segurana</title> </h:head> <h:body> <h1>Voc est autenticado!</h1> </h:body> </html>

8. Adicione o projeto segurancaWeb no glasssh. Clique com o boto direito no glasssh da view Servers e escolha a opo Add and Remove. 9. Acesse atravs de um navegador a url http://localhost:8080/segurancaWeb/ index.xhtml e teste o processo de autenticao.

7.5

Autorizao - Aplicaes EJB

Podemos limitar o acesso dos usurios aos mtodos de um Session Bean. Por exemplo, possvel declarar que um determinado mtodo de um Session Bean s pode ser chamado por usurios administradores ou moderadores.

7.5.1

@RolesAllowed

Restries de acesso podem ser denidas pela anotao @RolesAllowed que pode ser aplicada na classe ou nos mtodos de um Session Bean. Se aplicada na classe valer para todos 89 K19 Treinamentos

Segurana os mtodos. Se aplicada ao mesmo tempo na classe e em algum mtodo, valer as restries denidas no mtodo.
1 2 3 4 1 2 3 4 5 @RolesAllowed({"administrador", "moderador"}) public void adiciona(Produto produto){ this.manager.persist(produto); } @RolesAllowed({"administrador", "moderador"}) @Stateful class CarrinhoBean { ... }

7.5.2

@PermitAll

Podemos utilizar a anotao @PermitAll para permitir que qualquer tipo de usurio tenha acesso. Para conseguir o mesmo efeito com a anotao @RolesAllowed, teramos que listar todos os Roles. Alm disso, caso um Role fosse criado ou destrudo, alteraes seriam necessrias.
1 2 3 4 1 2 3 4 5 @PermitAll public void adiciona(Produto produto){ this.manager.persist(produto); } @PermitAll @Stateful class CarrinhoBean { ... }

7.5.3

@DenyAll

O funcionamento da anotao @DenyAll exatamente o oposto da @P ERMITA LL. Podemos utilizar a anotao @D ENYA LL em aplicaes que so implantadas em ambientes diferentes. Sendo que em determinados ambientes certas funcionalidades devem ser desabilitadas.
1 2 3 4 1 2 3 4 5 @DenyAll public void adiciona(Produto produto){ this.manager.persist(produto); } @DenyAll @Stateful class CarrinhoBean { ... }

7.5.4

@RunAs

Eventualmente, um Session Bean chama outro Session Bean. Suponha, que os mtodos do primeiro possam ser executados por usurios moderadores e os mtodos do segundo por administradores. Para que o primeiro Session Bean possa chamar o Segundo, temos que denir o papel de administrador para o primeiro Session Bean atravs da anotao @RunAs. www.k19.com.br 90

Segurana
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @Stateless @RunAs("administrador") class MensagemRepositorio { @PersistenceContext private EntityManager manager; @EJB private TopicoRepositorio topicoRepositorio; @RolesAllowed({"moderador"}) public void remove(Long id){ Mensagem m = this.manager.find(Mensagem.class, id); this.manager.remove(m); Topico t = m.getTopico(); if(t.getMensagens().size() == 1){ this.topicoRepositorio.remove(t); } } }

7.6

Exerccios

10. Crie um pacote chamado sessionbeans no projeto segurancaWeb e adicione nesse pacote um Singleton Session Bean.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Singleton public class TarefasBean { private List<String> tarefas = new ArrayList<String>(); @RolesAllowed({"ADMIN", "USERS"}) public void adiciona(String tarefa){ this.tarefas.add(tarefa); } @RolesAllowed({"ADMIN", "USERS"}) public List<String> listaTarefas() { return this.tarefas; } @RolesAllowed({"ADMIN"}) public void remove(String tarefa){ this.tarefas.remove(tarefa); } }

11. Crie um pacote chamado managedbeans no projeto segurancaWeb e adicione nesse pacote um Managed Bean.
1 2 3 4 5 6 7 8 9 10 11 @ManagedBean public class TarefasMB { @EJB private TarefasBean tarefasBean; private String tarefa; public void adiciona(){ this.tarefasBean.adiciona(this.tarefa); }

91

K19 Treinamentos

Segurana
12 13 14 15 16 17 18 19 20 21 22

public void remove(String tarefa){ this.tarefasBean.remove(tarefa); } public List<String> getTarefas(){ return this.tarefasBean.listaTarefas(); } // GETTERS AND SETTERS }

12. Altere o arquivo index.xhtml do projeto segurancaWeb.


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Segurana</title> </h:head> <h:body> <h1>Voc est autenticado!</h1> <h1>Nova Tarefa</h1> <h:form> <h:outputLabel value="Tarefa: " /> <h:inputText value="#{tarefasMB.tarefa}" /> <h:commandButton action="#{tarefasMB.adiciona}" value="Salvar" /> <h1>Lista de Tarefas</h1> <h:dataTable value="#{tarefasMB.tarefas}" var="tarefa"> <h:column> <h:outputText value="#{tarefa}" /> </h:column> <h:column> <h:commandLink action="#{tarefasMB.remove(tarefa)}">remove</ h:commandLink> </h:column> </h:dataTable> </h:form> </h:body> </html>

13. Adicione e remova tarefas utilizando todos os usurios cadastrados. Observe que usurios com Role USERS no conseguem remover tarefas.

www.k19.com.br

92

Captulo 8 Interceptadores
Uma aplicao EJB pode denir, atravs de mtodos de callback, lgicas a serem executadas pelo EJB Container quando uma instncia de um Session Bean muda de estado. O mtodo de callback PostConstruct executado quando uma instncia de um Session Bean de qualquer tipo muda do estado NO EXISTE para o PRONTO. O mtodo de callback PreDestroy executado quando uma instncia de um Session Bean muda do estado PRONTO para o NO EXISTE. O mtodo de callback PrePassivate executado quando uma instncia de um Stateful Session Bean muda do estado PRONTO para o PASSIVADO. O mtodo de callback PostActivate executado quando uma instncia de um Stateful Session Bean muda do estado PASSIVADO para o PRONTO. H um mtodo de callback para cada uma das seguintes transies: NO EXISTE->PRONTO, PRONTO->PASSIVADO, PASSIVADO->PRONTO e PRONTO->NO EXISTE. Alm dessas transies, podemos considerar que toda vez que um mtodo de negcio chamado ocorre a transio PRONTO->PRONTO. No h mtodo de callback para essa transio especial. Contudo, na arquitetura EJB, podemos utilizar a ideia de interceptadores para conseguir executar lgicas antes ou depois da execuo de um mtodo de negcio. comum utilizar interceptadores para tarefas que no esto diretamente relacionadas s regras de negcio implementadas nos Session Beans. Por exemplo, podemos implementar logging ou controle de acesso com interceptadores.

8.1

Interceptor Methods

A lgica de um interceptador denida dentro de um mtodo anotado com @AroundInvoke ou registrado atravs de XML. No h restries em relao a visibilidade desse mtodo, ou seja, ele pode ser pblico, protegido, padro ou privado. Contudo, ele deve possuir uma assinatura compatvel com o seguinte formato:
1 Object <METODO>(InvocationContext) throws Exception

Veja um exemplo concreto de mtodo interceptador: 93

Interceptadores
1 2 3 4 5 6 7 8 9 10 11 12 @AroundInvoke public Object interceptador(InvocationContext ic) throws Exception { // IDA System.out.println("ANTES DO MTODO DE NEGCIO"); // CHAMANDO O MTODO DE NEGCIO E PEGANDO O SEU RETORNO Object retornoDoMetodoDeNegocio = ic.proceed(); // VOLTA System.out.println("DEPOIS DO MTODO DE NEGCIO"); return retornoDoMetodoDeNegocio; }

8.2

Internal Interceptors

Um interceptador interno criado quando um mtodo interceptador denido dentro de um Session Bean. Cada Session Bean pode ter no mximo um interceptador interno. Um interceptador interno atua em todos os mtodos de negcio do seu respectivo Session Bean.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Stateless class CalculadoraBean { // MTODOS DE NEGCIO // MTODOS DE CALLBACK // MTODO INTERCEPTADOR @AroundInvoke public Object interceptador(InvocationContext ic) throws Exception { // IDA System.out.println("ANTES DO MTODO DE NEGCIO"); // CHAMANDO O MTODO DE NEGCIO E PEGANDO O SEU RETORNO Object retornoDoMetodoDeNegocio = ic.proceed(); // VOLTA System.out.println("DEPOIS DO MTODO DE NEGCIO"); return retornoDoMetodoDeNegocio; } }

8.3

External Interceptors

Os interceptadores externos so criados quando um mtodo interceptador denido fora de um Session Bean em uma classe comum. Novamente, no mais do que um mtodo interceptador pode ser denido em uma mesma classe.
1 2 3 4 5 6 7 8 9 10 11 12 class LoggingInterceptor { @AroundInvoke public Object interceptador(InvocationContext ic) throws Exception { // IDA System.out.println("ANTES DO MTODO DE NEGCIO"); // CHAMANDO O MTODO DE NEGCIO E PEGANDO O SEU RETORNO Object retornoDoMetodoDeNegocio = ic.proceed(); // VOLTA System.out.println("DEPOIS DO MTODO DE NEGCIO");

www.k19.com.br

94

Interceptadores
13 14 15 return retornoDoMetodoDeNegocio; } }

8.3.1

Method-Level Interceptors

Interceptadores externos podem ser associados a mtodos de negcio atravs da anotao @Interceptors.
1 2 3 4 5 6 7 8 @Stateless class CalculadoraBean { @Interceptors({LoggingInterceptor.class}) public double soma(double a, double b){ return a + b; } }

Vrios interceptadores externos podem ser associados a um mtodo de negcio atravs da anotao @I NTERCEPTORS.
1 2 3 4 5 6 7 8 @Stateless class CalculadoraBean { @Interceptors({LoggingInterceptor.class, SegurancaInterceptor.class}) public double soma(double a, double b){ return a + b; } }

8.3.2

Class-Level Interceptors

Interceptadores externos tambm podem ser associados a Session Beans atravs da anotao @Interceptors. Quando associado a um Session Bean, um interceptador externo ser aplicado a todos os mtodos de negcio desse Session Bean.
1 2 3 4 5 6 7 8 @Stateless @Interceptors({LoggingInterceptor.class}) class CalculadoraBean { public double soma(double a, double b){ return a + b; } }

Vrios interceptadores externos podem ser associados a um Session Bean atravs da anotao @I NTERCEPTORS.
1 2 3 4 5 6 7 8 @Stateless @Interceptors({LoggingInterceptor.class, SegurancaInterceptor.class}) class CalculadoraBean { public double soma(double a, double b){ return a + b; } }

95

K19 Treinamentos

Interceptadores

8.3.3

Default Interceptors

Interceptadores externos tambm podem ser associados a mtodos de negcio atravs de conguraes adicionadas no arquivo de congurao do EJB, o ejb-jar.xml. Esse arquivo deve ser colocado em uma pasta chamada META-INF dentro do mdulo EJB da aplicao. Por exemplo, suponha que o interceptador externo denido pela classe L OGGING I NTER CEPTOR tenha que ser aplicado em todos os mtodos de negcio de todos os Session Beans.
1 2 3 4 <interceptor-binding> <ejb-name>*</ejb-name> <interceptor-class>interceptadores.LoggingInterceptor</interceptor-class> </interceptor-binding>

Ou podemos aplicar a apenas um Session Bean.


1 2 3 4 <interceptor-binding> <ejb-name>sessionbeans.CalculadoraBean</ejb-name> <interceptor-class>INTERCEPTOR</interceptor-class> </interceptor-binding

8.4

Excluindo Interceptadores

Podemos excluir os Default Interceptors e os Class-Level Interceptors atravs das anotaes @ExcludeDefaultInterceptors e @ExcludeClassInterceptors respectivamente. A anotao @E XCLUDE D EFAULT I NTERCEPTORS pode ser aplicada em um mtodo de negcio ou no Session Bean.
1 2 3 4 5 6 7 8 @Stateless @ExcludeDefaultInterceptors class CalculadoraBean { public double soma(double a, double b){ return a + b; } }

A anotao @E XCLUDE C LASS I NTERCEPTORS pode ser aplicada em um mtodo de negcio.


1 2 3 4 5 6 7 8 9 @Stateless @Interceptors({LoggingInterceptor.class, SegurancaInterceptor.class}) class CalculadoraBean { @ExcludeClassInterceptors public double soma(double a, double b){ return a + b; } }

www.k19.com.br

96

Interceptadores

8.5

Invocation Context

Um mtodo interceptador recebe um Invocation Context como parmetro. Atravs dos Invocation Context, os mtodos interceptadores podem acessar a instncia do Session Bean que ser utilizada para atender a chamada, descobrir qual mtodo de negcio ser executado, quais parmetros foram passados e at mesmo trocar os parmetros antes de chegar no mtodo de negcio. Veja os mtodos disponveis nessa interface.
1 2 3 4 5 6 7 8 public interface InvocationContext { public Object getTarget(); public Method getMethod(); public Object[] getParameters(); public void setParameters(Object[]); public java.util.Map<String,Object> getContextData(); public Object proceed() throws Exception; }

8.6

Ordem dos Interceptadores

A ordem na qual os interceptadores so executados pode afetar o funcionamento da aplicao. A especicao dos interceptadores dene a seguinte ordem:

1. Default Interceptors 2. Class-Level Interceptors 3. Method-Level Interceptors 4. Internal Interceptors

Quando dois ou mais Default Interceptors esto associados a um mtodo de negcio, eles sero executados na ordem em que foram denidos no ejb-jar.xml. Quando dois ou mais Class-Level Interceptors esto associados a um mtodo de negcio, eles sero executados na ordem em que foram declarados na anotao @Interceptors. Quando dois ou mais Method-Level Interceptors esto associados a um mtodo de negcio, eles sero executados na ordem em que foram declarados na anotao @Interceptors.

8.7

Exerccios

1. Crie um Dynamic Web Project no eclipse chamado interceptadoresWeb. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo. 97 K19 Treinamentos

Interceptadores

www.k19.com.br

98

Interceptadores

99

K19 Treinamentos

Interceptadores

www.k19.com.br

100

Interceptadores

2. Congure a aplicao interceptadoresWeb para utilizar o data source jdbc/K19 criado no captulo 5, adicionando o arquivo persistence.xml na pasta META-INF dentro do src do projeto interceptadoresWeb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="K19" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/K19</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect. MySQL5InnoDBDialect"/> </properties> </persistence-unit> </persistence>

3. Crie um pacote chamado entidades no projeto interceptadoresWeb e adicione nesse pacote um Entity Bean para modelar mensagens.
1 2 @Entity public class Mensagem {

101

K19 Treinamentos

Interceptadores
3 4 5 6 7 8 9 10

@Id @GeneratedValue private Long id; private String texto; // GETTERS AND SETTERS }

4. Crie um pacote chamado sessionbeans no projeto interceptadoresWeb e adicione nesse pacote um SLSB para funcionar como repositrio de mensagens.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Stateless public class MensagemRepositorio { @PersistenceContext private EntityManager manager; public void adiciona(Mensagem mensagem) { this.manager.persist(mensagem); } public List<Mensagem> getMensagens() { TypedQuery<Mensagem> query = this.manager.createQuery( "select x from Mensagem x", Mensagem.class); return query.getResultList(); } }

5. Crie um pacote chamado managedbeans no projeto interceptadoresWeb e adicione nesse pacote um Managed Bean para oferecer algumas aes para as telas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @ManagedBean public class MensagemMB { @EJB private MensagemRepositorio repositorio; private Mensagem mensagem = new Mensagem(); private List<Mensagem> mensagensCache; public void adiciona(){ this.repositorio.adiciona(this.mensagem); this.mensagem = new Mensagem(); this.mensagensCache = null; } public List<Mensagem> getMensagens(){ if(this.mensagensCache == null){ this.mensagensCache = this.repositorio.getMensagens(); } return this.mensagensCache; } public Mensagem getMensagem() { return mensagem; } public void setMensagem(Mensagem mensagem) { this.mensagem = mensagem; } }

www.k19.com.br

102

Interceptadores 6. Crie uma tela para cadastrar mensagens. Adicione na pasta WebContent do projeto interceptadoresWeb um arquivo chamado mensagens.xhtml com o seguinte contedo.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Mensagens</title> </h:head> <h:body> <h1>Nova Mensagem</h1> <h:form> <h:outputLabel value="Mensagem: "/> <h:inputTextarea value="#{mensagemMB.mensagem.texto}"/> <h:commandButton action="#{mensagemMB.adiciona}" value="Salvar"/> </h:form> <h1>Lista de Mensagens</h1> <h:dataTable value="#{mensagemMB.mensagens}" var="mensagem"> <h:column> <h:outputText value="#{mensagem.id}"/> </h:column> <h:column> <h:outputText value="#{mensagem.texto}"/> </h:column> </h:dataTable> </h:body> </html>

7. Implemente um interceptador externo para realizar o logging da aplicao. Crie um pacote chamado interceptadores no projeto interceptadoresWeb e adicione nesse pacote a seguinte classe.
1 2 3 4 5 6 7 8 9 10 11 12 public class LoggingInterceptor { @AroundInvoke public Object interceptador(InvocationContext ic) throws Exception { System.out.println("CHAMANDO O MTODO: " + ic.getMethod()); Object retornoDoMetodoDeNegocio = ic.proceed(); System.out.println("MTODO " + ic.getMethod() + " FINALIZADO"); return retornoDoMetodoDeNegocio; } }

8. Adicione na pasta WEB-INF do projeto interceptadoresWeb o arquivo ejb-jar.xml com o seguinte contedo. 103 K19 Treinamentos

Interceptadores
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?xml version="1.0" encoding="UTF-8"?> <ejb-jar version="3.1" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/ javaee/ejb-jar_3_1.xsd"> <interceptors> <interceptor> <interceptor-class>interceptadores.LoggingInterceptor</interceptor-class> </interceptor> </interceptors> <assembly-descriptor> <interceptor-binding> <ejb-name>*</ejb-name> <interceptor-class>interceptadores.LoggingInterceptor</interceptor-class> </interceptor-binding> </assembly-descriptor> </ejb-jar>

9. Acesse a url http://localhost:8080/interceptadoresWeb/mensagens. xhtml e depois observe as mensagens do interceptador no console do eclipse. 10. Implemente um interceptador externo para eliminar palavras proibidas das mensagens adicionas o logging da aplicao. Adicione no pacote interceptadores do projeto interceptadoresWeb a seguinte classe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class CensuraInterceptor { private List<String> palavrasProibidas = new ArrayList<String>(); public CensuraInterceptor(){ this.palavrasProibidas.add("coca-cola"); this.palavrasProibidas.add("fiat"); this.palavrasProibidas.add("sony"); } @AroundInvoke public Object interceptador(InvocationContext ic) throws Exception { Object[] parameters = ic.getParameters(); Mensagem mensagem = (Mensagem)parameters[0]; for (String palavraProibida : this.palavrasProibidas) { String textoOriginal = mensagem.getTexto(); String textoCensurado = textoOriginal.replaceAll(palavraProibida, "! CENSURADO!"); mensagem.setTexto(textoCensurado); } return ic.proceed(); } }

11. Associe o interceptador de censura ao mtodo de adicionar mensagens do Session Bean MensagemRepositorio.
1 2 3 4 @Interceptors({CensuraInterceptor.class}) public void adiciona(Mensagem mensagem) { this.manager.persist(mensagem); }

12. Adicione mensagens com palavras proibidas atravs da url http://localhost: 8080/interceptadoresWeb/mensagens.xhtml. www.k19.com.br 104

Interceptadores 13. Implemente um interceptador externo para calcular o tempo gasto para executar cada mtodo de negcio. Associe esse interceptador a todos os mtodos de negcio da aplicao.

105

K19 Treinamentos

Interceptadores

www.k19.com.br

106

Captulo 9 Scheduling
Algumas aplicaes possuem a necessidade de agendar tarefas para serem executadas periodicamente ou uma nica vez aps um determinado tempo. Por exemplo, suponha uma aplicao que calcula o salrio dos funcionrios de uma empresa de acordo com as horas registradas. Possivelmente, esse clculo deve ser realizado uma vez por ms. Outro exemplo, suponha que uma empresa vende seus produtos atravs da internet. As entregas s so realizadas aps a conrmao dos pagamentos. Quando um cliente realiza um pedido, o sistema da empresa deve esperar alguns dias para vericar se o pagamento correspondente foi realizado para que a entrega possa ser liberada.

9.1

Timers

Para agendar tarefas, podemos criar alarmes (timers) atravs do TimerService. Por exemplo, suponha que seja necessrio executar uma tarefa uma nica vez depois de 30 minutos.
1 timerService.createTimer(30 * 60 * 1000, "info");

O primeiro parmentro do mtodo CREATE T IMER () quantidade de tempo que ele deve esperar para disparar e o segundo uma informao que podemos associar ao timer. Tambm, podemos criar um alarme peridico que dispara a cada 30 minutos atravs do T IMER S ER VICE utilizando a sobrecarga do mtodo CREATE T IMER ().
1 timerService.createTimer(30 * 60 * 1000, 30 * 60 * 1000, "info");

Podemos obter o T IMER S ERVICE por injeo atravs da anotao @Resource.


1 2 3 4 5 6 7 8 @Stateless class FolhaDePagamentoBean { @Resource private TimerService timerService; ... }

Os alarmes no podem ser criados para Stateful Session Beans. Essa funcionalidade deve ser adicionada em verses futuras da especicao Enterprise Java Beans. 107

Scheduling

9.2

Mtodos de Timeout

Quando um alarme (timer) dispara, o EJB Container executa um mtodo de timeout no Bean que criou o alarme. Para denir um mtodo de timeout devemos utilizar a anotao @Timeout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Stateless class PedidoBean { @Resource private TimerService timerService; public void registraPedido(Pedido pedido){ this.timerService.createTimer(5 * 24 * 60 * 60 * 1000, pedido); } @Timeout public void verificaPagamento(Timer timer){ Pedido pedido = (Pedido)timer.getInfo(); // verifica o pagamento do pedido } }

9.3

Timers Automticos

Na verso 3.1 da especicao Enterprise Java Beans, os alarmes podem ser criados e automaticamente associados a mtodos de timeout atravs da anotao @Schedule.
1 2 3 4 5 6 7 8 @Stateless class FolhaDePagamentoBean { @Schedule(dayOfMonth="1") public void calculaSalarios(){ // implementacao } }

9.4

Exerccios

1. Crie um Dynamic Web Project no eclipse chamado schedulingWeb. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo. www.k19.com.br 108

Scheduling

109

K19 Treinamentos

Scheduling

www.k19.com.br

110

Scheduling

111

K19 Treinamentos

Scheduling

2. Congure a aplicao schedulingWeb para utilizar o data source jdbc/K19 criado no captulo 5, adicionando o arquivo persistence.xml na pasta META-INF dentro do src do projeto schedulingWeb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="K19" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/K19</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect. MySQL5InnoDBDialect"/> </properties> </persistence-unit> </persistence>

3. Crie um pacote chamado entidades no projeto schedulingWeb e adicione nesse pacote um Entity Bean para modelar produtos.
1 2 @Entity public class Produto {

www.k19.com.br

112

Scheduling
3 4 5 6 7 8 9 10 11 12

@Id @GeneratedValue private Long id; private String nome; private double preco; // GETTERS AND SETTERS }

4. Crie um pacote chamado sessionbeans no projeto schedulingWeb e adicione nesse pacote um SLSB para funcionar como repositrio de produtos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Stateless public class ProdutoRepositorio { @PersistenceContext private EntityManager manager; public void adiciona(Produto produto) { this.manager.persist(produto); } public List<Produto> getProdutos() { TypedQuery<Produto> query = this.manager.createQuery( "select x from Produto x", Produto.class); return query.getResultList(); } }

5. Crie um pacote chamado managedbeans no projeto schedulingWeb e adicione nesse pacote um Managed Bean para oferecer algumas aes para as telas.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @ManagedBean public class ProdutoMB { @EJB private ProdutoRepositorio repositorio; private Produto produto = new Produto(); private List<Produto> produtosCache; public void adiciona(){ this.repositorio.adiciona(this.produto); this.produto = new Produto(); this.produtosCache = null; } public List<Produto> getProdutos(){ if(this.produtosCache == null){ this.produtosCache = this.repositorio.getProdutos(); } return this.produtosCache; } public void setProduto(Produto produto) { this.produto = produto; } public Produto getProduto() { return produto; } }

113

K19 Treinamentos

Scheduling 6. Crie uma tela para cadastrar produtos. Adicione na pasta WebContent do projeto schedulingWeb um arquivo chamado produtos.xhtml com o seguinte contedo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Produtos</title> </h:head> <h:body> <h1>Novo Produto</h1> <h:form> <h:outputLabel value="Nome: "/> <h:inputText value="#{produtoMB.produto.nome}"/> <h:outputLabel value="Preo: "/> <h:inputText value="#{produtoMB.produto.preco}"/> <h:commandButton action="#{produtoMB.adiciona}" value="Salvar"/> </h:form> <h1>Lista de Produtos</h1> <h:dataTable value="#{produtoMB.produtos}" var="produto"> <h:column> <h:outputText value="#{produto.nome}"/> </h:column> <h:column> <h:outputText value="#{produto.preco}"/> </h:column> </h:dataTable> </h:body> </html>

7. Adicione produtos atravs da url http://localhost:8080/schedulingWeb/ produtos.xhtml. 8. A cada 5 minutos um produto cadastrado deve ser escolhido para ser colocado em destaque. Implemente essa lgica atravs dos recursos de scheduling. Adicione a seguinte classe no pacote sessionbeans do projeto schedulingWeb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Singleton public class ProdutoDestaqueBean { @EJB private ProdutoRepositorio repositorio; private Produto produtoDestaque; @Schedule(second="30", minute="*", hour="*") public void trocaProdutoDestaque(){ Random gerador = new Random(); List<Produto> produtos = this.repositorio.getProdutos(); int i = gerador.nextInt(produtos.size()); this.produtoDestaque = produtos.get(i); } public void setProdutoDestaque(Produto produtoDestaque) {

www.k19.com.br

114

Scheduling
18 19 20 21 22 23 24 this.produtoDestaque = produtoDestaque; } public Produto getProdutoDestaque() { return produtoDestaque; } }

9. Adicione na classe ProdutoMB do projeto schedulingWeb o seguinte atributo.


1 2 @EJB private ProdutoDestaqueBean produtoDestaqueBean;

10. Adicione na classe ProdutoMB do projeto schedulingWeb o seguinte mtodo.


1 2 3 public Produto getProdutoDestaque(){ return this.produtoDestaqueBean.getProdutoDestaque(); }

11. Acrescente na tela produtos.xhtml do projeto schedulingWeb o produto em destaque.


1 2 3 4 5 6 <h1>Produto Destaque</h1> <h:outputLabel value="Nome: "/> <h:outputText value="#{produtoMB.produtoDestaque.nome}"/> <h:outputLabel value="Preo: "/> <h:outputText value="#{produtoMB.produtoDestaque.preco}"/>

12. Acesse periodicamente a url http://localhost:8080/schedulingWeb/produtos. xhtml para vericar que o produto em destaque muda de tempos em tempos.

115

K19 Treinamentos

Scheduling

www.k19.com.br

116

Captulo 10 Contexts and Dependency Injection - CDI


Aplicaes corporativas costumam utilizar tanto o container WEB para a camada de apresentao quanto o container EJB para a camada de negcio. A integrao entre o container WEB e o container EJB pode ser mais facilmente realizada atravs dos recursos denidos pela especicao Contexts and Dependency Injection - CDI. Dos recursos existentes na arquitetura CDI, podemos destacar o mecanismo de Injeo de Dependncia e o gerenciamento do ciclo de vida dos objetos atravs de contextos. De acordo com a especicao CDI, os seguintes tipos de objetos possuem suporte a esses dois recursos: Managed Beans Session Beans Objetos criados por Producer Methods Objetos disponibilizados por Producer Fields Resources (Java EE resources, Persistence Contexts, Persistence Units, Remote EJBs and Web Services)

10.1

Managed Beans

Na arquitetura Java EE, os Managed Beans so objetos gerenciados pelo container Java EE. O container deve oferecer um pequeno conjunto de servios fundamentais aos Managed Beans. A denio bsica do conceito de Managed Beans est documentada na especicao Java EE 6 Managed Beans. Contudo essa especicao permite que outras especicaes estendam a idia original de Managed Beans. No devemos confundir o conceito de Managed Beans do Java EE com o conceito de Managed Bean do JSF. Na verdade, um Managed Bean do JSF um caso particular de um Managed Bean do Java EE. A especicao CDI estende a denio de Managed Beans Na arquitetura CDI, os Managed Beans so denidos por classes que devem respeitar certas restries. Na seo 3.1.1 da especicao CDI so denidas essas restries. 117

Contexts and Dependency Injection - CDI

As classes que se encaixam nessas restries atuam como fonte de objetos que sero administrados pelo container CDI e podero ser injetados em outros objetos.

10.2

Producer Methods and Fields

Os Producer Methods so apenas mtodos que produzem objetos que sero administrados pelo container CDI e injetados em outros objetos. Os Producer Methods devem ser anotados com @Produces.
1 2 3 4 @Produces public List<Produto> listaProdutos() { // implementacao }

Atributos tambm podem ser utilizados como fonte de objetos para o container Java EE. Os Producer Fields devem ser anotados com @Produces.
1 2 @Produces public List<Produto> produtos;

10.3

EL Names

Na arquitetura CDI, pginas JSP ou JSF podem acessar objetos atravs de EL. Somente objetos com um EL Name podem ser acessados por pginas JSP ou JSF. A princpio, os seguintes tipos de objetos podem possuir um EL Name: Managed Beans Session Beans Objetos criados por Producer Methods Objetos disponibilizados por Producer Fields www.k19.com.br 118

Contexts and Dependency Injection - CDI Devemos aplicar a anotao @Named aos objetos que devem possuir um EL Name. Utilizando essa anotao, automaticamente, os objetos recebero um EL Name que determinado de acordo com o tipo de objeto.
1 2 3 4 1 2 3 4 5 1 2 3 4 5 6 7 8 9 10 11 1 2 3 @Named // Managed Bean - EL Name: geradorDeApostas public class GeradorDeApostas { // implementacao } @Named @Stateless // Session Bean - EL Name: geradorDeApostas public class GeradorDeApostas { // implementacao } @Named @Produces // Producer Method - EL Name: listaProdutos public List<Produto> listaProdutos() { // implementacao } @Named @Produces // Producer Method - EL Name: produtos public List<Produto> getProdutos() { // implementacao } @Named @Produces // Producer Field - EL Name: produtos public List<Produto> produtos;

possvel alterar o padro denindo EL Names diretamente na anotao @NAMED.


1 2 3 4 @Named("gerador") public class GeradorDeApostas { // implementacao }

10.4

beans.xml

Para habilitar os recursos do CDI para os objetos de uma aplicao, necessrio adicionar um arquivo chamado beans.xml na pasta META-INF no classpath.
1 2 3 4 5 6 7 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> </beans>

10.5

Exerccios

1. Crie um Dynamic Web Project no eclipse chamado cdiWeb. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as ima119 K19 Treinamentos

Contexts and Dependency Injection - CDI gens abaixo.

www.k19.com.br

120

Contexts and Dependency Injection - CDI

121

K19 Treinamentos

Contexts and Dependency Injection - CDI

www.k19.com.br

122

Contexts and Dependency Injection - CDI

2. Habilite os recursos do CDI adicionando um arquivo chamado beans.xml na pasta WEBINF do projeto cdiWeb.
1 2 3 4 5 6 7 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> </beans>

3. Crie um pacote chamado sessionbeans no projeto cdiWeb e adicione nesse pacote um SLSB para funcionar como lanador de moeda.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Named @Stateless public class LancadorDeMoedaBean { private String resultado; public void lanca() { if(Math.random() < 0.5){ this.resultado = "CARA"; } else { this.resultado = "COROA"; } }

123

K19 Treinamentos

Contexts and Dependency Injection - CDI


15 16 17 18 19 20 21 22 public void setResultado(String resultado) { this.resultado = resultado; } public String getResultado() { return resultado; } }

4. Crie uma tela para utilizar o lanador de moedas. Adicione na pasta WebContent do projeto cdiWeb um arquivo chamado moeda.xhtml com o seguinte contedo.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Moeda</title> </h:head> <h:body> <h1>Moeda</h1> <h:form> <h:commandButton action="#{lancadorDeMoedaBean.lanca}" value="Jogar"/> </h:form> <h2>Resultado: <h:outputText value="#{lancadorDeMoedaBean.resultado}"/></h2> </h:body> </html>

5. Acesse a url http://localhost:8080/cdiWeb/moeda.xhtml.

6. Crie um pacote chamado managedbeans no projeto cdiWeb e adicione nesse pacote uma classe para gerar nmeros aleatrios.
1 2 3 4 5 6 7 8 9 10 11 12 public class GeradorDeNumeros { @Named @Produces public List<Double> getNumeros(){ List<Double> numeros = new ArrayList<Double>(); for (int i = 0; i < 5; i++) { numeros.add(Math.random()); } return numeros; } }

7. Crie uma tela para utilizar o gerador de nmeros. Adicione na pasta WebContent do projeto cdiWeb um arquivo chamado numeros.xhtml com o seguinte contedo. www.k19.com.br 124

Contexts and Dependency Injection - CDI


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Nmeros</title> </h:head> <h:body> <h1>Nmeros</h1> <h:dataTable value="#{numeros}" var="numero"> <h:column> <h:outputText value="#{numero}"/> </h:column> </h:dataTable> </h:body> </html>

8. Acesse a url http://localhost:8080/cdiWeb/numeros.xhtml.

10.6

Escopos e Contextos

Os objetos administrados pelo container CDI so armazenados em contextos. Conceitualmente, um contexto uma coleo de objetos relacionados logicamente que devem existir durante um perodo de tempo especco. A especicao CDI dene quatro contextos padres. Request Context: Quando se trata de aplicaes Java WEB, para cada requisio HTTP um novo Request Context criado pelo container CDI e destrudo no nal do processamento da mesma requisio. Mltiplos Request Contexts podem existir simultaneamente. Session Context: Um Session Context est sempre associado a uma HTTP Session. Quando uma HTTP Session criada pelo container WEB, o container CDI cria um Session Context associado a essa HTTP Session. Quando uma HTTP Session destruda pelo container WEB, o container CDI tambm destri o Session Context correspondente. Mltiplos Session Contexts podem existir simultaneamente. Application Context: O container CDI cria um Application Context quando a aplicao inicializada e o destri quando a aplicao nalizada. Mltiplos Session Contexts no podem existir simultaneamente. Conversation Context: H dois tipos de Coversation Context: transient e long-running. Um Conversation Context do tipo transient se comporta de maneira muito parecida com o Request Context. Basicamente, um Conversartion do tipo long-running criado na chamada do mtodo C ONVERSATION . BEGIN () e destrudo quando o mtodo C ONVER SATION . END () executado. Mltiplos Conversation Contexts podem existir simultaneamente. 125 K19 Treinamentos

Contexts and Dependency Injection - CDI Todo objeto administrado pelo container CDI possui um escopo. O escopo de um objeto dene em qual contexto ele ser armazenado quando criado pelo container CDI. A especicao CDI dene cinco escopos padres: Request, Session, Application, Conversation e Dependent. Objetos com escopo Request, Session, Application e Conversation so armazenados no Request Context, Session Context, Application Context e Conversation Context respectivamente. Um objeto com escopo Dependent pertence a outro objeto. O objeto dependente armazenado indiretamente em algum contexto de acordo com o escopo do objeto a qual ele pertence. As anotaes: @RequestScoped, @SessionScoped, @ApplicationScoped, @ConversationScoped e @Dependent so utilizadas para denir o escopo dos objetos. Por padro, se nenhuma anotao for denida o escopo dos objetos o Dependent.
1 2 3 4 1 2 3 4 5 @RequestScoped public class GeradorDeApostas { // implementacao } @Produces @SessionScoped public List<Produto> listaProdutos() { // implementacao }

10.7

Injection Points

Quando um objeto criado pelo container CDI, todas as dependncias so injetados pelo container nesse objeto. As dependncias so outros objetos pertencentes ao mesmo contexto do objeto que est sendo criado. Se alguma dependncia no estiver criada o container se encarrega de cri-la antes. As dependncias de um objeto so denidas atravs de Injection Points. H trs tipos de Injection Points:

10.7.1

Bean Constructors

As dependncias de um objeto podem ser denidas atravs de construtores com a anotao @Inject.
1 2 3 4 5 6 7 public class CarrinhoDeCompras { @Inject public CarrinhoDeCompras(Usuario usuario) { } }

10.7.2

Field

As dependncias de um objeto podem ser denidas atravs de atributos com a anotao @Inject.
1 2 3 public class CarrinhoDeCompras { @Inject

www.k19.com.br

126

Contexts and Dependency Injection - CDI


4 5 6 7 private Usuario usuario;

10.7.3

Initializer methods

As dependncias de um objeto podem ser denidas atravs de mtodos inicializadores com a anotao @Inject.
1 2 3 4 5 6 7 8 9 public class CarrinhoDeCompras { private Usuario usuario; @Inject public void setUsuario(Usuario usuario){ this.usuario = usuario; } }

10.8

Exerccios

9. Altere o mtodo GET N UMEROS () da classe G ERADOR D E N UMEROS do projeto cdiWeb para que ele adicione uma mensagem no console toda vez que for chamado.
1 2 3 4 5 6 7 8 9 10 11 12 13 public class GeradorDeNumeros { @Named @Produces public List<Double> getNumeros(){ System.out.println("GERANDO NMEROS"); List<Double> numeros = new ArrayList<Double>(); for (int i = 0; i < 5; i++) { numeros.add(Math.random()); } return numeros; } }

10. Acesse a url http://localhost:8080/cdiWeb/numeros.xhtml e depois observe as mensagens impressas no console do eclipse. 11. Para evitar que o mtodo GET N UMEROS seja chamado mais do que uma vez por requisio HTTP, utilize o Resquet Scope.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class GeradorDeNumeros { @Named @Produces @RequestScoped public List<Double> getNumeros(){ System.out.println("GERANDO NMEROS"); List<Double> numeros = new ArrayList<Double>(); for (int i = 0; i < 5; i++) { numeros.add(Math.random()); } return numeros; } }

127

K19 Treinamentos

Contexts and Dependency Injection - CDI 12. Acesse novamente a url http://localhost:8080/cdiWeb/numeros.xhtml e depois observe as mensagens impressas no console do eclipse. 13. Utilize os recursos do CDI para implementar uma aplicao com todas as funcionalidades de CRUD. Utilize alunos como entidade dessa aplicao.

www.k19.com.br

128

Captulo 11 Projeto
Neste captulo, implementaremos um pequeno projeto para praticar os conceitos discutidos nos captulos anteriores. Criaremos um sistema simples de cadastro de bugs.

11.1

Exerccios

1. Crie um Dynamic Web Project no eclipse chamado bugWeb. Voc pode digitar CTRL+3 em seguida new Dynamic Web Project e ENTER. Depois, siga exatamente as imagens abaixo.

129

Projeto

www.k19.com.br

130

Projeto

2. Congure a aplicao bugWeb para utilizar o data source jdbc/K19 criado no captulo 5, adicionando o arquivo persistence.xml na pasta META-INF dentro do src do projeto bugWeb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml /ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="K19" transaction-type="JTA"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <jta-data-source>jdbc/K19</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect. MySQL5InnoDBDialect"/> </properties> </persistence-unit> </persistence>

3. Habilite os recursos do CDI adicionando o arquivo beans.xml na pasta WEB-INF do projeto bugWeb.
1 2 3 4 5 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee

131

K19 Treinamentos

Projeto
6 7 http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> </beans>

4. Congure a aplicao bugWeb para que ele utilize o Realm K19-Realm criado no captulo 7, adicionando no arquivo web.xml do projeto bugWeb as conguraes necessrias.
1 2 3 <login-config> <realm-name>K19-Realm</realm-name> </login-config>

5. Faa o mapeamento dos Groups do K19-Realm para os Roles da aplicao bugWeb.


1 2 3 4 5 6 7 8 9 <security-role-mapping> <role-name>ADMIN</role-name> <group-name>admin</group-name> </security-role-mapping> <security-role-mapping> <role-name>USERS</role-name> <group-name>users</group-name> </security-role-mapping>

6. Crie um pacote chamado entities no projeto bugWeb. 7. Adicione no pacote entities um Entity Bean para modelar projetos e outro para modelar bugs.
1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Entity public class Project { @Id @GeneratedValue private Long id; private String name; private String description; // GETTERS AND SETTERS } @Entity public class Bug { @Id @GeneratedValue private Long id; private String description; private String severity; @ManyToOne private Project project; // GETTERS AND SETTERS }

8. Crie um pacote chamado sessionbeans no projeto bugWeb. 9. Adicione no pacote sessionbeans um SLSB para funcionar como repositrio de projetos e outro para funcionar como repositrio de bugs. www.k19.com.br 132

Projeto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @Stateless @RolesAllowed({ "ADMIN", "USERS" }) public class ProjectRepository { @PersistenceContext private EntityManager manager; public void add(Project project) { this.manager.persist(project); } public void edit(Project project) { this.manager.merge(project); } @RolesAllowed({ "ADMIN" }) public void removeById(Long id) { Project project = this.manager.find(Project.class, id); TypedQuery<Bug> query = this.manager.createQuery( "select x from Bug x where x.project = :project", Bug.class); query.setParameter("project", project); List<Bug> bugs = query.getResultList(); for (Bug bug : bugs) { this.manager.remove(bug); } this.manager.remove(project); } @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public List<Project> findAll() { TypedQuery<Project> query = this.manager.createQuery( "select x from Project x", Project.class); return query.getResultList(); } @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public Project findById(Long id) { return this.manager.find(Project.class, id); } } @Stateless @RolesAllowed({ "ADMIN", "USERS" }) public class BugRepository { @PersistenceContext private EntityManager manager; public void add(Bug bug) { this.manager.persist(bug); } public void edit(Bug bug) { this.manager.merge(bug); } @RolesAllowed({ "ADMIN" }) public void removeById(Long id) { Bug bug = this.manager.find(Bug.class, id); this.manager.remove(bug); } @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public List<Bug> findAll() { TypedQuery<Bug> query = this.manager.createQuery("select x from Bug x", Bug.class); return query.getResultList();

133

K19 Treinamentos

Projeto
26 27 28 29 30 31 32 } @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public Bug findById(Long id) { return this.manager.find(Bug.class, id); } }

10. Crie um pacote chamado managedbeans no projeto bugWeb. 11. Adicione no pacote managedbeans um Managed Bean CDI para oferecer para as telas JSF as funcionalidades de CRUD relacionadas aos projetos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @Named @RequestScoped public class ProjectMB { @Inject private ProjectRepository projectRepository; private Project project = new Project(); private List<Project> projects; public void save(){ if(this.getProject().getId() == null){ this.projectRepository.add(this.getProject()); } else { this.projectRepository.edit(this.getProject()); } this.project = new Project(); this.projects = null; } public void delete(Long id){ this.projectRepository.removeById(id); this.projects = null; } public void prepareEdit(Long id){ this.project = this.projectRepository.findById(id); } public Project getProject() { return project; } public List<Project> getProjects() { if(this.projects == null){ this.projects = this.projectRepository.findAll(); } return projects; } }

12. Adicione no pacote managedbeans um Managed Bean CDI para oferecer para as telas JSF as funcionalidades de CRUD relacionadas aos bugs.
1 2 3 4 5 6 7 8 @Named @RequestScoped public class BugMB { @Inject private BugRepository bugRepository; @Inject

www.k19.com.br

134

Projeto
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 private ProjectRepository projectRepository; private Bug bug = new Bug(); private Long projectId; private List<Bug> bugs; public void save(){ Project project = this.projectRepository.findById(this.projectId); this.bug.setProject(project); if(this.getBug().getId() == null){ this.bugRepository.add(this.getBug()); } else { this.bugRepository.edit(this.getBug()); } this.bug = new Bug(); this.bugs = null; } public void delete(Long id){ this.bugRepository.removeById(id); this.bug = null; } public void prepareEdit(Long id){ this.bug = this.bugRepository.findById(id); } public Bug getBug() { return bug; } public List<Bug> getBugs() { if(this.bugs == null){ this.bugs = this.bugRepository.findAll(); } return bugs; } public void setProjectId(Long projectId) { this.projectId = projectId; } public Long getProjectId() { return projectId; } }

13. Adicione no pacote managedbeans um Managed Bean CDI para implementar o processo de login e logout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Named @RequestScoped public class AuthenticatorMB { private String username; private String password; public String login() throws ServletException{ FacesContext context = FacesContext.getCurrentInstance(); HttpServletRequest request = (HttpServletRequest) context.getExternalContext() .getRequest(); request.login(this.username, this.password); return "/projects"; } public String logout() throws ServletException {

135

K19 Treinamentos

Projeto
15 16 17 18 19 20 21 22 FacesContext context = FacesContext.getCurrentInstance(); HttpServletRequest request = (HttpServletRequest) context.getExternalContext() .getRequest(); request.logout(); return "/login"; } // GETTERS AND SETTERS }

14. Crie um pacote chamado lters no projeto bugWeb. 15. Adicione no pacote lters um Filtro para vericar a autenticao dos usurios.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 @WebFilter(servletNames = { "Faces Servlet" }) public class AuthenticatorFilter implements javax.servlet.Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; if (req.getRemoteUser() == null && !req.getRequestURI().endsWith(req. getContextPath() + "/login.xhtml")) { HttpServletResponse res = (HttpServletResponse) response; res.sendRedirect(req.getContextPath() + "/login.xhtml"); } else { chain.doFilter(request, response); } } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void destroy() { } }

16. Crie um menu para as telas da aplicao bugWeb. Adicione um arquivo chamado menu.xhtml na pasta WebContent do projeto bugWeb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <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"> <h:form> <h:panelGrid> <h:commandLink action="#{authenticatorMB.logout}">logout</h:commandLink> <h:outputLink value="#{request.contextPath}/projects.xhtml">Projects</ h:outputLink> <h:outputLink value="#{request.contextPath}/bugs.xhtml">Bugs</h:outputLink > </h:panelGrid> </h:form> </ui:composition>

17. Crie um tela de login na aplicao bugWeb. Adicione um arquivo chamado login.xhtml na pasta WebContent do projeto bugWeb. www.k19.com.br 136

Projeto
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Login</title> </h:head> <h:body> <h1>Login</h1> <h:form> <h:panelGrid> <h:outputLabel value="Username:" /> <h:inputText value="#{authenticatorMB.username}" /> <h:outputLabel value="Password:" /> <h:inputSecret value="#{authenticatorMB.password}" /> <h:commandButton action="#{authenticatorMB.login}" value="login" /> </h:panelGrid> </h:form> </h:body> </html>

18. Crie uma tela para administrar os projetos. Adicione um arquivo chamado projects.xhtml na pasta WebContent do projeto bugWeb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Projects</title> </h:head> <h:body> <ui:include src="/menu.xhtml"/> <hr/> <h1>New Project</h1> <h:form> <h:panelGrid> <h:inputHidden value="#{projectMB.project.id}" /> <h:outputLabel value="Name:" /> <h:inputText value="#{projectMB.project.name}" /> <h:outputLabel value="Description:" /> <h:inputTextarea value="#{projectMB.project.description}" /> <h:commandButton action="#{projectMB.save}" value="Save" /> </h:panelGrid> </h:form> <hr/> <h1>Project List</h1> <h:dataTable value="#{projectMB.projects}" var="project"

137

K19 Treinamentos

Projeto
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 rendered="#{not empty projectMB.projects}" border="1"> <h:column> <f:facet name="header">Id</f:facet> #{project.id} </h:column> <h:column> <f:facet name="header">Name</f:facet> #{project.name} </h:column> <h:column> <f:facet name="header">Description</f:facet> #{project.description} </h:column> <h:column> <f:facet name="header">Delete</f:facet> <h:form> <h:commandLink action="#{projectMB.delete(project.id)}" >delete</ h:commandLink> </h:form> </h:column> <h:column> <f:facet name="header">Edit</f:facet> <h:form> <h:commandLink action="#{projectMB.prepareEdit(project.id)}" >edit</ h:commandLink> </h:form> </h:column> </h:dataTable> </h:body> </html>

19. Crie uma tela para administrar os bugs. Adicione um arquivo chamado bugs.xhtml na pasta WebContent do projeto bugWeb.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Bugs</title> </h:head> <h:body> <ui:include src="/menu.xhtml"/> <hr /> <h1>New Bug</h1> <h:form> <h:panelGrid> <h:inputHidden value="#{bugMB.bug.id}" /> <h:outputLabel value="Severity:" /> <h:selectOneMenu value="#{bugMB.bug.severity}"> <f:selectItem itemValue="LOW" /> <f:selectItem itemValue="MEDIUM" /> <f:selectItem itemValue="HIGH" /> </h:selectOneMenu>

<h:outputLabel value="Description:" />

www.k19.com.br

138

Projeto
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 <h:inputTextarea value="#{bugMB.bug.description}" /> <h:outputLabel value="Project:" /> <h:selectOneMenu value="#{bugMB.projectId}"> <f:selectItems value="#{projectMB.projects}" var="project" itemLabel="#{project.name}" itemValue="#{project.id}" /> </h:selectOneMenu> <h:commandButton action="#{bugMB.save}" value="Save" /> </h:panelGrid> </h:form> <hr /> <h1>Bug List</h1> <h:dataTable value="#{bugMB.bugs}" var="bug" rendered="#{not empty bugMB.bugs}" border="1"> <h:column> <f:facet name="header">Id</f:facet> #{bug.id} </h:column> <h:column> <f:facet name="header">Project</f:facet> #{bug.project.name} </h:column> <h:column> <f:facet name="header">Severity</f:facet> #{bug.severity} </h:column> <h:column> <f:facet name="header">Description</f:facet> #{bug.description} </h:column> <h:column> <f:facet name="header">Delete</f:facet> <h:form> <h:commandLink action="#{bugMB.delete(bug.id)}">delete</h:commandLink> </h:form> </h:column> <h:column> <f:facet name="header">Edit</f:facet> <h:form> <h:commandLink action="#{bugMB.prepareEdit(bug.id)}">edit</ h:commandLink> </h:form> </h:column> </h:dataTable> </h:body> </html>

20. Crie uma tela para os erros internos e os erros de autorizao. Adicione um arquivo chamado error.xhtml na pasta WebContent do projeto bugWeb.
1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html 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"> <h:head> <title>Error</title> </h:head>

139

K19 Treinamentos

Projeto
12 13 14 15 16

<h:body> <h3>Internal Error or Client not authorized for this invocation.</h3> </h:body> </html>

21. Congure a pgina de erro no arquivo web.xml do projeto bugWeb. Adicione o seguinte trecho de cdigo nesse arquivo.
1 2 3 4 <error-page> <exception-type>java.lang.Exception</exception-type> <location>/error.xhtml</location> </error-page>

22. Teste a aplicao!!!

www.k19.com.br

140

Você também pode gostar