Escolar Documentos
Profissional Documentos
Cultura Documentos
Desenvolvimento Web Avanado com JSF 2.2, EJB 3.2 e CDI 1.1
22 de agosto de 2015
As apostilas atualizadas esto disponveis em www.k19.com.br
Sumrio
Sobre a K19
Seguro Treinamento
Termo de Uso
Cursos
Enterprise JavaBeans
1.1 Introduo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.2 EJB Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1
1
2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
21
21
21
22
23
24
25
34
34
40
i
S UMRIO
2.10
2.11
2.12
2.13
2.14
2.15
2.16
3
ii
ii
Exerccios de Fixao
Ciclo de Vida . . . . .
Escalabilidade e Pool
Callbacks . . . . . . .
Exerccios de Fixao
Mtodos Assncronos
Exerccios de Fixao
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
41
46
47
47
48
50
51
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
55
55
56
58
58
62
64
66
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
75
75
76
78
83
85
86
88
Persistncia
5.1 Data Sources . . . . . . . . . .
5.2 Exerccios de Fixao . . . . .
5.3 persistence.xml . . . . . . . .
5.4 Entity Beans . . . . . . . . . .
5.5 Entity Classes e Mapeamento
5.6 Exerccios de Fixao . . . . .
5.7 Entity Managers . . . . . . . .
5.8 Entity Manager Factories . . .
5.9 Exerccios de Fixao . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
95
95
95
102
103
103
104
109
110
111
Transaes
6.1 ACID . . . . . . . . . . . . . . . . . . . . .
6.2 Transao Local ou Distribuda . . . . .
6.3 JTA e JTS . . . . . . . . . . . . . . . . . . .
6.4 Container Managed Transactions - CMT
6.5 Bean Managed Transactions - BMT . . .
6.6 Exerccios de Fixao . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
115
115
115
115
116
118
119
.
.
.
.
127
127
127
132
132
.
.
.
.
.
.
.
.
.
Segurana
7.1 Realms . . . . . . . . . . . . . . .
7.2 Exerccios de Fixao . . . . . .
7.3 Autenticao - Aplicaes Web
7.4 Exerccios de Fixao . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
www.k19.com.br
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
iii
S UMRIO
7.5
7.6
8
Interceptadores
8.1 Interceptor Methods . . . .
8.2 Internal Interceptors . . . .
8.3 External Interceptors . . . .
8.4 Excluindo Interceptadores .
8.5 Invocation Context . . . . .
8.6 Ordem dos Interceptadores
8.7 Exerccios de Fixao . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
149
149
150
150
152
152
153
153
Scheduling
9.1 Timers . . . . . . . . .
9.2 Mtodos de Timeout
9.3 Timers Automticos .
9.4 Exerccios de Fixao
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
163
163
163
164
165
.
.
.
.
.
.
.
.
175
175
176
176
177
178
183
184
185
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
A Projeto
187
A.1 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
www.facebook.com/k19treinamentos
iii
S UMRIO
iv
iv
www.k19.com.br
S UMRIO
Sobre a K19
A K19 uma empresa especializada na capacitao de desenvolvedores de software. Sua equipe
composta por profissionais formados em Cincia da Computao pela Universidade de So Paulo
(USP) e que possuem vasta experincia em treinamento de profissionais para rea de TI.
O principal objetivo da K19 oferecer treinamentos de mxima qualidade e relacionados s principais tecnologias utilizadas pelas empresas. Atravs desses treinamentos, seus alunos tornam-se
capacitados para atuar no mercado de trabalho.
Visando a mxima qualidade, a K19 mantm as suas apostilas em constante renovao e melhoria, oferece instalaes fsicas apropriadas para o ensino e seus instrutores esto sempre atualizados
didtica e tecnicamente.
www.facebook.com/k19treinamentos
S UMRIO
Seguro Treinamento
Na K19 o aluno faz o curso quantas vezes quiser!
Comprometida com o aprendizado e com a satisfao dos seus alunos, a K19 a nica que possui o Seguro Treinamento. Ao contratar um curso, o aluno poder refaz-lo quantas vezes desejar
mediante a disponibilidade de vagas e pagamento da franquia do Seguro Treinamento.
As vagas no preenchidas at um dia antes do incio de uma turma da K19 sero destinadas ao
alunos que desejam utilizar o Seguro Treinamento. O valor da franquia para utilizar o Seguro Treinamento 10% do valor total do curso.
www.k19.com.br
S UMRIO
Termo de Uso
Termo de Uso
Todo o contedo desta apostila propriedade da K19 Treinamentos. A apostila pode ser utilizada
livremente para estudo pessoal . Alm disso, este material didtico pode ser utilizado como material
de apoio em cursos de ensino superior desde que a instituio correspondente seja reconhecida pelo
MEC (Ministrio da Educao) e que a K19 seja citada explicitamente como proprietria do material.
proibida qualquer utilizao desse material que no se enquadre nas condies acima sem
o prvio consentimento formal, por escrito, da K19 Treinamentos. O uso indevido est sujeito s
medidas legais cabveis.
www.facebook.com/k19treinamentos
S UMRIO
S
TO
EN
AM
EIN
TREINAMENTOS
TR
EIN
AM
EN
TO
TR
www.k19.com.br/cursos
www.k19.com.br
CAPTULO
Introduo
Muitos sistemas corporativos so desenvolvidos seguindo a arquitetura definida pelo padro Enterprise JavaBeans (EJB). Ao utilizar essa arquitetura, diversos recursos so disponibilizados a esses
sistemas.
Transaes: A arquitetura EJB define um suporte sofisticado 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 forma 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. Por exemplo, aplicaes EJB podem ser como Web Services.
Multithreading e Concorrncia: A arquitetura EJB permite que as aplicaes sejam 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 especificao JPA.
Gerenciamento de Objetos: Mecanismos de injeo de dependncias e controle de ciclo de vida so
oferecidos aos objetos de uma aplicao EJB. O mecanismo de controle de ciclo de vida pode
garantir a escalabilidade de uma aplicao.
Integrao: A arquitetura EJB fortemente integrada com os componentes da plataforma Java EE.
Podemos, por exemplo, facilmente integrar os recursos do JSF em uma aplicao EJB.
EJB Container
Toda aplicao EJB executada e gerenciada por um EJB Container. H diversas opes de EJB
Container disponveis. Os servidores de aplicao Java EE como o Glassfish e o JBoss possuem um
EJB Container. Portanto, podemos utiliz-los para executar as nossas aplicaes EJB.
www.facebook.com/k19treinamentos
Exerccios de Fixao
Copie o arquivo glassfish-4.1.zip da pasta K19-Arquivos para a sua rea de Trabalho. Depois,
descompacte esse arquivo.
1
Importante
Voc tambm pode obter o arquivo glassfish-4.1.zip atravs do site da K19: www.k19.
com.br/arquivos.
2
Copie o arquivo jboss-as-7.1.1.Final.zip da pasta K19-Arquivos para a sua rea de Trabalho.
Depois, descompacte esse arquivo.
Importante
Voc tambm pode obter o arquivo jboss-as-7.1.1.Final.zip atravs do site da K19:
www.k19.com.br/arquivos.
Importante
Voc tambm pode obter o arquivo wildfly-8.2.0.Final.zip atravs do site da K19:
www.k19.com.br/arquivos.
www.k19.com.br
www.facebook.com/k19treinamentos
www.k19.com.br
www.facebook.com/k19treinamentos
www.k19.com.br
www.facebook.com/k19treinamentos
www.k19.com.br
www.facebook.com/k19treinamentos
10
Configure o Glassfish no Eclipse Luna. Digite CTRL+3 para abrir o Quick Access. Em seguida,
pesquise por Define a new server.
6
10
www.k19.com.br
11
www.facebook.com/k19treinamentos
11
12
Pare o Glassfish. Em seguida, configure o JBoss no Eclipse Luna. Digite CTRL+3 para abrir o
Quick Access. Em seguida, pesquise por Define a new server.
7
12
www.k19.com.br
13
www.facebook.com/k19treinamentos
13
14
14
www.k19.com.br
15
www.facebook.com/k19treinamentos
15
16
Pare o JBoss. Em seguida, configure o Wildfly no Eclipse Luna. Digite CTRL+3 para abrir o
Quick Access. Em seguida, pesquise por Define a new server.
8
16
www.k19.com.br
17
www.facebook.com/k19treinamentos
17
18
18
www.k19.com.br
19
www.facebook.com/k19treinamentos
19
20
20
www.k19.com.br
CAPTULO
Session Beans
Um sistema corporativo composto por muitos processos ou tarefas. Por exemplo, um sistema
bancrio possui processos especficos 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 especficos que so chamados de Session Beans. O EJB Container administra esses componentes oferecendo
diversos recursos a eles.
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 caracterstica fundamental dos SLSBs que eles
no armazenam estado conversacional. Vejamos alguns exemplos a seguir.
Servio de Cmbio
Considere um sistema de converso monetria. Esse sistema capaz de converter valores monetrios de uma moeda para outra. Por exemplo, converter 100 reais para o valor correspondente em
dlar americano. Poderamos, implementar essa regra de negcio atravs do mtodo a seguir.
1 public double converte ( double valor , String moedaOrigem , String moedaDestino ) {
2
// lgica da converso monetria
3 }
A execuo do mtodo converte() no depende das suas execues anteriores. Em outras palavras, o mtodo converte() no precisa manter estado conversacional.
Dicionrio
Considere a implementao de um dicionrio digital de portugus. Dado uma palavra, o dicionrio digital deve devolver a definio dela. Podemos criar um mtodo para implementar essa regra
de negcio.
1 public String getDefinicao ( String palavra ) {
2
// lgica do dicionario
3 }
www.facebook.com/k19treinamentos
21
22
Consulta de CEP
Considere um sistema de consulta de CEP. Esse sistema capaz de informar o CEP de uma determinada localidade. Podemos criar um mtodo para implementar essa regra de negcio.
1 public String consultaCEP ( String estado , String cidade , String logradouro , Integer numero ) {
2
// lgica da consulta do CEP
3 }
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 conversacional.
22
www.k19.com.br
23
Por fim, necessrio definir se o acesso do SLSB local ou remoto. Quando o acesso local, apenas quem est dentro do servidor de aplicao no qual se encontra o SLSB pode acess-lo. Quando
o acesso remoto, tanto quem est dentro quanto quem est fora do servidor de aplicao no qual
se encontra o SLSB pode acess-lo.
A definio do tipo de acesso pode ser realizada atravs das anotaes: @Local e @Remote.
1
2
3
4
5
@Stateless
@Remote ( Calculadora . class )
public class CalculadoraBean implements Calculadora {
...
}
Cdigo Java 2.7: CalculadoraBean.java
1
2
3
4
5
@Stateless
@Local ( Calculadora . class )
public class CalculadoraBean implements Calculadora {
...
}
Cdigo Java 2.8: CalculadoraBean.java
Nas anotaes @Local e @Remote, devemos informar as interfaces que definem os mtodos de
negcio do nosso SLSB. A classe CalculadoraBean poderia implementar diversas interfaces. Contudo, apenas os mtodos das interfaces declaradas nessas anotaes sero considerados mtodos de
negcio.
www.facebook.com/k19treinamentos
23
24
13
return a * b ;
14
}
15
16
public double divide ( double a , double b ) {
17
return a / b ;
18
}
19 }
Cdigo Java 2.9: CalculadoraBean.java
Depois de definir 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 ;
}
}
Cdigo Java 2.11: CalculadoraBean.java
Perceba que o acesso local foi definido 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 Calculadora que define as operaes
do SLSB precisa estar no classpath da camada web diferentemente da classe CalculadoraBean que
implementa as operaes.
24
www.k19.com.br
25
Suponha que a camada web da nossa aplicao utiliza apenas Servlets. Podemos injetar, atravs
da anotao @EJB, o SLSB em uma Servlet.
1 @WebServlet ( " / soma " )
2 public class SomaServlet extends HttpServlet {
3
@EJB
4
private Calculadora calculadora ;
5
6
protected void service ( HttpServletRequest req , HttpServletResponse res ) {
7
double a = Double . parseDouble ( request . getParameter ( " a " ) ) ;
8
double b = Double . parseDouble ( request . getParameter ( " b " ) ) ;
9
10
double resultado = this . calculadora . soma (a , b ) ;
11
12
PrintWriter out = response . getWriter () ;
13
out . println ( " < html > < body > <p > " ) ;
14
out . println ( " Soma : " + resultado ) ;
15
out . println ( " </p > </ body > </ html > " ) ;
16
}
17 }
Agora, suponha que a camada web utilize JSF. Podemos injetar o SLSB em um managed bean
tambm atravs da anotao @EJB.
1 @ManagedBean
2 public class CalculadoraMB {
3
@EJB
4
private Calculadora calculadora ;
5
6
private double a ;
7
8
private double b ;
9
10
private double resultado ;
11
12
public void soma () {
13
this . resultado = this . calculadora . soma (a , b ) ;
14
}
15
16
// GETTERS AND SETTERS
17 }
Exerccios de Fixao
Crie um EJB project no eclipse. Voc pode digitar CTRL+3 em seguida new EJB project e
ENTER. Depois, siga exatamente as imagens abaixo.
1
www.facebook.com/k19treinamentos
25
26
26
www.k19.com.br
27
calculadora: As classes que implementam os SLSB devem ser colocadas nesse projeto.
calculadoraClient: As interfaces que definem as operaes dos SLSB devem ser colocadas nesse
projeto.
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.
2
www.facebook.com/k19treinamentos
27
28
28
www.k19.com.br
29
www.facebook.com/k19treinamentos
29
30
30
www.k19.com.br
31
www.facebook.com/k19treinamentos
31
32
No projeto calculadora, crie uma classe java chamada CalculadoraBean em um pacote chamado br.com.k19.sessionbeans.
5
1
2
3
4
5
6
7
8
9
10
11
12
32
www.k19.com.br
33
No projeto calculadoraWeb, crie uma classe java chamada CalculadoraMB em um pacote chamado br.com.k19.managedbeans.
6
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
Crie uma simples tela na aplicao web para utilizar o managed bean. Adicione o arquivo
soma.xhtml na pasta WebContent do projeto calculadoraWeb com o seguinte contedo.
7
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 : outputLabel value = " Valor B : " / >
<h : inputText value = " #{ calculadoraMB . b } " / >
<h : commandButton action = " #{ calculadoraMB . soma } " value = " soma " / >
<h : outputLabel value = " Resultado : " / >
<h : outputText value = " #{ calculadoraMB . resultado } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 2.1: soma.xhtml
www.facebook.com/k19treinamentos
33
34
Adicione o projeto calculadoraEAR no Glassfish. Clique com o boto direito no Glassfish utilizando view Servers e escolha a opo Add and Remove.
8
Certifique-se que o JBoss e o Wildfly estejam parados. Inicie o Glassfish. Acesse a url http:
//localhost:8080/calculadoraWeb/soma.xhtml e teste o funcionamento da aplicao.
9
Exerccios de Fixao
Para no confundir, feche os projetos calculadora, calculadoraClient, calculadoraEAR e calculadoraWeb. Para isso, clique com o boto direito do mouse sobre esses projetos e selecione a opo
Close Project.
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
11
34
www.k19.com.br
35
abaixo.
www.facebook.com/k19treinamentos
35
36
36
www.k19.com.br
37
www.facebook.com/k19treinamentos
37
38
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
Crie uma simples tela na aplicao web para utilizar o managed bean. Adicione o arquivo
dado.xhtml na pasta WebContent do projeto dadoWeb com o seguinte contedo.
14
1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5
xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
38
www.k19.com.br
39
8
9
10
11
12
13
14
15
16
17
18
19
15
Remova o projeto calculadoraEAR e adicione o projeto dadoWeb no Glassfish. Clique com
o boto direito no Glassfish da view Servers e escolha a opo Add and Remove. Depois, siga as
imagens abaixo.
www.facebook.com/k19treinamentos
39
16
40
40
www.k19.com.br
41
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.
Exerccios de Fixao
17
Adicione uma interface chamada LancadorDeDado no pacote br.com.k19.sessionbeans do
projeto dadoWeb.
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
19
1
2
3
4
5
6
7
8
9
10
11
12
www.facebook.com/k19treinamentos
41
42
Crie um Java project no eclipse. Voc pode digitar CTRL+3 em seguida new Java project e
ENTER. Depois, siga exatamente as imagens abaixo.
20
42
www.k19.com.br
43
www.facebook.com/k19treinamentos
43
44
44
www.k19.com.br
45
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
www.facebook.com/k19treinamentos
45
46
Republique o projeto dadoWeb. Voc pode clicar com o boto direito nesse projeto na view
Servers dentro do Glassfish e selecionar a opo Full publish.
24
25
Ciclo de Vida
As instncias dos SLSBs so administradas pelo EJB Container. Devemos entender o 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.
Estados
O ciclo de vida das instncias de um SLSB possui apenas dois estados.
1. NO EXISTE
2. PRONTO
www.k19.com.br
47
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 aplicao
oferece configuraes especficas para melhorar a eficincia no atendimento das chamadas. Por
exemplo, o Glassfish permite que uma quantidade mxima de instncias de um determinado SLSB
seja definida pela aplicao.
Callbacks
Podemos associar lgicas especficas 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 @Stateless
www.facebook.com/k19treinamentos
47
48
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 fim, os mtodos anotados com @PostConstruct 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 @Stateless
2 public class CalculadoraBean {
3
4
@PreDestroy
5
public void destruindo () {
6
System . out . println ( " Mais uma calculadora ser destruda ... " )
7
}
8
9
// METODOS DE NEGOCIO
10 }
Cdigo Java 2.25: CalculadoraBean.java
Exerccios de Fixao
26
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
48
@Stateless
@Remote ( LancadorDeDado . class )
public class LancadorDeDadoBean implements LancadorDeDado {
private Random gerador = new Random () ;
private static int contador ;
@PostConstruct
public void inicializando () {
synchronized ( LancadorDeDadoBean . class ) {
LancadorDeDadoBean . contador ++;
System . out . println ( " Criando um lanador de dados ... " ) ;
www.k19.com.br
49
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 }
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
www.facebook.com/k19treinamentos
49
50
Mtodos Assncronos
A partir da verso 3.1 do EJB, podemos definir mtodos assncronos nos session beans. Geralmente, mtodos assncronos so utilizados para implementar tarefas demoradas. Para definir um
mtodo assncrono, basta utilizar a anotao @Asynchronous. Se essa anotao for aplicada na
classe que define um session bean, todos os mtodos de negcio desse session bean sero assncronos. Por outro lado, podemos aplicar essa anotao somentes nos mtodos de negcio que devem
ser assncronos.
1
2
3
4
5
6
7
8
@Stateless
@Asynchronous
public class MeuSessionBean {
public Future < Integer > metodoAssincrono1 () {. . . }
public Future < String > metodoAssincrono2 () {. . . }
}
Cdigo Java 2.28: MeuSessionBean.java
50
www.k19.com.br
51
1 @Stateless
2 public class MeuSessionBean {
3
4
@Asynchronous
5
public Future < Integer > metodoAssincrono1 () {. . . }
6
7
@Asynchronous
8
public Future < String > metodoAssincrono2 () {. . . }
9
10
public String metodoSincrono1 () {. . . }
11
12
public Integer metodoSincrono2 () {. . . }
13 }
Cdigo Java 2.29: MeuSessionBean.java
MeuSessionBean bean = . . .
Future < String > future = bean . metodoAssincrono2 () ;
// executa alguma coisa enquanto o session bean trabalha
// verifica se a tarefa terminou
if ( future . isDone () ) {
}
A interface Future tambm permite que o resultado seja recuperado atravs do mtodo get().
1
2
3
4
5
6
7
8
MeuSessionBean bean = . . .
Future < String > future = bean . metodoAssincrono2 () ;
// executa alguma coisa enquanto o session bean trabalha
// verifica se a tarefa terminou
if ( future . isDone () ) {
String resultado = future . get () ;
}
Exerccios de Fixao
31
1 ...
2 @Asynchronous
3 public Future < Map < Integer , Integer > > calculaFrequencia () {
4
Map < Integer , Integer > map = new HashMap < Integer , Integer >() ;
5
map . put (1 , 0) ;
6
map . put (2 , 0) ;
7
map . put (3 , 0) ;
8
map . put (4 , 0) ;
www.facebook.com/k19treinamentos
51
52
9
map . put (5 , 0) ;
10
map . put (6 , 0) ;
11
12
for ( int i = 0; i < 500; i ++) {
13
int v = this . gerador . nextInt (6) + 1;
14
map . put (v , map . get ( v ) + 1) ;
15
try {
16
Thread . sleep (100) ;
17
} catch ( InterruptedException e ) {
18
}
19
System . out . println ( i ) ;
20
}
21
return new AsyncResult < Map < Integer , Integer > >( map ) ;
22 }
23 . . .
Cdigo Java 2.32: LancadorDeDadoBean.java
32
33
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
52
www.k19.com.br
53
Republique o projeto dadoWeb. Voc pode clicar com o boto direito nesse projeto na view
Servers dentro do Glassfish e selecionar a opo Full publish.
34
35
www.facebook.com/k19treinamentos
53
54
54
www.k19.com.br
CAPTULO
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 conversacional.
Carrinho de Compras
Para exemplificar, 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 class CarrinhoBean {
2
3
public void adiciona ( Produto produto ) {
4
// lgica para adicionar produto
5
}
6
7
public void remove ( Produto produto ) {
8
// lgica para remover produto
9
}
10
11
public void finalizaCompra () {
12
// lgica para finalizar a compra
13
}
14 }
Cdigo Java 3.1: CarrinhoBean.java
www.facebook.com/k19treinamentos
55
56
12
13
public void finalizaCompra () {
14
// lgica para finalizar a compra
15
}
16 }
Cdigo Java 3.2: CarrinhoBean.java
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 modifiquem respostas j realizadas antes
de finalizar a prova. As resposta poderiam ser mantidas em um mapa.
1 class ProvaBean {
2
private Map < Integer , Character > respostas = new HashMap < Integer , Character >() ;
3
4
public void responde ( Integer questao , Character resposta ) {
5
this . respostas . put ( questao , resposta ) ;
6
}
7
8
public void finaliza () {
9
// lgica para finalizar a prova
10
}
11 }
Cdigo Java 3.3: ProvaBean.java
Uma instncia da classe ProvaBean 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.
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 class ListaDeVideos {
2
private List < Video > videos = new ArrayList < Video >() ;
3
4
public void adiciona ( Video video ) {
5
this . videos . add ( video ) ;
6
}
7
8
public void embaralha () {
9
Collections . shuffle ( this . videos ) ;
10
}
11 }
Cdigo Java 3.4: ListaDeVideos.java
Novamente, cada instncia da classe ListaDeVideos deve ser exclusiva de um cliente e os vdeos
adicionados devem ser mantidos entre as chamadas dos mtodos.
www.k19.com.br
57
O primeiro passo para implementar um SFSB definir a sua interface de utilizao atravs de
uma interface java. Por exemplo, considere um SFSB que implemente o funcionamento do carrinho
de compras. Uma possvel interface de utilizao para esse session bean seria:
1 public interface Carrinho {
2
void adiciona ( Produto produto ) ;
3
void remove ( Produto produto ) ;
4 }
Cdigo Java 3.5: Carrinho.java
Aps definir a interface de utilizao, o segundo passo seria implementar as operaes do SFSB
atravs de uma classe java.
1 public class CarrinhoBean implements Carrinho {
2
3
private Set < Produto > produtos = new HashSet < Produto >() ;
4
5
public void adiciona ( Produto produto ) {
6
this . produtos . add ( produto ) ;
7
}
8
9
public void remove ( Produto produto ) {
10
this . produtos . remove ( produto ) ;
11
}
12 }
Cdigo Java 3.6: CarrinhoBean.java
O terceiro passo especificar o tipo de session bean que queremos utilizar. No caso do carrinho,
o tipo seria SFSB. Essa definio realizada atravs da anotao @Stateful.
1 @Stateful
2 public class CarrinhoBean implements Carrinho {
3
...
4 }
Cdigo Java 3.7: CarrinhoBean.java
Por fim, necessrio definir 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 definio 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 {
...
}
Cdigo Java 3.8: CarrinhoBean.java
1
2
3
4
5
@Stateful
@Local ( Carrinho . class )
public class CarrinhoBean implements Carrinho {
...
}
www.facebook.com/k19treinamentos
57
58
Exerccios de Fixao
Para no confundir, feche os projetos dadoWeb e dadoJavaSE. Para isso, clique com o boto
direito do mouse sobre esses projetos e selecione a opo Close Project.
1
58
www.k19.com.br
59
www.facebook.com/k19treinamentos
59
60
60
www.k19.com.br
61
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
www.facebook.com/k19treinamentos
61
62
Adicione o arquivo produtos.xhtml na pasta WebContent do projeto carrinhoWeb com o seguinte contedo.
5
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 >
Cdigo XHTML 3.1: produtos.xhtml
Remova o projeto dadoWeb do Glassfish. Adicione o projeto carrinhoWeb no JBoss. Certifiquese que o Glassfish e o Wildfly estejam parados. Execute o JBoss e teste a aplicao acessando a url
http://localhost:8080/carrinhoWeb/produtos.xhtml.
6
Ciclo de Vida
As instncias dos SFSBs so administradas pelo EJB Container. Devemos entender o 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.
Estados
O ciclo de vida das instncias de um SFSB possui trs estados.
1. NO EXISTE
2. PRONTO
3. PASSIVADO
62
www.k19.com.br
63
www.facebook.com/k19treinamentos
63
64
Callbacks
Podemos associar lgicas especficas nas transies de estado no ciclo de vida dos SFSBs.
@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 @Stateful
2 public class CarrinhoBean {
3
64
www.k19.com.br
65
4
5
6
7
8
9
10 }
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 fim, os mtodos anotados com @PostConstruct 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 @Stateful
2 public class CarrinhoBean {
3
4
@PreDestroy
5
public void destruindo () {
6
System . out . println ( " Mais um carrinho ser destrudo ... " ) ;
7
}
8
9
// METODOS DE NEGOCIO
10 }
Cdigo Java 3.15: CarrinhoBean.java
@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 @Stateful
2 public class CarrinhoBean {
3
4
@PrePassivate
5
public void passivando () {
6
System . out . println ( " Mais um carrinho ser passivado ... " ) ;
7
}
8
9
// METODOS DE NEGOCIO
10 }
Cdigo Java 3.16: CarrinhoBean.java
@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 @Stateful
www.facebook.com/k19treinamentos
65
66
Exerccios de Fixao
1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
66
@Stateful
@Remote ( Carrinho . class )
public class CarrinhoBean implements Carrinho {
private
private
private
private
Set < String > produtos = new HashSet < String >() ;
static int contadorTotal ;
static int contadorAtivos ;
int id ;
www.k19.com.br
67
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
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
84
85
86
87
88
89 }
www.facebook.com/k19treinamentos
67
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
68
Republique o projeto carrinhoWeb. Voc pode clicar com o boto direito nesse projeto na view
Servers dentro do JBoss e selecionar a opo Full publish.
10
11
Utilize o script add-user.sh para adicionar o usurio k19 no JBoss. Siga os passos abaixo.
cosen@k19 :~/ Desktop / jboss - as -7.1.1. Final / bin$ ./ add - user . sh
What type of user do you wish to add ?
a) Management User ( mgmt - users . properties )
b) Application User ( application - users . properties )
(a ): b
Enter the details of the new user to add .
Realm ( ApplicationRealm ) :
Username : k19
Password :
Re - enter Password :
What roles do you want this user to belong to ? ( Please enter a comma separated list ,
or leave blank for none ) :
About to add user k19 for realm ApplicationRealm
Is this correct yes / no ? yes
Added user k19 to file / home / cosen / Desktop / jboss - as -7.1.1. Final / standalone /
configuration / application - users . properties
Added user k19 to file / home / cosen / Desktop / jboss - as -7.1.1. Final / domain /
configuration / application - users . properties
68
www.k19.com.br
69
1
2
3
4
5
6
7
8
9
10
...
< stateful default - access - timeout = " 5000 " cache - ref = " passivating " / >
...
< cache name = " passivating " passivation - store - ref = " file " aliases = " SimpleStatefulCache " / >
...
< file - passivation - store name = " file "
idle - timeout = " 10 "
idle - timeout - unit = " SECONDS "
max - size = " 5 " / >
...
13
Crie um Java project no eclipse. Voc pode digitar CTRL+3 em seguida new Java project e
ENTER. Depois, siga exatamente as imagens abaixo.
www.facebook.com/k19treinamentos
69
70
70
www.k19.com.br
71
www.facebook.com/k19treinamentos
71
14
1
2
3
4
5
6
72
1
2
3
4
5
6
7
8
9
10
11
12
13
72
www.k19.com.br
73
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 }
16
dor.
www.facebook.com/k19treinamentos
73
74
74
www.k19.com.br
CAPTULO
Uma nica instncia da classe ContadorDeUsuariosBean 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.
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 definir alguns mtodos para implementar esse sistema.
1 class ChatBean {
2
private Set < String > salas = new HashSet < String >() ;
3
4
public void criaSala ( String sala ) {
5
this . salas . add ( sala ) ;
6
}
7
8
public List < String > listaSalas () {
9
return new ArrayList < String >( this . salas ) ;
10
}
11 }
www.facebook.com/k19treinamentos
75
76
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 ChatBean deve ser criada
j que as salas sero compartilhadas entre todos os usurios.
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 class TransitoBean {
2
private Map < String , List < Integer > > vias = new HashMap < String , List < Integer > >() ;
3
4
public void registra ( String via , Integer velocidade ) {
5
if ( this . vias . containsKey ( via ) ) {
6
this . vias . get ( via ) . add ( velocidade ) ;
7
}
8
}
9
10
public List < Integer > getVelocidadesRegistradas ( String via ) {
11
return this . vias . get ( via ) ;
12
}
13 }
Cdigo Java 4.3: TransitoBean.java
Os dados sobre o trnsito so fornecidos pelos usurios e todos podem consultar as mesmas
informaes. A princpio, no necessrio manter esses dados persistidos.
Implementao
Para implementar um Singleton Session Bean podemos definir uma interface java com as assinaturas dos mtodos de negcio. Por exemplo, suponha que um Singleton Session Bean ser utilizado
para implementar um sistema de chat.
1 public interface Chat {
2
void criaSala ( String sala ) ;
3
List < String > listaSalas () ;
4 }
Cdigo Java 4.4: Chat.java
Aps definir a interface de utilizao, o segundo passo seria implementar as operaes do session
bean atravs de uma classe java.
1 public class ChatBean implements Chat {
2
3
private Set < String > salas = new HashSet < String >() ;
4
5
public void criaSala ( String sala ) {
6
this . salas . add ( sala ) ;
7
}
76
www.k19.com.br
77
8
9
public List < String > listaSalas () {
10
return new ArrayList < String >( this . salas ) ;
11
}
12 }
Cdigo Java 4.5: ChatBean.java
O terceiro passo especificar o tipo de session bean que queremos utilizar. No caso do chat, o
tipo seria Singleton. Essa definio realizada atravs da anotao @Singleton.
1 @Singleton
2 public class ChatBean implements Chat {
3
...
4 }
Cdigo Java 4.6: ChatBean.java
Por fim, necessrio definir 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 definio 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 {
...
}
Cdigo Java 4.7: ChatBean.java
1
2
3
4
5
@Singleton
@Local ( Chat . class )
public class ChatBean implements Chat {
...
}
Cdigo Java 4.8: ChatBean.java
www.facebook.com/k19treinamentos
77
78
13 }
Exerccios de Fixao
Para no confundir, feche os projetos carrinhoWeb e carrinhoJavaSE. Para isso, clique com o
boto direito do mouse sobre esses projetos e selecione a opo Close Project.
1
78
www.k19.com.br
79
www.facebook.com/k19treinamentos
79
80
80
www.k19.com.br
81
3
Crie um pacote chamado br.com.k19.sessionbeans no projeto chatWeb e adicione a seguinte
classe nesse pacote.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
www.facebook.com/k19treinamentos
81
82
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
Adicione o arquivo chat.xhtml na pasta WebContent do projeto chatWeb com o seguinte contedo.
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
82
<! 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 >
www.k19.com.br
83
25
</ h : dataTable >
26
</ h : form >
27 </ h : body >
28 </ html >
Cdigo XHTML 4.1: chat.xhtml
6
Remova o projeto carrinhoWeb do JBoss. Adicione o projeto chatWeb no Wildfly. Certifique-se
que o Glassfish e o JBoss estejam parado. Inicie o Wildfly e teste a aplicao acessando a url http://
localhost:8080/chatWeb/chat.xhtml. Utilize pelo menos dois navegadores diferentes para acessar a aplicao e observe que as mesmas salas so apresentadas nesses navegadores.
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.
Estados
O ciclo de vida das instncias dos Singleton Session Beans possui dois estados.
1. NO EXISTE
2. PRONTO
@Singleton
@Startup
class ContadorDeUsuariosBean {
private int contador = 0;
public void adiciona () {
this . contador ++;
}
public int getContador () {
return this . contador ;
}
}
Cdigo Java 4.12: ContadorDeUsuariosBean.java
www.facebook.com/k19treinamentos
83
84
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.
Callbacks
Podemos associar lgicas especficas 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 @Singleton
2 class ContadorDeUsuariosBean {
3
4
@PostConstruct
5
public void inicializando () {
6
System . out . println ( " Contador de usurios criado ... " ) ;
7
}
8
9
// METODOS DE NEGOCIO
10 }
Cdigo Java 4.13: ContadorDeUsuariosBean.java
84
www.k19.com.br
85
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 fim, os mtodos anotados com @PostConstruct 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 @Singleton
2 class ContadorDeUsuariosBean {
3
4
@PreDestroy
5
public void destruindo () {
6
System . out . println ( " Contador de usurios ser destrudo ... " ) ;
7
}
8
9
// METODOS DE NEGOCIO
10 }
Cdigo Java 4.14: ContadorDeUsuariosBean.java
Exerccios de Fixao
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
www.facebook.com/k19treinamentos
85
86
34 }
Cdigo Java 4.15: ChatBean.java
1
2
3
4
5
6
10
Concorrncia
Um Singleton Session Bean suporta acesso concorrente. Em outras palavras, a instncia de um
Singleton Session Bean pode processar diversas chamadas a mtodos de negcio simultaneamente.
H dois modos de gerenciamento de acesso instncia de um Singleton Session Bean:
Container Managed Concurrency (CMC)
Bean Managed Concurrency (BMC)
O modo padro de gerenciamento o CMC. Opcionalmente, podemos declarar o modo CMC
atravs da anotao @ConcurrencyManagement. Mas, lembre-se que no necessarrio pois esse
o modo padro.
1
2
3
4
5
@Singleton
@ConcurrencyManagement ( ConcurrencyManagementType . CONTAINER )
public class ContadorDeUsuariosBean {
...
}
Cdigo Java 4.17: ContadorDeUsuariosBean.java
www.k19.com.br
87
1
2
3
4
5
CMC
No modo CMC, todo mtodo de negcio associado ao Read Lock ou ao Write Lock. Chamadas a mtodos associados ao Read Lock podem ser executadas simultaneamente. Por outro lado,
chamadas a mtodos associados ao Write Lock so executadas uma de cada vez.
Por padro, no CMC, os mtodos so associados ao Write Lock. Opcionalmente, podemos declarar o tipo de Lock atravs da anotao @Lock. Mas, lembre-se que no necessrio pois o Write
Lock associado aos mtodos de negcio por padro.
1
2
3
4
5
6
7
8
9
10
11
12
13
@Singleton
@Lock ( LockType . WRITE )
public class ContadorDeUsuariosBean {
private int contador = 0;
public void adiciona () {
this . contador ++;
}
public int getContador () {
return this . contador ;
}
}
Cdigo Java 4.19: ContadorDeUsuariosBean.java
1 @Singleton
2 public class ContadorDeUsuariosBean {
3
private int contador = 0;
4
5
@Lock ( LockType . WRITE )
6
public void adiciona () {
7
this . contador ++;
8
}
9
10
public int getContador () {
11
return this . contador ;
12
}
13 }
Cdigo Java 4.20: ContadorDeUsuariosBean.java
A anotao @Lock pode ser aplicada na classe do session bean ou diretamente nos mtodos de
negcio.
Para associar o Read Lock aos mtodos de negcio, devemos utilizar a anotao @Lock na classe
do session bean ou nos mtodos de negcio.
1 @Singleton
2 @Lock ( LockType . READ )
3 public class ContadorDeUsuariosBean {
4
private int contador = 0;
5
www.facebook.com/k19treinamentos
87
88
1 @Singleton
2 public class ContadorDeUsuariosBean {
3
private int contador = 0;
4
5
public void adiciona () {
6
this . contador ++;
7
}
8
9
@Lock ( LockType . READ )
10
public int getContador () {
11
return this . contador ;
12
}
13 }
Cdigo Java 4.22: ContadorDeUsuariosBean.java
BMC
No modo BMC, o controle de concorrncia deve ser implementado dentro dos mtodos de negcio. Voc pode utilizar a instruo synchronized ou os recursos do pacote java.util.concurrent.
Para isso, voc precisa ter bons conhecimento de programao concorrente.
Exerccios de Fixao
11
12
1
2
3
4
5
6
7
88
www.k19.com.br
89
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Crie um Java project no eclipse. Voc pode digitar CTRL+3 em seguida new Java project e
ENTER. Depois, siga exatamente as imagens abaixo.
13
www.facebook.com/k19treinamentos
89
90
90
www.k19.com.br
91
Importante: Selecione o arquivo jboss-client.jar contido na pasta client que est na pasta bin
do diretrio de instalao do Wildfly.
www.facebook.com/k19treinamentos
91
14
92
Utilize o script add-user.sh para adicionar o usurio k19 no JBoss. Siga os passos abaixo.
cosen@k19 :~/ Desktop / wildfly -8.2.0. Final / bin$ ./ add - user . sh
What type of user do you wish to add ?
a) Management User ( mgmt - users . properties )
b) Application User ( application - users . properties )
(a ): b
Enter the details of the new user to add .
Using realm ApplicationRealm as discovered from the existing property files .
Username : k19
Password recommendations are listed below . To modify these restrictions edit
the add - user . properties configuration file .
- The password should not be one of the following restricted values { root ,
admin , administrator }
- The password should contain at least 8 characters , 1 alphabetic character ( s ) ,
1 digit (s), 1 non - alphanumeric symbol ( s )
- The password should be different from the username
Password :
Re - enter Password :
What groups do you want this user to belong to ? ( Please enter a comma separated
92
www.k19.com.br
93
15
1
2
3
4
5
6
7
8
9
10 remote . connection . default . username = k19
11 remote . connection . default . password = singleton123 #
Arquivo de Propriedades 4.1: jboss-ejb-client.properties
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
www.facebook.com/k19treinamentos
93
94
System . out . println ( " Incrementando " + threads . length * threads . length
+ " vezes " ) ;
for ( int i = 0; i < threads . length ; i ++) {
threads [ i ] = new Thread ( new Runnable () {
@Override
public void run () {
for ( int i = 0; i < threads . length ; i ++) {
contador . incrementa () ;
}
}
}) ;
threads [ i ]. start () ;
}
for ( Thread thread : threads ) {
thread . join () ;
}
System . out . println ( " Contador = " + contador . getValor () ) ;
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@Singleton
@Remote ( Contador . class )
public class ContadorBean implements Contador {
private int valor ;
public void incrementa () {
this . valor ++;
}
@Lock ( LockType . READ )
public int getValor () {
return this . valor ;
}
}
Cdigo Java 4.26: ContadorBean.java
19
Reinicie o Wildfly. Execute alguns vezes a classe TesteDeAcessoConcorrente e observe que o
valor do contador estar correto.
94
www.k19.com.br
CAPTULO
P ERSISTNCIA
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 configuraes relativas s conexes JDBC podem ser definidas nas aplicaes ou nos servidores de aplicao. Quando definidas em uma aplicao sero utilizadas somente por essa aplicao.
Quando definidas em um servidor de aplicao podem ser utilizadas em diversas aplicaes.
Em um servidor de aplicao, as configuraes JDBC so definidas em componentes chamados
Data Sources. A criao de Data Sources depende do servidor de aplicao utilizado. Em particular,
no Glassfish, os Data Sources podem ser criados atravs da interface de administrao.
Os Data Sources permitem que uma nica configurao JDBC seja utilizada por diversas aplicaes. Eles tambm permitem que outros tipos de configuraes sejam compartilhadas. Por exemplo,
a configurao de um Connection Pool.
Alm disso, atravs de Data Sources podemos utilizar facilmente o servio de transaes dos
servidores de aplicao. Esse servio definido pela especificao Java Transaction API (JTA).
Exerccios de Fixao
Vamos configurar um Data Source no Glassfish. Copie o arquivo mysql-connector-java-VERSAObin.jar que se encontra na pasta K19-Arquivos/mysql-connector-java-VERSAO da rea de Trabalho
para a pasta glassfishv4/glassfish/lib.
1
Importante
Voc tambm pode obter o driver JDBC do MySQL atravs do site da K19: www.k19.
com.br/arquivos.
Acesse o MySQL Server atravs do MySQL Workbench ou atravs do cliente de linha de comando; apague a base de dados k22_glassfish caso ela exista; crie uma base de dados chamada
k22_glassfish.
2
www.facebook.com/k19treinamentos
95
P ERSISTNCIA
96
96
www.k19.com.br
97
P ERSISTNCIA
DatabaseName: k22_glassfish
Password: root
ServerName: localhost
URL: jdbc:mysql://localhost:3306/k22_glassfish
url: jdbc:mysql://localhost:3306/k22_glassfish
User: root
Depois, clique em finish. Para testar o Connection Pool K19, siga os passos abaixo:
www.facebook.com/k19treinamentos
97
P ERSISTNCIA
98
98
www.k19.com.br
99
P ERSISTNCIA
99
P ERSISTNCIA
100
100
www.k19.com.br
101
P ERSISTNCIA
Agora, vamos configurar um Data Source no Wildfly. Crie uma pasta chamada mysql dentro
da pasta modules/system/layers/base/com do Wildfly. Dentro da pasta mysql crie uma pasta chamada main. Copie o arquivo mysql-connector-java-VERSAO-bin.jar que se encontra na pasta K19Arquivos/mysql-connector-java-VERSAO da rea de Trabalho para a pasta main.
4
Importante
Voc tambm pode obter o driver JDBC do MySQL atravs do site da K19: www.k19.
com.br/arquivos.
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < module xmlns = " urn:jboss:module:1 .0 " name = " com . mysql " >
3
< resources >
4
< resource - root path = " mysql - connector - java -5.1.35 - bin . jar " / >
5
</ resources >
6
< dependencies >
www.facebook.com/k19treinamentos
101
P ERSISTNCIA
102
7
< module name = " javax . api " / >
8
</ dependencies >
9 </ module >
Cdigo XML 5.1: module.xml
Na linha 4, indique corretamente o nome correspondente ao arquivo do driver que voc est
utilizando.
6 Acesse o MySQL Server atravs do MySQL Workbench ou atravs do cliente de linha de comando;
apague a base de dados k22_wildfly caso ela exista; crie uma base de dados chamada k22_wildfly.
Altere o arquivo de configurao do Wildfly (standalone/configuration/standalone.xml). Adicione dentro da tag <datadources> a configurao de um novo Data Source.
7
1
2
3
4
5
6
7
8
9
10
11
...
< datasource jndi - name = " java: / jdbc / K19 " pool - name = " K19 " jta = " true "
enabled = " true " use - java - context = " true " use - ccm = " true " >
< connection - url > jdbc:mysql: // localhost:3306 / k22_wildfly </ connection - url >
< driver > com . mysql </ driver >
< security >
< user - name > root </ user - name >
< password > root </ password >
</ security >
</ datasource >
...
Cdigo XML 5.2: standalone.xml
...
< driver name = " com . mysql " module = " com . mysql " >
<xa - datasource - class >
com . mysql . jdbc . jdbc2 . optional . MysqlXADataSource
</ xa - datasource - class >
< driver - class > com . mysql . jdbc . Driver </ driver - class >
</ driver >
...
Cdigo XML 5.3: standalone.xml
Pare o Glassfish. Inicie o Wildfly e observe se o Data Source foi criado corretamente. No console,
deve aparecer uma mensagem semelhante a que apresentada abaixo.
8
persistence.xml
Em um ambiente Java EE, diversas configuraes relativas persistncia so realizadas nos Data
Sources. Contudo, algumas configuraes ainda devem ser realizadas pelas aplicaes. A especificao JPA determina que cada aplicao contenha um arquivo de configuraes chamado persistence.xml dentro de uma pasta chamada META-INF no classpath da aplicao.
102
www.k19.com.br
103
P ERSISTNCIA
No arquivo persistece.xml podemos definir qual Data Source ser utilizado pela aplicao.
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
< provider > org . hibernate . ejb . HibernatePersistence </ provider >
10
<jta - data - source > jdbc / K19 </ jta - data - source >
11
12
< properties >
13
< property name = " hibernate . show_sql " value = " true " / >
14
< property name = " hibernate . format_sql " value = " true " / >
15
< property name = " hibernate . hbm2ddl . auto " value = " update " / >
16
< property name = " hibernate . dialect " value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
17
</ properties >
18
</ persistence - unit >
19 </ persistence >
Cdigo XML 5.4: persisntece.xml
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 chamados Entity
Beans. So exemplos de entity beans que poderiam formar uma aplicao:
clientes
produtos
pedidos
funcionrios
fornecedores
@Entity a principal anotao do JPA. Ela que deve aparecer antes do nome de uma classe. E deve
ser definida em todas as classes que tero objetos persistidos no banco de dados.
As classes anotadas com @Entity 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 @Entity so mapeados para colunas na
tabela correspondente classe. Outra vez, por conveno, as colunas possuem os mesmos nowww.facebook.com/k19treinamentos
103
P ERSISTNCIA
104
mes dos atributos. E novamente, podemos alterar esse padro utilizando para isso a anotao
@Column.
@Id Utilizada para indicar qual atributo de uma classe anotada com @Entity ser mapeado para a
chave primria da tabela correspondente classe. Geralmente o atributo anotado com @Id
do tipo Long.
@GeneratedValue Geralmente vem acompanhado da anotao @Id. 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 @Entity
2 public class Livro {
3
4
@Id @GeneratedValue ( strategy = GenerationType . IDENTITY )
5
private Long id ;
6
7
private String nome ;
8
9
private Double preco ;
10
11
// GETTERS AND SETTERS
12 }
Cdigo Java 5.1: Livro.java
1 @Entity
2 public class Autor {
3
4
@Id @GeneratedValue ( strategy = GenerationType . IDENTITY )
5
private Long id ;
6
7
private String nome ;
8
9
@ManyToMany
10
private List < Livro > livros ;
11
12
// GETTERS AND SETTERS
13 }
Cdigo Java 5.2: Autor.java
Consulte a apostila do curso K21 - Persistncia com JPA 2 e Hibernate para obter detalhes sobre
o mapeamento das Entity Classes http://www.k19.com.br/downloads/apostilas-java.
Exerccios de Fixao
Para no confundir, feche os projetos chatWeb e contadorJavaSE. Para isso, clique com o boto
direito do mouse sobre esses projetos e selecione a opo Close Project.
9
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.
10
104
www.k19.com.br
105
P ERSISTNCIA
www.facebook.com/k19treinamentos
105
P ERSISTNCIA
106
106
www.k19.com.br
107
P ERSISTNCIA
www.facebook.com/k19treinamentos
107
P ERSISTNCIA
108
11
12
INF.
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " create " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML 5.5: persistence.xml
13
Crie um pacote chamado br.com.k19.entidades no projeto persistenciaWeb e adicione nesse
pacote uma Entity Class para definir os livros de uma editora.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entity
public class Livro {
@Id @GeneratedValue ( strategy = GenerationType . IDENTITY )
private Long id ;
private String nome ;
private Double preco ;
// GETTERS AND SETTERS
}
Cdigo Java 5.3: Livro.java
Adicione no pacote br.com.k19.entidades uma Entity Class para definir autores dos livros de
uma editora.
14
1
2
3
4
5
6
7
8
108
www.k19.com.br
109
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
P ERSISTNCIA
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://online.k19.com.br.
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 @Stateless
2 public class CalculadoraBean {
3
4
@PersisteceContext
5
private EntityManager manager ;
6
www.facebook.com/k19treinamentos
109
P ERSISTNCIA
110
7
// Resto do cdigo
8 }
Cdigo Java 5.7: CalculadoraBean.java
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 @Stateless
2 public class CalculadoraBean {
3
4
@PersisteceUnit
5
private EntityManagerFactory factory ;
6
7
// Resto do cdigo
8 }
Cdigo Java 5.9: CalculadoraBean.java
110
www.k19.com.br
111
P ERSISTNCIA
Exerccios de Fixao
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
www.facebook.com/k19treinamentos
111
P ERSISTNCIA
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 }
112
Crie uma tela para cadastrar livros. Adicione na pasta WebContent um arquivo chamado livros.xhtml com o seguinte contedo.
17
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 > Livros </ title >
</ h : head >
<h : body >
< h1 > Novo Livro </ h1 >
<h : messages / >
<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 >
Cdigo XHTML 5.1: livros.xhtml
112
www.k19.com.br
113
P ERSISTNCIA
19 Acesse o MySQL Server atravs do MySQL Workbench ou atravs do cliente de linha de comando;
Verifique as tabelas geradas na base de dados k22_glassfish e seus respectivos dados.
Acesse o MySQL Server atravs do MySQL Workbench ou atravs do cliente de linha de comando;
Verifique as tabelas geradas na base de dados k22_wildfly e seus respectivos dados.
21
www.facebook.com/k19treinamentos
113
P ERSISTNCIA
114
114
www.k19.com.br
CAPTULO
T RANSAES
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 especfica para que uma
determinada tarefa seja realizada. Tipicamente, as transaes modificam informaes armazenadas
em resources (bases de dados, filas de mensagens, sistemas corporativos de informao - EIS, entre
outros).
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 finalizada no podem afetar operaes
que no fazem parte da transao.
Durabilidade: Aps a confirmao de uma transao, as modificaes realizadas por ela devem ser
refletidas nos resources mesmo que acontea uma falha de hardware.
JTA e JTS
www.facebook.com/k19treinamentos
115
T RANSAES
116
Todo servidor de aplicao Java EE deve oferecer suporte para as aplicaes utilizarem transaes. As especificaes relacionadas a esse tpico so: Java Transaction API - JTA e Java Transaction
Service - JTS. Os documentos dessas especificaes podem ser obtidos atravs do site: www.jcp.org.
A especificao Enterprise Java Beans (EJB) fortemente integrada com as especificaes JTA e
JTS, simplificando 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:
@Stateful
@TransactionManagement ( TransactionManagementType . CONTAINER )
public class CarrinhoBean {
...
}
Atributo Transacional
O EJB Container abre, confirma, 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 definido com um dos seguintes valores: REQUIRED, REQUIRES_NEW, SUPPORTS, MANDATORY, NOT_SUPPORTED e NEVER.
O comportamento do EJB Container o seguinte:
116
www.k19.com.br
117
T RANSAES
Atributo Transacional
REQUIRED
REQUIRED
NO
SIM
REQUIRES_NEW
REQUIRES_NEW
NO
SIM
SUPPORTS
SUPPORTS
NO
SIM
No faz nada
Usa a transao que j estava
aberta
MANDATORY
NO
MANDATORY
SIM
Lana EJBTransactionRequiredException
Usa a transao que j estava
aberta
NOT_SUPPORTED
NOT_SUPPORTED
NO
SIM
No faz nada
Suspende a que estava aberta
NEVER
NEVER
NO
SIM
No faz nada
Lana EJBException
Quando queremos que todos os mtodos de um Session Bean possuam o mesmo atributo transacional, devemos anotar a classe com @TransactionAttribute.
1
2
3
4
5
6
@Stateful
@TransactionManagement ( TransactionManagementType . CONTAINER )
@TransactionAttribute ( TransactionAttributeType . REQUIRED )
public class CarrinhoBean {
...
}
Caso nenhum atributo transacional seja definido explicitamente, o EJB Container utilizar por
padro o REQUIRED.
www.facebook.com/k19treinamentos
117
T RANSAES
118
9
context . setRollbackOnly () ;
10
}
11
...
12
}
13 }
Cdigo Java 6.4: CarrinhoBean.java
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 classificao de uma System
Exception.
1 @ApplicationException
2 public class ValorNegativoException extends RuntimeException {
3
4 }
Cdigo Java 6.5: ValorNegativoException.java
A mesma anotao pode alterar o comportamento padro para rollback das Application Exceptions.
1 @ApplicationException ( rollback = true )
2 public class ValorNegativoException extends RuntimeException {
3
4 }
Cdigo Java 6.6: ValorNegativoException.java
118
www.k19.com.br
119
T RANSAES
No modo BMT, devemos injetar um UserTransaction atravs da anotao @Resource. Esse objeto permite que a aplicao abra, confirme 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.
Exerccios de Fixao
Para no confundir, feche o projeto persistenciaWeb. Para isso, clique com o boto direito do
mouse sobre esse projeto e selecione a opo Close Project.
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.
2
www.facebook.com/k19treinamentos
119
T RANSAES
120
120
www.k19.com.br
121
T RANSAES
www.facebook.com/k19treinamentos
121
T RANSAES
122
122
www.k19.com.br
123
T RANSAES
INF.
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " create " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML 6.1: persistence.xml
5
Crie um pacote chamado br.com.k19.entidades no projeto transacoesWeb e adicione nesse
pacote uma Entity Class para definir os produtos de uma loja.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Entity
public class Produto {
@Id @GeneratedValue ( strategy = GenerationType . IDENTITY )
private Long id ;
private String nome ;
private double preco ;
// GETTERS AND SETTERS
}
Cdigo Java 6.9: Produto.java
1
2
3
4
5
6
7
8
www.facebook.com/k19treinamentos
123
T RANSAES
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
124
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
124
@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 ;
}
www.k19.com.br
125
T RANSAES
34
35
36
37
38
39
40
41 }
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 >
Cdigo XHTML 6.1: produtos.xhtml
9
Remova o projeto persistenciaWeb do Wildfly. Adicione o projeto transacoesWeb no Glassfish.
Certifique-se que o JBoss e o Wildfly estejam parados. Inicie o Glassfish e teste a aplicao acessando
a url http://localhost:8080/transacoesWeb/produtos.xhtml.
Adicione o projeto transacoesWeb no glassfish. Clique com o boto direito no glassfish da view
Servers e escolha a opo Add and Remove.
10
Adicione alguns produtos e observe que produtos com preo negativo no so persistidos devido
www.facebook.com/k19treinamentos
125
T RANSAES
126
ao rollback.
126
www.k19.com.br
CAPTULO
S EGURANA
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 configuraes 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 Glassfish.
Exerccios de Fixao
www.facebook.com/k19treinamentos
127
S EGURANA
128
Adicione um usurio chamado K19 dentro de um grupo chamado admin com a senha K19. Siga
os passos abaixo:
2
128
www.k19.com.br
129
S EGURANA
www.facebook.com/k19treinamentos
129
S EGURANA
130
Grupo
admin
users
Senha
keizo
afk
Acesse o MySQL Server atravs do MySQL Workbench ou atravs do cliente de linha de comando;
crie tabelas chamadas Usuario, Grupo e Usuario_Grupo na base de dados k22_glassfish.
4
130
www.k19.com.br
131
5
1
2
3
4
5
6
7
8
9
10
S EGURANA
131
S EGURANA
132
Exerccios de Fixao
Para no confundir, feche o projeto transacoesWeb. Para isso, clique com o boto direito do
mouse sobre esse projeto e selecione a opo Close Project.
7
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.
8
132
www.k19.com.br
133
S EGURANA
www.facebook.com/k19treinamentos
133
S EGURANA
134
134
www.k19.com.br
135
S EGURANA
www.facebook.com/k19treinamentos
135
S EGURANA
136
1
2
3
4
5
6
7
8
9
10
11
...
< 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 >
...
Cdigo XML 7.1: glassfish-web.xml
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
...
< welcome - file - list >
< welcome - file > index . xhtml </ welcome - file >
</ welcome - file - list >
< login - config >
< auth - method > FORM </ auth - method >
< realm - name >K19 - Realm </ realm - name >
< form - login - config >
< form - login - page >/ login . xhtml </ form - login - page >
< form - error - page >/ acesso - negado . xhtml </ form - error - page >
</ form - login - config >
</ 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 >
...
Cdigo XML 7.2: web.xml
1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5
xmlns : ui = " http :// java . sun . com / jsf / facelets "
136
www.k19.com.br
137
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
S EGURANA
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
12 Adicione um arquivo chamado acesso-negado.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
17
<! 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 > Acesso Negado </ h1 >
<h : link outcome = " / login " value = " Tentar novamente " / >
</ h : body >
</ html >
Cdigo XHTML 7.2: acesso-negado.xhtml
Adicione um arquivo chamado menu.xhtml em uma pasta chamada includes dentro de WebContent/WEB-INF no projeto segurancaWeb com seguinte contedo.
13
1 < ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
2
xmlns : ui = " http :// java . sun . com / jsf / facelets "
3
xmlns : h = " http :// java . sun . com / jsf / html "
4
xmlns : f = " http :// java . sun . com / jsf / core " >
5
6
<h : form >
7
<h : panelGrid >
8
<h : commandLink action = " #{ autenticadorMB . sair } " value = " Sair " / >
9
</ h : panelGrid >
10
</ h : form >
11
12 </ ui : composition >
Cdigo XHTML 7.3: menu.xhtml
14
137
S EGURANA
138
<! 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 > Autenticado </ h1 >
< ui : include src = " / WEB - INF / includes / menu . xhtml " / >
</ h : body >
</ html >
Cdigo XHTML 7.4: index.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@ManagedBean
public class AutenticadorMB {
public String sair () {
FacesContext fc = FacesContext . getCurrentInstance () ;
ExternalContext ec = fc . getExternalContext () ;
HttpSession session = ( HttpSession ) ec . getSession ( false ) ;
session . invalidate () ;
return " / login " ;
}
}
Cdigo Java 7.1: AutenticadorMB.java
Grupo
admin
admin
users
Senha
K19
keizo
afk
www.k19.com.br
139
17
1
2
3
4
5
6
7
8
9
10
11
12
S EGURANA
18
19
Adicione uma pasta chamada META-INF na pasta src do projeto segurancaWeb. Na pasta
META-INF, crie o arquivo persistence.xml.
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " none " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML 7.4: persistence.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
www.facebook.com/k19treinamentos
139
S EGURANA
16
17
18
19
20
21
22
23
24
25 }
140
21
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Entity
@Table ( name = " Usuario " )
public class Usuario {
@Id
private String nome ;
private String senha ;
@ManyToMany ( fetch = FetchType . EAGER )
private List < Grupo > grupos = new ArrayList < Grupo >() ;
// GETTERS AND SETTERS
}
Cdigo Java 7.3: Usuario.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
140
@PersistenceContext
private EntityManager manager ;
www.k19.com.br
141
20
21
22
23
24
S EGURANA
this . manager . persist ( g ) ;
}
25
26
27 }
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
www.facebook.com/k19treinamentos
141
S EGURANA
142
15
16 @ManagedBean
17 public class UsuarioMB {
18
19
@EJB
20
private UsuarioRepositorio usuarioRepositorio ;
21
22
@EJB
23
private GrupoRepositorio grupoRepositorio ;
24
25
private Usuario usuario = new Usuario () ;
26
27
private List < String > nomesDosGrupos ;
28
29
private List < Usuario > usuarios ;
30
31
private List < Grupo > grupos ;
32
33
public void adiciona () throws NoSuchAlgorithmException {
34
// Associando os Grupos ao novo Usurio
35
for ( String nomeDoGrupo : this . nomesDosGrupos ) {
36
Grupo g = new Grupo () ;
37
g . setNome ( nomeDoGrupo ) ;
38
this . usuario . getGrupos () . add ( g ) ;
39
}
40
41
// Criptografando a senha do novo Usurio
42
MessageDigest md = MessageDigest . getInstance ( " MD5 " ) ; // or " SHA -1"
43
md . update ( this . usuario . getSenha () . getBytes () ) ;
44
BigInteger hash = new BigInteger (1 , md . digest () ) ;
45
String senhaCriptografada = hash . toString (16) ;
46
while ( senhaCriptografada . length () < 32) { // 40 for SHA -1
47
senhaCriptografada = " 0 " + senhaCriptografada ;
48
}
49
this . usuario . setSenha ( senhaCriptografada ) ;
50
51
// Salvando o usurio
52
this . usuarioRepositorio . adiciona ( this . usuario ) ;
53
this . usuario = new Usuario () ;
54
this . usuarios = null ;
55
}
56
57
public List < Grupo > getGrupos () {
58
if ( this . grupos == null ) {
59
this . grupos = this . grupoRepositorio . buscaTodos () ;
60
}
61
62
return this . grupos ;
63
}
64
65
public List < Usuario > getUsuarios () {
66
if ( this . usuarios == null ) {
67
this . usuarios = this . usuarioRepositorio . buscaTodos () ;
68
}
69
70
return this . usuarios ;
71
}
72
73
public Usuario getUsuario () {
74
return usuario ;
75
}
76
77
public void setUsuario ( Usuario usuario ) {
78
this . usuario = usuario ;
79
}
80
81
public List < String > getNomesDosGrupos () {
82
return nomesDosGrupos ;
83
}
84
142
www.k19.com.br
143
S EGURANA
85
public void setNomesDosGrupos ( List < String > nomesDosGrupos ) {
86
this . nomesDosGrupos = nomesDosGrupos ;
87
}
88 }
Cdigo Java 7.6: UsuarioMB.java
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
43
44
45
46
47
48
49
50
51
52
<! 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 >
< ui : include src = " / WEB - INF / includes / menu . xhtml " / >
< h1 > Novo Usuario </ h1 >
<h : messages / >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Nome " / >
<h : inputText value = " #{ usuarioMB . usuario . nome } " required = " true " / >
<h : outputLabel value = " Senha " / >
<h : inputSecret value = " #{ usuarioMB . usuario . senha } " required = " true " / >
<h : selectManyCheckbox value = " #{ usuarioMB . nomesDosGrupos } "
required = " true " >
<f : selectItems value = " #{ usuarioMB . grupos } " var = " g "
itemLabel = " #{ g . nome } " itemValue = " #{ g . nome } " / >
</ h: selectManyCheckbox >
</ h : panelGrid >
<h : commandButton value = " Salvar " action = " #{ usuarioMB . adiciona } " / >
</ h : form >
< hr / >
<h : dataTable value = " #{ usuarioMB . usuarios } " var = " u " border = " 1 " >
<h : column >
<f : facet name = " header " > Nome do Usurio </ f : facet >
<h : outputText value = " #{ u . nome } " / >
</ h : column >
<h : column >
<f : facet name = " header " > Grupos </ f : facet >
<h : outputText value = " #{ u . grupos } " / >
</ h : column >
</ h : dataTable >
</ h : body >
</ html >
Cdigo XHTML 7.5: index.xhtml
www.facebook.com/k19treinamentos
143
S EGURANA
144
26
1 < ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
2
xmlns : ui = " http :// java . sun . com / jsf / facelets "
3
xmlns : h = " http :// java . sun . com / jsf / html "
4
xmlns : f = " http :// java . sun . com / jsf / core " >
5
6
<h : form >
7
<h : panelGrid >
8
<h : commandLink action = " #{ autenticadorMB . sair } " value = " Sair " / >
9
<h : commandLink action = " / usuarios " value = " Usurios " / >
10
</ h : panelGrid >
11
</ h : form >
12 </ ui : composition >
Cdigo XHTML 7.6: menu.xhtml
27
Grupo
admin
admin
users
Senha
K19
keizo
afk
28
usuarios.xhtml
@RolesAllowed
Restries de acesso podem ser definidas pela anotao @RolesAllowed que pode ser aplicada
na classe ou nos mtodos de um Session Bean. Se aplicada na classe valer para todos os mtodos.
Se aplicada ao mesmo tempo na classe e em algum mtodo, valer as restries definidas no mtodo.
1 @RolesAllowed ({ " administrador " , " moderador " })
2 public void adiciona ( Produto produto ) {
3
this . manager . persist ( produto ) ;
4 }
1
2
3
4
5
144
www.k19.com.br
145
S EGURANA
@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 @PermitAll
2 public void adiciona ( Produto produto ) {
3
this . manager . persist ( produto ) ;
4 }
1
2
3
4
5
@PermitAll
@Stateful
class CarrinhoBean {
...
}
Cdigo Java 7.10: CarrinhoBean.java
@DenyAll
O funcionamento da anotao @DenyAll exatamente o oposto da @PermitAll. Podemos utilizar a anotao @DenyAll em aplicaes que so implantadas em ambientes diferentes. Sendo que
em determinados ambientes certas funcionalidades devem ser desabilitadas.
1 @DenyAll
2 public void adiciona ( Produto produto ) {
3
this . manager . persist ( produto ) ;
4 }
1
2
3
4
5
@DenyAll
@Stateful
class CarrinhoBean {
...
}
Cdigo Java 7.12: CarrinhoBean.java
@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 definir o papel de
administrador para o primeiro Session Bean atravs da anotao @RunAs.
1 @Stateless
2 @RunAs ( " administrador " )
3 class MensagemRepositorio {
4
5
@PersistenceContext
6
private EntityManager manager ;
7
8
@EJB
9
private TopicoRepositorio topicoRepositorio ;
10
11
@RolesAllowed ({ " moderador " })
12
public void remove ( Long id ) {
13
Mensagem m = this . manager . find ( Mensagem . class , id ) ;
14
this . manager . remove ( m ) ;
www.facebook.com/k19treinamentos
145
S EGURANA
146
15
16
Topico t = m . getTopico () ;
17
18
if ( t . getMensagens () . size () == 1) {
19
this . topicoRepositorio . remove ( t ) ;
20
}
21
}
22 }
Cdigo Java 7.13: MensagemRepositorio.java
Exerccios de Fixao
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
1
2
3
4
5
6
7
8
9
10
146
www.k19.com.br
147
S EGURANA
31
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
32
www.facebook.com/k19treinamentos
147
S EGURANA
148
1 < ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
2
xmlns : ui = " http :// java . sun . com / jsf / facelets "
3
xmlns : h = " http :// java . sun . com / jsf / html "
4
xmlns : f = " http :// java . sun . com / jsf / core " >
5
6
<h : form >
7
<h : panelGrid >
8
<h : commandLink action = " #{ autenticadorMB . sair } " value = " Sair " / >
9
<h : commandLink action = " / usuarios " value = " Usurios " / >
10
<h : commandLink action = " / tarefas " value = " Tarefas " / >
11
</ h : panelGrid >
12
</ h : form >
13 </ ui : composition >
Cdigo XHTML 7.8: menu.xhtml
33
148
www.k19.com.br
CAPTULO
I NTERCEPTADORES
Uma aplicao EJB pode definir, 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.
Interceptor Methods
A lgica de um interceptador definida 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
www.facebook.com/k19treinamentos
149
I NTERCEPTADORES
150
8
9
// VOLTA
10
System . out . println ( " DEPOIS DO MTODO DE NEGCIO " ) ;
11
return retornoDoMetodoDeNegocio ;
12 }
Internal Interceptors
Um interceptador interno criado quando um mtodo interceptador definido 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 @Stateless
2 class CalculadoraBean {
3
4
// MTODOS DE NEGCIO
5
6
// MTODOS DE CALLBACK
7
8
// MTODO INTERCEPTADOR
9
@AroundInvoke
10
public Object interceptador ( InvocationContext ic ) throws Exception {
11
// IDA
12
System . out . println ( " ANTES DO MTODO DE NEGCIO " ) ;
13
14
// CHAMANDO O MTODO DE NEGCIO E PEGANDO O SEU RETORNO
15
Object retornoDoMetodoDeNegocio = ic . proceed () ;
16
17
// VOLTA
18
System . out . println ( " DEPOIS DO MTODO DE NEGCIO " ) ;
19
return retornoDoMetodoDeNegocio ;
20
}
21 }
Cdigo Java 8.3: CalculadoraBean.java
External Interceptors
Os interceptadores externos so criados quando um mtodo interceptador definido fora de um
Session Bean em uma classe comum. Novamente, no mais do que um mtodo interceptador pode
ser definido em uma mesma classe.
1 class LoggingInterceptor {
2
3
@AroundInvoke
4
public Object interceptador ( InvocationContext ic ) throws Exception {
5
// IDA
6
System . out . println ( " ANTES DO MTODO DE NEGCIO " ) ;
7
8
// CHAMANDO O MTODO DE NEGCIO E PEGANDO O SEU RETORNO
9
Object retornoDoMetodoDeNegocio = ic . proceed () ;
10
11
// VOLTA
12
System . out . println ( " DEPOIS DO MTODO DE NEGCIO " ) ;
13
return retornoDoMetodoDeNegocio ;
14
}
15 }
Cdigo Java 8.4: LoggingInterceptor.java
150
www.k19.com.br
151
I NTERCEPTADORES
Method-Level Interceptors
Interceptadores externos podem ser associados a mtodos de negcio atravs da anotao @Interceptors.
1 @Stateless
2 class CalculadoraBean {
3
4
@Interceptors ({ LoggingInterceptor . class })
5
public double soma ( double a , double b ) {
6
return a + b ;
7
}
8 }
Cdigo Java 8.5: CalculadoraBean.java
Vrios interceptadores externos podem ser associados a um mtodo de negcio atravs da anotao @Interceptors.
1 @Stateless
2 class CalculadoraBean {
3
4
@Interceptors ({ LoggingInterceptor . class , SegurancaInterceptor . class })
5
public double soma ( double a , double b ) {
6
return a + b ;
7
}
8 }
Cdigo Java 8.6: CalculadoraBean.java
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 ;
}
}
Cdigo Java 8.7: CalculadoraBean.java
Vrios interceptadores externos podem ser associados a um Session Bean atravs da anotao
@Interceptors.
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 ;
}
}
Cdigo Java 8.8: CalculadoraBean.java
www.facebook.com/k19treinamentos
151
I NTERCEPTADORES
152
Default Interceptors
Interceptadores externos tambm podem ser associados a mtodos de negcio atravs de configuraes adicionadas no arquivo de configurao 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 definido pela classe LoggingInterceptor
tenha que ser aplicado em todos os mtodos de negcio de todos os Session Beans.
1 < interceptor - binding >
2
<ejb - name >* </ ejb - name >
3
< interceptor - class > interceptadores . LoggingInterceptor </ interceptor - class >
4 </ interceptor - binding >
Excluindo Interceptadores
Podemos excluir os Default Interceptors e os Class-Level Interceptors atravs das anotaes @ExcludeDefaultInterceptors e @ExcludeClassInterceptors respectivamente.
A anotao @ExcludeDefaultInterceptors 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 ;
}
}
Cdigo Java 8.9: CalculadoraBean.java
@Stateless
@Interceptors ({ LoggingInterceptor . class , SegurancaInterceptor . class })
class CalculadoraBean {
@ExcludeClassInterceptors
public double soma ( double a , double b ) {
return a + b ;
}
}
Cdigo Java 8.10: CalculadoraBean.java
Invocation Context
152
www.k19.com.br
153
I NTERCEPTADORES
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 public interface InvocationContext {
2
public Object getTarget () ;
3
public Method getMethod () ;
4
public Object [] getParameters () ;
5
public void setParameters ( Object []) ;
6
public java . util . Map < String , Object > getContextData () ;
7
public Object proceed () throws Exception ;
8 }
Cdigo Java 8.11: InvocationContext.java
Exerccios de Fixao
Para no confundir, feche o projeto segurancaWeb. Para isso, clique com o boto direito do
mouse sobre esse projeto e selecione a opo Close Project.
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.
2
www.facebook.com/k19treinamentos
153
I NTERCEPTADORES
154
154
www.k19.com.br
155
I NTERCEPTADORES
www.facebook.com/k19treinamentos
155
I NTERCEPTADORES
156
156
www.k19.com.br
157
I NTERCEPTADORES
Adicione uma pasta chamada META-INF na pasta src do projeto interceptadoresWeb. Na pasta
META-INF, crie o arquivo persistence.xml.
3
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " create " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML 8.1: persistence.xml
4
Crie um pacote chamado br.com.k19.entidades no projeto interceptadoresWeb e adicione
nesse pacote um Entity Bean para modelar mensagens.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
www.facebook.com/k19treinamentos
157
I NTERCEPTADORES
15
16
17
18
19
20
21
22
23
24
25
26
27
28 }
158
@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 () ;
}
Crie um pacote chamado br.com.k19.managedbeans no projeto interceptadoresWeb e adicione nesse pacote um Managed Bean para oferecer algumas aes para as telas.
6
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
158
www.k19.com.br
159
I NTERCEPTADORES
Crie uma tela para cadastrar mensagens. Adicione na pasta WebContent do projeto interceptadoresWeb um arquivo chamado mensagens.xhtml com o seguinte contedo.
7
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 >
Cdigo XHTML 8.3: mensagens.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
159
I NTERCEPTADORES
160
guinte contedo.
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 <ejb - jar version = " 3.1 " xmlns = " http :// java . sun . com / xml / ns / javaee "
3
xmlns : xsi = " http :// www . w3 . org /2001/ XMLSchema - instance "
4
xsi : schemaLocation = " http :// java . sun . com / xml / ns / javaee http :// java . sun . com / xml / ns / javaee / ejb - jar_3_1 . xsd " >
5
6
< interceptors >
7
< interceptor >
8
< interceptor - class >
9
br . com . k19 . interceptadores . LoggingInterceptor
10
</ interceptor - class >
11
</ interceptor >
12
</ interceptors >
13
14
< assembly - descriptor >
15
< interceptor - binding >
16
<ejb - name >* </ ejb - name >
17
< interceptor - class >
18
br . com . k19 . interceptadores . LoggingInterceptor
19
</ interceptor - class >
20
</ interceptor - binding >
21
</ assembly - descriptor >
22 </ ejb - jar >
Cdigo XHTML 8.4: ejb-jar.xml
10 Remova o projeto segurancaWeb do Glassfish. Adicione o projeto interceptadoresWeb no Wildfly. Certifique-se que o Glassfish e o JBoss estejam parados. Inicie o Wildfly e teste a aplicao acessando a url http://localhost:8080/interceptadoresWeb/mensagens.xhtml. Verifique o log do
Wildfly para observar as mensagens do interceptador.
Implemente um interceptador externo para eliminar palavras proibidas das mensagens adicionas o logging da aplicao. Adicione no pacote br.com.k19.interceptadores do projeto interceptadoresWeb a seguinte classe.
11
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
160
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 ) {
www.k19.com.br
161
27
28
I NTERCEPTADORES
String textoOriginal = mensagem . getTexto () ;
String textoCensurado = textoOriginal . replaceAll ( palavraProibida , " ! CENSURADO ! " );
mensagem . setTexto ( textoCensurado ) ;
29
30
}
31
return ic . proceed () ;
32
}
33 }
Associe o interceptador de censura ao mtodo de adicionar mensagens do session bean MensagemRepositorio. No esquea de adicionar o importe da anotao import javax.interceptor.Interceptors.
12
1
2
3
4
5
6
...
@Interceptors ({ CensuraInterceptor . class })
public void adiciona ( Mensagem mensagem ) {
this . manager . persist ( mensagem ) ;
}
...
Cdigo Java 8.17: MensagemRepositorio.java
13
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " none " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML 8.2: persistence.xml
14
mensagens.xhtml.
www.facebook.com/k19treinamentos
161
I NTERCEPTADORES
162
162
www.k19.com.br
CAPTULO
S CHEDULING
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 confirmao dos pagamentos. Quando um cliente realiza um pedido,
o sistema da empresa deve esperar alguns dias para verificar se o pagamento correspondente foi
realizado para que a entrega possa ser liberada.
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 createTimer() 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 TimerService utilizando a
sobrecarga do mtodo createTimer().
1 timerService . createTimer (30 * 60 * 1000 , 30 * 60 * 1000 , " info " ) ;
Os alarmes no podem ser criados para Stateful Session Beans. Essa funcionalidade deve ser
adicionada em verses futuras da especificao Enterprise Java Beans.
Mtodos de Timeout
www.facebook.com/k19treinamentos
163
S CHEDULING
164
Quando um alarme (timer) dispara, o EJB Container executa um mtodo de timeout no Bean
que criou o alarme. Para definir um mtodo de timeout devemos utilizar a anotao @Timeout.
1 @Stateless
2 class PedidoBean {
3
4
@Resource
5
private TimerService timerService ;
6
7
public void registraPedido ( Pedido pedido ) {
8
this . timerService . createTimer (5 * 24 * 60 * 60 * 1000 , pedido ) ;
9
}
10
11
@Timeout
12
public void verificaPagamento ( Timer timer ) {
13
Pedido pedido = ( Pedido ) timer . getInfo () ;
14
// verifica o pagamento do pedido
15
}
16 }
Cdigo Java 9.4: PedidoBean.java
Timers Automticos
Na verso 3.1 da especificao Enterprise Java Beans, os alarmes podem ser criados e automaticamente associados a mtodos de timeout atravs da anotao @Schedule.
1 @Stateless
2 class FolhaDePagamentoBean {
3
4
@Schedule ( dayOfMonth = " 1 " )
5
public void calculaSalarios () {
6
// implementacao
7
}
8 }
Cdigo Java 9.5: FolhaDePagamentoBean.java
month
dayOfWeek
year
Valores
[0 . . . 59]
[0 . . . 59]
[0 . . . 23]
[1 . . . 31]
[-7 . . . -1] quantidade de dias para o trmino do ms.
[1st, 2nd, 3rd, 4th, 5th, Last ]
[Sun, Mon, Tue, Wed, Thu, Fri, Sat]
[1 . . . 12]
[Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec ]
[0 . . . 7]
[Sun, Mon, Tue, Wed, Thu, Fri, Sat]
ano com 4 dgitos
164
www.k19.com.br
165
S CHEDULING
Exerccios de Fixao
Para no confunfir, feche os projetos interceptadoresWeb. Para isso, clique com o boto direito
do mouse sobre esse projeto e selecione a opo Close Project.
1
2 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.facebook.com/k19treinamentos
165
S CHEDULING
166
166
www.k19.com.br
167
S CHEDULING
www.facebook.com/k19treinamentos
167
S CHEDULING
168
168
www.k19.com.br
169
S CHEDULING
Adicione uma pasta chamada META-INF na pasta src do projeto schedulingWeb. Na pasta
META-INF, crie o arquivo persistence.xml.
3
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " create " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML 9.1: persistence.xml
4
Crie um pacote chamado br.com.k19.entidades no projeto schedulingWeb e adicione nesse
pacote um Entity Bean para modelar produtos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1
2
3
4
5
6
7
8
9
10
11
12
www.facebook.com/k19treinamentos
169
S CHEDULING
170
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
170
www.k19.com.br
171
S CHEDULING
Crie uma tela para cadastrar produtos. Adicione na pasta WebContent do projeto schedulingWeb um arquivo chamado produtos.xhtml com o seguinte contedo.
7
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 >
Cdigo XHTML 9.1: produtos.xhtml
8
Remova o projeto interceptadoresWeb do Wildfly. Adicione o projeto schedulingWeb no Glassfish. Certifique-se que o JBoss e o Wildfly estejam parados. Inicie o Glassfish e teste a aplicao
acessando a url http://localhost:8080/schedulingWeb/produtos.xhtml.
Periodicamente um produto cadastrado deve ser escolhido e colocado em destaque. Implemente essa lgica atravs dos recursos de scheduling. Adicione a seguinte classe no pacote br.com.k19.sessionbeans do projeto schedulingWeb.
9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
www.facebook.com/k19treinamentos
171
S CHEDULING
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35 }
172
@EJB
private ProdutoRepositorio repositorio ;
private Produto produtoDestaque ;
@Schedule ( second = " */5 " , minute = " * " , hour = " * " , persistent = false )
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 ) {
this . produtoDestaque = produtoDestaque ;
}
public Produto getProdutoDestaque () {
return produtoDestaque ;
}
10
1
2
3
4
...
@EJB
private ProdutoDestaqueBean produtoDestaqueBean ;
...
Cdigo Java 9.15: ProdutoMB.java
11
1
2
3
4
5
...
public Produto getProdutoDestaque () {
return this . produtoDestaqueBean . getProdutoDestaque () ;
}
...
Cdigo Java 9.16: ProdutoMB.java
12
1
2
3
4
5
6
7
8
...
< h1 > Produto Destaque </ h1 >
<h : outputLabel value = " Nome : " / >
<h : outputText value = " #{ produtoMB . produtoDestaque . nome } " / >
<h : outputLabel value = " Preo : " / >
<h : outputText value = " #{ produtoMB . produtoDestaque . preco } " / >
...
Cdigo XHTML 9.2: produtos.xhtml
13
172
www.k19.com.br
173
S CHEDULING
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " none " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML 9.2: persistence.xml
www.facebook.com/k19treinamentos
173
S CHEDULING
174
174
www.k19.com.br
CAPTULO
10
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 definidos pela especificao
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
especificao 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 e Web Services)
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 definio bsica do conceito de Managed Beans est documentada na especificao Java EE
6 Managed Beans. Contudo essa especificao permite que outras especificaes 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 especificao CDI estende a definio de Managed Beans Na arquitetura CDI, os Managed Beans so definidos por classes que devem respeitar certas restries. Na seo 3.1.1 da especificao
CDI so definidas essas restries.
www.facebook.com/k19treinamentos
175
176
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.
Atributos tambm podem ser utilizados como fonte de objetos para o container Java EE. Os Producer Fields devem ser anotados com @Produces.
1 @Produces
2 public List < Produto > produtos ;
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
176
www.k19.com.br
177
Session Beans
Objetos criados por Producer Methods
Objetos disponibilizados por Producer Fields
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 @Named // Managed Bean - EL Name : geradorDeApostas
2 public class GeradorDeApostas {
3
// implementacao
4 }
Cdigo Java 10.3: GeradorDeApostas.java
1
2
3
4
5
@Named
@Stateless // Session Bean - EL Name : geradorDeApostas
public class GeradorDeApostas {
// implementacao
}
Cdigo Java 10.4: GeradorDeApostas.java
1
2
3
4
5
6
7
8
9
10
11
@Named
@Produces // Producer Method - EL Name : listaProdutos
public List < Produto > listaProdutos () {
// implementacao
}
@Named
@Produces // Producer Method - EL Name : produtos
public List < Produto > getProdutos () {
// implementacao
}
1 @Named
2 @Produces // Producer Field - EL Name : produtos
3 public List < Produto > produtos ;
beans.xml
Para modifcar as configuraes do CDI, necessrio adicionar um arquivo chamado beans.xml
na pasta META-INF no classpath.
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
www.facebook.com/k19treinamentos
177
178
2 < beans xmlns = " http: // java . sun . com / xml / ns / javaee "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = "
5
http: // java . sun . com / xml / ns / javaee
6
http: // java . sun . com / xml / ns / javaee / beans_1_0 . xsd " >
7 </ beans >
Exerccios de Fixao
Para no confundir, feche o projeto schedulingWeb. Para isso, clique com o boto direito do
mouse sobre esse projeto e selecione a opo Close Project.
1
2
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 imagens abaixo.
178
www.k19.com.br
179
www.facebook.com/k19treinamentos
179
180
180
www.k19.com.br
181
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
www.facebook.com/k19treinamentos
181
182
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.
4
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 >
Cdigo XHTML 10.1: moeda.xhtml
Remova o projeto schedulingWeb do Glassfish. Adicione o projeto cdiWeb no Glassfish. Certifiquese que o JBoss e o Wildfly estejam parado. Inicie o Glassfish e teste a aplicao acessando a url
http://localhost:8080/cdiWeb/moeda.xhtml.
5
6
Crie um pacote chamado br.com.k19.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
13
14
15
16
17
18
19
20
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.
1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
182
www.k19.com.br
183
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
< 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 >
Cdigo XHTML 10.2: numeros.xhtml
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < beans xmlns = " http: // java . sun . com / xml / ns / javaee "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = "
5
http: // java . sun . com / xml / ns / javaee
6
http: // java . sun . com / xml / ns / javaee / beans_1_0 . xsd " >
7 </ beans >
Cdigo XML 10.2: beans.xml
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 especfico. A especificao CDI define 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 final 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.
www.facebook.com/k19treinamentos
183
184
Todo objeto administrado pelo container CDI possui um escopo. O escopo de um objeto define
em qual contexto ele ser armazenado quando criado pelo container CDI. A especificao CDI define
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 definir o escopo dos objetos. Por padro, se nenhuma anotao for definida o escopo dos objetos o Dependent.
1 @RequestScoped
2 public class GeradorDeApostas {
3
// implementacao
4 }
Cdigo Java 10.10: GeradorDeApostas.java
1
2
3
4
5
@Produces
@SessionScoped
public List < Produto > listaProdutos () {
// implementacao
}
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 definidas atravs de Injection Points. H trs tipos de Injection Points:
184
www.k19.com.br
185
Bean Constructors
As dependncias de um objeto podem ser definidas atravs de construtores com a anotao @Inject.
1 public class CarrinhoDeCompras {
2
3
@Inject
4
public CarrinhoDeCompras ( Usuario usuario ) {
5
6
}
7 }
Cdigo Java 10.12: CarrinhoDeCompras.java
Field
As dependncias de um objeto podem ser definidas atravs de atributos com a anotao @Inject.
1 public class CarrinhoDeCompras {
2
3
@Inject
4
private Usuario usuario ;
5 }
Cdigo Java 10.13: CarrinhoDeCompras.java
Initializer methods
As dependncias de um objeto podem ser definidas atravs de mtodos inicializadores com a
anotao @Inject.
1 public class CarrinhoDeCompras {
2
3
private Usuario usuario ;
4
5
@Inject
6
public void setUsuario ( Usuario usuario ) {
7
this . usuario = usuario ;
8
}
9 }
Cdigo Java 10.14: CarrinhoDeCompras.java
Exerccios de Fixao
Altere o mtodo getNumeros() da classe GeradorDeNumeros do projeto cdiWeb para que ele
adicione uma mensagem no console toda vez que for chamado.
10
1
2
3
4
5
6
7
8
...
@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 () ) ;
www.facebook.com/k19treinamentos
185
186
9
}
10
return numeros ;
11 }
12 . . .
Cdigo Java 10.15: GeradorDeNumeros.java
12 Para evitar que o mtodo getNumeros seja chamado mais do que uma vez por requisio HTTP,
utilize o Resquet Scope. No esquea de importar a anotao import javax.enterprise.context.RequestScoped;.
1
2
3
4
5
6
7
8
9
10
11
12
13
...
@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 ;
}
...
Cdigo Java 10.16: GeradorDeNumeros.java
186
www.k19.com.br
APNDICE
P ROJETO
Neste captulo, implementaremos um pequeno projeto para praticar os conceitos discutidos nos
captulos anteriores. Criaremos um sistema simples de cadastro de bugs.
Exerccios de Fixao
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.
1
www.facebook.com/k19treinamentos
187
P ROJETO
188
188
www.k19.com.br
189
P ROJETO
www.facebook.com/k19treinamentos
189
P ROJETO
190
Adicione uma pasta chamada META-INF na pasta src do projeto bugWeb. Na pasta META-INF,
crie o arquivo persistence.xml.
2
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
5
http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd "
6
version = " 2.1 " >
7
8
< persistence - unit name = " K19 " transaction - type = " JTA " >
9
<jta - data - source > jdbc / K19 </ jta - data - source >
10
11
< properties >
12
< property
13
name = " javax . persistence . schema - generation . database . action "
14
value = " create " / >
15
</ properties >
16
</ persistence - unit >
17 </ persistence >
Cdigo XML A.1: persistence.xml
1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < beans xmlns = " http: // java . sun . com / xml / ns / javaee "
3
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
4
xsi:schemaLocation = "
190
www.k19.com.br
191
P ROJETO
5
http: // java . sun . com / xml / ns / javaee
6
http: // java . sun . com / xml / ns / javaee / beans_1_0 . xsd " >
7 </ beans >
Cdigo XML A.2: beans.xml
Configure a aplicao bugWeb para que ele utilize o Realm K19-Realm criado no captulo 7,
adicionando no arquivo web.xml do projeto bugWeb as configuraes necessrias.
4
1
2
3
4
5
...
< login - config >
< realm - name >K19 - Realm </ realm - name >
</ login - config >
...
Cdigo XML A.3: web.xml
1
2
3
4
5
6
7
8
9
10
11
...
< 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 >
...
Cdigo XML A.4: glassfish-web.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
www.facebook.com/k19treinamentos
191
P ROJETO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
192
@Entity
public class Bug {
@Id @GeneratedValue
private Long id ;
private String description ;
private String severity ;
@ManyToOne
private Project project ;
// GETTERS AND SETTERS
}
Cdigo Java A.2: Bug.java
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
192
@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 ) ;
www.k19.com.br
193
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 }
P ROJETO
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 ) ;
}
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
43
44
45
46
www.facebook.com/k19treinamentos
193
P ROJETO
194
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
43
44
45
46
47
48
49
50
51
52
194
195
P ROJETO
@Named
@RequestScoped
public class BugMB {
@Inject
private BugRepository bugRepository ;
@Inject
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 . bugs = 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 ;
www.facebook.com/k19treinamentos
195
P ROJETO
196
69
}
70 }
Cdigo Java A.6: BugMB.java
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
@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 {
FacesContext context = FacesContext . getCurrentInstance () ;
HttpServletRequest request = ( HttpServletRequest ) context
. getExternalContext () . getRequest () ;
request . logout () ;
return " / login " ;
}
// GETTERS AND SETTERS
}
Cdigo Java A.7: AuthenticatorMB.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
196
www.k19.com.br
197
17
18
19
20
21
22
P ROJETO
@Override
public void doFilter ( ServletRequest request , ServletResponse response ,
FilterChain chain ) throws IOException , ServletException {
HttpServletRequest req = ( HttpServletRequest ) request ;
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 }
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 () {
}
Crie um menu para as telas da aplicao bugWeb. Adicione um arquivo chamado menu.xhtml
na pasta WebContent do projeto bugWeb.
12
1 < ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
2
xmlns : ui = " http :// java . sun . com / jsf / facelets "
3
xmlns : h = " http :// java . sun . com / jsf / html "
4
xmlns : f = " http :// java . sun . com / jsf / core " >
5
6
<h : form >
7
<h : panelGrid >
8
<h : commandLink action = " #{ authenticatorMB . logout } " > logout </ h : commandLink >
9
10
<h : outputLink value = " #{ request . contextPath }/ projects . xhtml " > Projects </ h : outputLink >
11
12
<h : outputLink value = " #{ request . contextPath }/ bugs . xhtml " > Bugs </ h : outputLink >
13
</ h : panelGrid >
14
</ h : form >
15 </ ui : composition >
Cdigo XHTML A.1: menu.xhtml
13 Crie um tela de login na aplicao bugWeb. Adicione um arquivo chamado login.xhtml na pasta
WebContent do projeto bugWeb.
1
2
3
4
5
6
7
8
9
10
11
12
<! 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 >
www.facebook.com/k19treinamentos
197
P ROJETO
198
Crie uma tela para administrar os projetos. Adicione um arquivo chamado projects.xhtml na
pasta WebContent do projeto bugWeb.
14
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
43
44
45
46
<! 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 " / >
198
< 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 "
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 >
www.k19.com.br
199
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
P ROJETO
Crie uma tela para administrar os bugs. Adicione um arquivo chamado bugs.xhtml na pasta
WebContent do projeto bugWeb.
15
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
<! 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 >
www.facebook.com/k19treinamentos
199
P ROJETO
200
39
40
<h : commandButton action = " #{ bugMB . save } " value = " Save " / >
41
</ h : panelGrid >
42
</ h : form >
43
44
< hr / >
45
46
< h1 > Bug List </ h1 >
47
<h : dataTable value = " #{ bugMB . bugs } " var = " bug "
48
rendered = " #{ not empty bugMB . bugs } " border = " 1 " >
49
<h : column >
50
<f : facet name = " header " > Id </ f : facet >
51
#{ bug . id }
52
</ h : column >
53
54
<h : column >
55
<f : facet name = " header " > Project </ f : facet >
56
#{ bug . project . name }
57
</ h : column >
58
59
<h : column >
60
<f : facet name = " header " > Severity </ f : facet >
61
#{ bug . severity }
62
</ h : column >
63
64
<h : column >
65
<f : facet name = " header " > Description </ f : facet >
66
#{ bug . description }
67
</ h : column >
68
69
<h : column >
70
<f : facet name = " header " > Delete </ f : facet >
71
<h : form >
72
<h : commandLink action = " #{ bugMB . delete ( bug . id ) } " > delete </ h : commandLink >
73
</ h: form >
74
</ h : column >
75
<h : column >
76
<f : facet name = " header " > Edit </ f : facet >
77
<h : form >
78
<h : commandLink action = " #{ bugMB . prepareEdit ( bug . id ) } " > edit </ h : commandLink >
79
</ h: form >
80
</ h : column >
81
</ h : dataTable >
82 </ h : body >
83 </ html >
Cdigo XHTML A.4: bugs.xhtml
Crie uma tela para os erros internos e os erros de autorizao. Adicione um arquivo chamado
error.xhtml na pasta WebContent do projeto bugWeb.
16
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 > Error </ title >
</ h : head >
<h : body >
< h3 > Internal Error or Client not authorized for this invocation . </ h3 >
</ h : body >
</ html >
200
www.k19.com.br
201
P ROJETO
Configure a pgina de erro no arquivo web.xml do projeto bugWeb. Adicione o seguinte trecho
de cdigo nesse arquivo.
17
18
Teste a aplicao!!!
www.facebook.com/k19treinamentos
201