Desenvolvimento Web
com JSF2 e JPA2
31 de janeiro de 2012
Sumrio
Sobre a K19
Seguro Treinamento
Termo de Uso
Cursos
Banco de dados
1.1 Sistemas Gerenciadores de Banco de Dados . .
1.2 MySQL Server . . . . . . . . . . . . . . . . . . .
1.3 Bases de dados (Databases) . . . . . . . . . . .
1.4 Criando uma base de dados no MySQL Server
1.5 Tabelas . . . . . . . . . . . . . . . . . . . . . . .
1.6 Criando tabelas no MySQL Server . . . . . . . .
1.7 Operaes Bsicas . . . . . . . . . . . . . . . . .
1.8 Chaves Primria e Estrangeira . . . . . . . . . .
1.9 Exerccios de Fixao . . . . . . . . . . . . . . .
1.10 Exerccios Complementares . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
1
1
2
2
2
3
3
4
5
5
9
JDBC
2.1 Driver . . . . . . . . . . . . . . . . . . . . . .
2.2 JDBC . . . . . . . . . . . . . . . . . . . . . . .
2.3 Instalando o Driver JDBC do MySQL Server
2.4 Criando uma conexo . . . . . . . . . . . . .
2.5 Inserindo registros . . . . . . . . . . . . . . .
2.6 Exerccios de Fixao . . . . . . . . . . . . .
2.7 Exerccios Complementares . . . . . . . . .
2.8 SQL Injection . . . . . . . . . . . . . . . . . .
2.9 Exerccios de Fixao . . . . . . . . . . . . .
2.10 Exerccios Complementares . . . . . . . . .
2.11 Listando registros . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
25
26
27
28
28
29
29
31
31
32
33
33
www.k19.com.br
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
S UMRIO
2.12
2.13
2.14
2.15
2.16
2.17
3
ii
ii
Exerccios de Fixao . . . .
Exerccios Complementares
Connection Factory . . . . .
Exerccios de Fixao . . . .
Exerccios Complementares
Desafios . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
34
35
35
36
37
38
JPA 2 e Hibernate
3.1 Mltiplas sintaxes da linguagem SQL . . . .
3.2 Orientao a Objetos VS Modelo Relacional
3.3 Ferramentas ORM . . . . . . . . . . . . . . .
3.4 O que JPA e Hibernate? . . . . . . . . . . .
3.5 Bibliotecas . . . . . . . . . . . . . . . . . . .
3.6 Configurao . . . . . . . . . . . . . . . . . .
3.7 Mapeamento . . . . . . . . . . . . . . . . . .
3.8 Gerando Tabelas . . . . . . . . . . . . . . . .
3.9 Exerccios de Fixao . . . . . . . . . . . . .
3.10 Manipulando entidades . . . . . . . . . . .
3.11 Exerccios de Fixao . . . . . . . . . . . . .
3.12 Repository . . . . . . . . . . . . . . . . . . .
3.13 Exerccios de Fixao . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
39
39
39
40
41
41
42
42
44
44
46
48
49
50
Web Container
4.1 Necessidades de uma aplicao web
4.2 Web Container . . . . . . . . . . . . .
4.3 Servlet e Java EE . . . . . . . . . . . .
4.4 Exerccios de Fixao . . . . . . . . .
4.5 Aplicao Web Java . . . . . . . . . .
4.6 Exerccios de Fixao . . . . . . . . .
4.7 Processando requisies . . . . . . .
4.8 Servlet . . . . . . . . . . . . . . . . . .
4.9 Exerccios de Fixao . . . . . . . . .
4.10 Frameworks . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
53
53
55
55
55
56
57
57
57
58
58
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
61
61
61
62
66
69
71
.
.
.
.
.
.
.
77
77
78
78
81
81
88
90
.
.
.
.
.
.
Componentes Visuais
6.1 Estrutura Bsica de uma Pgina JSF
6.2 Formulrios . . . . . . . . . . . . . .
6.3 Caixas de Texto . . . . . . . . . . . . .
6.4 Campos Ocultos . . . . . . . . . . . .
6.5 Caixas de Seleo . . . . . . . . . . .
6.6 Botes e Links . . . . . . . . . . . . .
6.7 Exerccios de Fixao . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
www.k19.com.br
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
iii
S UMRIO
6.8
6.9
6.10
6.11
6.12
6.13
6.14
6.15
6.16
6.17
6.18
6.19
7
Exerccios Complementares . .
Textos e Imagens . . . . . . . . .
Exerccios de Fixao . . . . . .
Componentes de Organizao .
Tabelas . . . . . . . . . . . . . .
Exerccios de Fixao . . . . . .
Exerccios Complementares . .
Mensagens . . . . . . . . . . . .
Adicionando JavaScript e CSS .
Outros Componentes . . . . . .
Exerccios de Fixao . . . . . .
Exerccios Complementares . .
Templates e Modularizao
7.1 Templates . . . . . . . . . . .
7.2 Exerccios de Fixao . . . .
7.3 Modularizao . . . . . . . .
7.4 Exerccios de Fixao . . . .
7.5 Exerccios Complementares
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
93
93
95
96
97
100
102
102
102
103
104
105
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
107
107
110
111
113
114
Navegao
8.1 Navegao Implcita . . . . . . . .
8.2 Navegao Explcita . . . . . . . .
8.3 Exerccios de Fixao . . . . . . .
8.4 Navegaes Esttica e Dinmica
8.5 Exerccios de Fixao . . . . . . .
8.6 Exerccios Complementares . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
117
117
119
120
123
125
127
Escopos
9.1 Request . . . . . . . .
9.2 View . . . . . . . . . .
9.3 Session . . . . . . . .
9.4 Application . . . . . .
9.5 Exerccios de Fixao
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
129
129
130
131
133
133
.
.
.
.
.
.
.
.
.
.
.
.
.
.
139
139
139
141
143
143
146
146
147
148
150
150
153
154
156
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
10 Converso e Validao
10.1 Converso . . . . . . . . . . . . .
10.2 Conversores Padro . . . . . . . .
10.3 Exerccios de Fixao . . . . . . .
10.4 Exerccios Complementares . . .
10.5 Mensagens de Erro . . . . . . . .
10.6 Exerccios de Fixao . . . . . . .
10.7 Validao . . . . . . . . . . . . . .
10.8 Validadores Padro . . . . . . . .
10.9 Exerccios de Fixao . . . . . . .
10.10 Exerccios Complementares . . .
10.11 Bean Validation . . . . . . . . . .
10.12 Exerccios de Fixao . . . . . . .
10.13 Criando o seu Prprio Conversor
10.14 Exerccios de Fixao . . . . . . .
www.k19.com.br
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
iii
S UMRIO
iv
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
158
158
161
162
163
164
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
167
167
170
172
173
173
175
177
177
.
.
.
.
.
.
181
181
182
183
183
183
184
.
.
.
.
.
.
.
.
.
187
187
187
188
188
189
190
190
194
196
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
A Autenticao
199
A.1 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
B Pginas de Erro
205
B.1 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
C Projeto Futebol K19
C.1 Integrao JSF e JPA .
C.2 Exerccios de Fixao
C.3 Modelo . . . . . . . .
C.4 Exerccios de Fixao
C.5 Managed Beans . . .
C.6 Exerccios de Fixao
C.7 Telas . . . . . . . . . .
iv
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
www.k19.com.br
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
207
207
207
209
209
211
211
213
S UMRIO
C.8
C.9
D Respostas
www.k19.com.br
223
S UMRIO
vi
vi
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 que relacionados s
principais tecnologias utilizadas pelas empresas. Atravs desses treinamentos, seus alunos se tornam
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.k19.com.br
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.k19.com.br
S UMRIO
S
TO
EN
AM
EIN
TREINAMENTOS
TR
EIN
AM
EN
TO
S
TR
www.k19.com.br/cursos
www.k19.com.br
CAPTULO
B ANCO DE DADOS
Em geral, as aplicaes necessitam armazenar dados de forma persistente para consult-los posteriormente. Por exemplo, a aplicao de uma livraria precisa armazenar os dados dos livros e dos
autores de forma persistente.
Suponha que esses dados sejam armazenados em arquivos do sistema operacional. Vrios fatores importantes nos levam a descartar tal opo. A seguir, apresentamos as principais dificuldades a
serem consideradas na persistncia de dados.
Considerando todos esses aspectos, conclumos que um sistema complexo seria necessrio para
persistir as informaes de uma aplicao de maneira adequada. Felizmente, tal tipo de sistema j
existe e conhecido como Sistema Gerenciador de Banco de Dados (SGBD).
B ANCO DE DADOS
SQL Server
MySQL Server
PostgreSQL
MySQL Server
Neste treinamento, utilizaremos o MySQL Server, que mantido pela Oracle e amplamente utilizado em aplicaes comerciais. Para instalar o MySQL Server, voc pode utilizar o artigo disponvel
em nosso site: http://www.k19.com.br/artigos/instalando-mysql/
Podemos utilizar o comando SHOW DATABASES para listar as bases de dados existentes.
mysql > show databases ;
+ - - - - - - - - - - - - - - - - - - - -+
| Database
|
+ - - - - - - - - - - - - - - - - - - - -+
| information_schema |
| livraria
|
| mysql
|
| test
|
+ - - - - - - - - - - - - - - - - - - - -+
4 rows in set (0.03 sec )
www.k19.com.br
B ANCO DE DADOS
Repare que, alm da base de dados livraria, h outras trs bases. Essas bases foram criadas automaticamente pelo prprio MySQL Server para teste ou para armazenar configuraes.
Quando uma base de dados no mais necessria, ela pode ser removida atravs do comando
DROP DATABASE.
mysql > DROP DATABASE livraria ;
Query OK , 0 rows affected (0.08 sec )
Tabelas
Um servidor de banco de dados dividido em bases de dados com o intuito de separar as informaes de domnios diferentes. Nessa mesma linha de raciocnio, podemos dividir os dados de uma
base a fim de agrup-los segundo as suas correlaes. Essa separao feita atravs de tabelas. Por
exemplo, no sistema de um banco, interessante separar o saldo e o limite de uma conta, do nome e
CPF de um cliente. Ento, poderamos criar uma tabela para os dados relacionados s contas e outra
para os dados relacionados aos clientes.
nome
Jos
Maria
Cliente
idade cpf
27
31875638735
32
30045667856
numero
1
2
Conta
saldo
1000
2000
limite
500
700
Tabela 1.1: Tabelas para armazenar os dados relacionados aos clientes e s contas
Uma tabela formada por registros (linhas) e os registros so formados por campos (colunas).
Por exemplo, considere uma tabela para armazenar as informaes dos clientes de um banco. Cada
registro dessa tabela armazena em seus campos os dados de um determinado cliente.
As tabelas de uma base de dados podem ser listadas atravs do comando SHOW TABLES. Antes
de utilizar esse comando, devemos selecionar uma base de dados atravs do comando USE.
mysql > USE livraria ;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
www.k19.com.br
B ANCO DE DADOS
Se uma tabela no for mais desejada, ela pode ser removida atravs do comando DROP TABLE.
mysql > DROP TABLE Livro ;
Query OK , 0 rows affected (0.00 sec )
Operaes Bsicas
As operaes bsicas para manipular os dados persistidos so: inserir, ler, alterar e remover.
Essas operaes so realizadas atravs de uma linguagem de consulta denominada SQL (Structured Query Language). Essa linguagem oferece quatro comandos bsicos: INSERT, SELECT, UPDATE
e DELETE. Esses comandos so utilizados para inserir, ler, alterar e remover registros, respectivamente.
mysql > INSERT INTO Livro ( titulo , preco ) VALUES ( Java , 98.75);
Query OK , 1 row affected (0.00 sec )
mysql > UPDATE Livro SET preco = 115.9 WHERE titulo = Java ;
Query OK , 1 row affected (0.00 sec )
Rows matched : 1 Changed : 1 Warnings : 0
www.k19.com.br
B ANCO DE DADOS
mysql > SELECT * FROM Livro ;
Empty set (0.00 sec )
Exerccios de Fixao
www.k19.com.br
B ANCO DE DADOS
Estando dentro da sua pasta, acesse o MySQL Server utilizando o usurio root e a senha root.
k19@k19 -11:~/ rafael$ mysql -u root -p
Enter password :
Caso exista uma base de dados chamada livraria, remova-a. Utilize o comando SHOW DATABASES para listar as bases de dados existentes e o comando DROP DATABASE para remover a base
livraria se ela existir.
3
4
Crie uma nova base de dados chamada livraria. Utilize o comando CREATE DATABASE. Voc
vai utilizar esta base nos exerccios seguintes.
mysql > CREATE DATABASE livraria ;
Query OK , 1 row affected (0.00 sec )
Abra um editor de texto e digite o cdigo abaixo para criar uma tabela com o nome Editora.
Depois salve o arquivo com o nome create-table-editora.sql dentro da pasta com o seu nome.
5
1
2
3
4
5
6
7
8
USE livraria ;
CREATE TABLE Editora (
id BIGINT NOT NULL AUTO_INCREMENT ,
nome VARCHAR (255) NOT NULL ,
email VARCHAR (255) NOT NULL ,
PRIMARY KEY ( id )
)
ENGINE = InnoDB ;
Cdigo SQL 1.1: Criando a tabela Editora
Dentro do terminal, use o comando source para executar o arquivo que voc acabou de criar.
mysql > source create - table - editora . sql
Database changed
www.k19.com.br
B ANCO DE DADOS
Query OK , 0 rows affected (0.08 sec )
Abra um novo editor de texto e digite o cdigo abaixo para criar uma tabela com o nome Livro.
Em seguida, salve o arquivo com o nome create-table-livro.sql dentro da pasta com o seu nome.
7
1
2
3
4
5
6
7
8
9
10
11
12
13
USE livraria ;
CREATE TABLE Livro (
id BIGINT NOT NULL AUTO_INCREMENT ,
titulo VARCHAR (255) NOT NULL ,
preco DOUBLE NOT NULL ,
editora_id BIGINT NOT NULL ,
PRIMARY KEY ( id ) ,
CONSTRAINT fk_editora FOREIGN KEY fk_editora ( editora_id )
REFERENCES Editora ( id )
ON DELETE RESTRICT
ON UPDATE RESTRICT
)
ENGINE = InnoDB ;
Cdigo SQL 1.2: Criando a tabela Livro
Dentro do terminal, use o comando source para executar o cdigo do arquivo create-table-livro.sql.
mysql > source create - table - livro . sql
Database changed
Query OK , 0 rows affected (0.08 sec )
Abra um novo editor de texto e digite o cdigo abaixo para adicionar alguns registros na tabela
Editora. Depois salve o arquivo com o nome adicionando-registros-editora.sql dentro da pasta
com o seu nome.
9
1
2
3
4
5
10 Dentro do terminal, execute o arquivo que voc acabou de criar para adicionar alguns registro
na tabela Editora.
mysql > source adicionando - registros - editora . sql
Query OK , 1 row affected (0.03 sec )
Query OK , 1 row affected (0.04 sec )
Query OK , 1 row affected (0.04 sec )
Abra um novo editor de texto e digite o cdigo abaixo para adicionar alguns registros na tabela
Livro. Depois salve o arquivo com o nome adicionando-registros-livro.sql dentro da pasta
com o seu nome.
11
1
2
www.k19.com.br
B ANCO DE DADOS
3
4
5
6
Dentro do terminal, execute o arquivo que voc acabou de criar para adicionar alguns registros
na Livro.
12
13
14
15
16
www.k19.com.br
B ANCO DE DADOS
17
Remova alguns registros da tabela Editora. Preste ateno para no remover uma editora que
tenha algum livro relacionado j adicionado no banco. Utilize o comando DELETE.
mysql > DELETE FROM Editora WHERE id =2;
Query OK , 1 row affected (0.05 sec )
18
Faa uma consulta para buscar todos os livros de uma determinada editora.
mysql > SELECT * FROM Livro as L , Editora as E WHERE L . editora_id = E . id and E . id = 1;
+ - - - -+ - - - - - - - - - - - - - - -+ - - - - - - -+ - - - - - - - - - - - -+ - - - -+ - - - - - - - - -+ - - - - - - - - - - - - - - - - - - -+
| id | titulo
| preco | editora_id | id | nome
| email
|
+ - - - -+ - - - - - - - - - - - - - - -+ - - - - - - -+ - - - - - - - - - - - -+ - - - -+ - - - - - - - - -+ - - - - - - - - - - - - - - - - - - -+
| 1 | Aprendendo C # | 92.9 |
1 | 1 | OReilly | oreilly@email . com |
+ - - - -+ - - - - - - - - - - - - - - -+ - - - - - - -+ - - - - - - - - - - - -+ - - - -+ - - - - - - - - -+ - - - - - - - - - - - - - - - - - - -+
1 row in set (0.00 sec )
Exerccios Complementares
Utilize o MySQL Query Browser para refazer os exerccios anteriores.
1
Abra o MySQL Query Browser utilizando localhost como Server Hostname, root como Username e root como Password.
Caso exista uma base de dados chamada livraria, remova-a conforme a figura abaixo.
www.k19.com.br
B ANCO DE DADOS
10
Crie uma nova base de dados chamada livraria, conforme mostrado na figura abaixo. Voc vai
utilizar esta base nos exerccios seguintes.
3
10
www.k19.com.br
11
B ANCO DE DADOS
11
B ANCO DE DADOS
12
12
www.k19.com.br
13
B ANCO DE DADOS
Crie os campos conforme a figura e no esquea de tornar todos os campos obrigatrios, marcando a opo NOT NULL. Alm disso, o campo id deve ser uma chave primria e automaticamente
incrementada.
www.k19.com.br
13
B ANCO DE DADOS
14
Aps clicar no boto Apply Changes, aparecer uma janela mostrando os comandos SQL gerados. Clique no boto Execute.
Crie uma tabela chamada Livro conforme as figuras abaixo. Altere o modo de criao da tabela
para InnoDB, conforme mostrado na figura.
6
14
www.k19.com.br
15
B ANCO DE DADOS
Novamente, adicione os campos conforme a figura abaixo, lembrando de marcar a opo NOT
NULL. Alm disso, o campo id deve ser uma chave primria e automaticamente incrementada.
www.k19.com.br
15
B ANCO DE DADOS
16
Voc precisa tornar o campo editora_id uma chave estrangeira. Selecione a aba Foreign Keys e
clique no boto com o smbolo + para adicionar uma chave estrangeira. Depois, siga os procedimentos conforme mostrados na figura abaixo.
16
www.k19.com.br
17
B ANCO DE DADOS
17
B ANCO DE DADOS
18
18
19
B ANCO DE DADOS
Consulte os registros da tabela Editora e, em seguida, consulte a tabela Livro. Veja exemplos logo
abaixo.
9
www.k19.com.br
19
B ANCO DE DADOS
20
20
www.k19.com.br
21
B ANCO DE DADOS
10
11
21
B ANCO DE DADOS
12
22
22
www.k19.com.br
23
B ANCO DE DADOS
Remova alguns registros da tabela Editora. Preste ateno para no remover uma editora que
tenha algum livro relacionado j adicionado no banco. Veja o exemplo abaixo:
13
Faa uma consulta para buscar todos os livros associados as suas respectivas editoras. Veja um
exemplo na figura abaixo.
14
www.k19.com.br
23
B ANCO DE DADOS
24
24
www.k19.com.br
CAPTULO
JDBC
No captulo anterior, aprendemos que utilizar bancos de dados uma tima alternativa para
armazenar os dados de uma aplicao. Entretanto, voc deve ter percebido que as interfaces disponveis para interagir com o MySQL Server no podem ser utilizadas por qualquer pessoa. Para
utiliz-las, necessrio conhecer a linguagem SQL e os conceitos do modelo relacional. Em geral, as
interfaces dos outros SGDBs exigem os mesmos conhecimentos.
Figura 2.1: Usurios comuns no possuem conhecimento sobre SQL ou sobre o modelo relacional
Para resolver esse problema, podemos desenvolver aplicaes com interfaces que no exijam conhecimentos tcnicos de SQL ou do modelo relacional para serem utilizadas. Dessa forma, usurios
comuns poderiam manipular as informaes do banco de dados atravs dessas aplicaes. Nessa
abordagem, os usurios interagem com as aplicaes e as aplicaes interagem com os SGDBs.
www.k19.com.br
Cadastro de Funcionrios
Nome:
Cdigo:
Salrio:
www.k19.com.br
25
JDBC
26
Driver
As aplicaes interagem com os SGDBs atravs de troca de mensagens. Os SGDBs definem o
formato das mensagens. Para no sobrecarregar o canal de comunicao entre as aplicaes e os
SGDBs, as mensagens trocadas devem ocupar o menor espao possvel. Geralmente, protocolos
binrios so mais apropriados para reduzir o tamanho das mensagens e consequentemente diminuir
a carga do canal de comunicao. Por isso, os SGDBs utilizam protocolos binrios.
find
rollback
getReference
persist
begin
getTransaction
commit
10110
111000
10010
Figura 2.3: Diminuindo o tamanho das mensagens para no sobrecarregar o meio de comunicao
Mensagens binrias so facilmente interpretadas por computadores. Por outro lado, so complexas para um ser humano compreender. Dessa forma, o trabalho dos desenvolvedores seria muito
complexo, aumentando o custo para o desenvolvimento e manuteno das aplicaes.
11
01 01
01 00 01
11 1 1 0
1
1
10 010 11 110 01
0 01 0 1
0
1
1
10 111 10 110 11
0 01 01 00
01 101 11
1 010
0
1011010111
0010110001
1010111101
0111011100
0101101001
1101011101
0010110011
1011010111
0010110001
1010111101
0111011100
0101101001
1101011101
0010110011
26
www.k19.com.br
27
JDBC
Para resolver esse problema e facilitar o desenvolvimento das aplicaes, as empresas proprietrias dos SGDBs, normalmente, desenvolvem e distribuem drivers de conexo. Um driver de conexo
atua como um intermedirio entre as aplicaes e os SGDBs.
Os drivers de conexo so tradutores de comandos escritos em uma determinada linguagem
de programao para comandos definidos de acordo com o protocolo de um SGDB. Utilizando um
driver de conexo, os desenvolvedores das aplicaes no manipulam diretamente as mensagens
binrias trocadas entre as aplicaes e os SGDBs.
Mais Sobre
Em alguns casos, o protocolo binrio de um determinado SGDB fechado. Consequentemente, a nica maneira de se comunicar com ele atravs de um driver de conexo
oferecido pelo fabricante desse SGDB.
JDBC
Suponha que os drivers de conexo fossem desenvolvidos sem nenhum padro. Cada driver teria
sua prpria interface, ou seja, seu prprio conjunto de instrues. Consequentemente, os desenvolvedores teriam de conhecer a interface de cada um dos drivers dos respectivos SGDBs que fossem
utilizar.
01110010101110011
Driver MySQL
createConnection()
00010011101110010
Driver Oracle
openConnection()
Para facilitar o trabalho do desenvolvedor da aplicao, a plataforma Java possui uma especificao que padroniza os drivers de conexo. A sigla dessa especificao JDBC (Java Database Connectivity). Em geral, as empresas proprietrias dos SGBDs desenvolvem e distribuem drivers de conexo
que seguem a especificao JDBC.
www.k19.com.br
27
28
getConnection()
Driver MySQL
JDBC
JDBC
00010011101110010
Driver Oracle
JDBC
getConnection()
01110010101110011
http://www.mysql.com/downloads/connector/j/.
A instalao desse driver consiste em descompactar o arquivo obtido no site acima e depois incluir o arquivo jar com o driver no class path da aplicao.
28
www.k19.com.br
29
JDBC
A classe responsvel pela criao de uma conexo JDBC a DriverManager do pacote java.sql.
A string de conexo, o usurio e a senha devem ser passados ao mtodo esttico getConnection()
da classe DriverManager para que ela possa criar uma conexo JDBC.
1
2
3
4
5
6
7
8
Inserindo registros
Aps estabelecer uma conexo JDBC, podemos executar operaes. A primeira operao que
realizaremos a insero de registros em uma tabela. O primeiro passo para executar essa operao
definir o cdigo SQL correspondente.
1
String sql = " INSERT INTO Editora ( nome , email ) VALUES ( K19 , contato@k19 . com . br ) ; " ;
Cdigo Java 2.3: Cdigo SQL correspondente operao de insero
O cdigo SQL correspondente operao que desejamos executar deve ser passado como parmetro para o mtodo prepareStatement() de uma conexo JDBC. Esse mtodo criar um objeto
que representa a operao que ser executada. A operao poder ser executada posteriormente
atravs do mtodo execute().
1
2
3
4
5
6
Importante
A mesma conexo pode ser reaproveitada para executar vrias operaes. Quando no
houver mais operaes a serem executadas, devemos finalizar a conexo JDBC atravs
do mtodo close(). Finalizar as conexes JDBC que no so mais necessrias importante
pois libera recursos no SGBD.
1
conexao . close () ;
Cdigo Java 2.5: Finalizando uma conexo JDBC
Exerccios de Fixao
www.k19.com.br
29
JDBC
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
30
import
import
import
import
www.k19.com.br
31
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
JDBC
String nome = entrada . nextLine () ;
System . out . println ( " Digite o email da editora : " ) ;
String email = entrada . nextLine () ;
String sql = " INSERT INTO Editora ( nome , email ) " +
" VALUES ( " + nome + " , " + email + " ) " ;
PreparedStatement comando = conexao . prepareStatement ( sql ) ;
System . out . println ( " Executando comando ... " ) ;
comando . execute () ;
System . out . println ( " Fechando conexo ... " ) ;
conexao . close () ;
} catch ( Exception e ) {
e . printStackTrace () ;
}
}
}
Cdigo Java 2.6: InsereEditora.java
Exerccios Complementares
1
Crie uma classe chamada InsereLivros para cadastrar livros na base de dados.
SQL Injection
A implementao da insero de registros feita anteriormente possui uma falha grave. Os dados
obtidos do usurio atravs do teclado no so tratados antes de serem enviados para o SGDB.
Esses dados podem conter caracteres especiais. Se esses caracteres no so tratados, o comportamento esperado da operao afetado. Eventualmente, registros no so inseridos como deveriam
ou brechas de segurana podem se abrir.
Por exemplo, considere a classe InsereEditora do exerccio de fixao. Se o usurio digitar
OReilly e oreilly@email.com, o cdigo SQL gerado pela aplicao seria:
1
Observe que o caractere aspas simples aparece cinco vezes no cdigo SQL acima. O SGDB no
saberia dizer onde de fato termina o nome da editora. Ao tentar executar esse cdigo, um erro de
sintaxe lanado pelo MySQL Server. Para resolver esse problema manualmente, devemos adicionar
o caractere \ antes do caractere aspas simples que faz parte do nome da editora. Na sintaxe do
MySQL Server, o caractere \ deve ser acrescentado imediatamente antes de todo caractere especial
que deve ser tratado como um caractere comum.
1
Os valores recebidos dos usurios devem ser analisados e os caracteres especiais contidos nesses
www.k19.com.br
31
JDBC
32
valores devem ser tratados. Esse processo extremamente trabalhoso, pois o conjunto de caracteres
especiais e a forma de trat-los diferente em cada SGDB.
A responsabilidade do tratamento dos caracteres especiais contidos nos valores de entrada dos
usurios pode ser repassada para os drivers JDBC. Dessa forma, o cdigo das aplicaes se torna
independente das particularidades desse processo para cada SGDB.
Mais Sobre
O processo de tratamento dos caracteres especiais das entradas dos usurios denominado sanitize.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Observe que o cdigo SQL foi definido com parmetros atravs do caractere ?. Antes de executar o comando, necessrio determinar os valores dos parmetros. Essa tarefa pode ser realizada
atravs do mtodo setString(), que recebe o ndice (posio) do parmetro no cdigo SQL e o valor correspondente. Esse mtodo faz o tratamento dos caracteres especiais contidos nos valores de
entrada do usurio de acordo com as regras do SGDB utilizado.
Exerccios de Fixao
Provoque um erro de SQL Injection na classe InsereEditoras. (Dica: tente entradas com aspas
simples.)
6
1
2
3
4
5
6
7
8
9
10
11
32
www.k19.com.br
33
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
JDBC
Exerccios Complementares
Provoque um erro de SQL Injection na classe InsereLivros. (Dica: tente entradas com aspas
simples.)
2
Agora tente causar novamente o problema de SQL Injection ao inserir novos livros.
Listando registros
O processo para executar um comando de consulta bem parecido com o processo de inserir
registros. O primeiro passo definir a consulta em SQL.
1
2
3
4
5
6
A diferena que para executar um comando de consulta necessrio utilizar o mtodo executeQuery() ao invs do execute(). Esse mtodo devolve um objeto da interface java.sql.Resultwww.k19.com.br
33
JDBC
34
O cdigo acima mostra como os campos do primeiro registro da consulta so recuperados. Para
recuperar os dados dos outros registros necessrio avanar o ResultSet atravs do mtodo next().
1
2
3
4
5
6
7
8
9
O prprio mtodo next() devolve um valor booleano para indicar se o ResultSet conseguiu
avanar para o prximo registro. Quando esse mtodo devolver false significa que no h mais
registros para serem consultados.
1
2
3
4
5
Exerccios de Fixao
8
Insira algumas editoras utilizando a classe InsereEditora que voc criou anteriormente.
9
Adicione uma nova classe ao projeto chamada ListaEditoras. O objetivo listar as editoras
que foram salvas no banco.
1
2
3
4
5
6
7
8
9
10
11
12
34
import
import
import
import
www.k19.com.br
35
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
Exerccios Complementares
5
Connection Factory
Voc deve ter percebido que em diversos pontos diferentes da nossa aplicao precisamos de
uma conexo JDBC. Se a url de conexo for definida em cada um desses pontos, teremos um problema de manuteno. Imagine que o driver do banco seja atualizado ou que o IP do SGBD seja
alterado. Teramos que alterar o cdigo da nossa aplicao em muitos lugares. Mais precisamente,
cada ocorrncia da url de conexo precisaria ser modificada. A probabilidade de algum ponto no
ser corrigido grande.
Para diminuir o trabalho de manuteno, podemos implementar uma classe responsvel pela
criao e distribuio de conexes. A url de conexo deve ser definida nessa classe e somente nela.
Consequentemente, alteraes nas informaes contidas na url de conexo afetariam apenas uma
classe da aplicao.
1
2
3
4
5
6
7
8
9
www.k19.com.br
35
JDBC
10
11
12
13
14
15
16
17
18
19
20
36
Agora, podemos obter uma nova conexo apenas chamando o mtodo createConnection(). O
resto do sistema no precisa mais conhecer os detalhes sobre a criao das conexes com o banco
de dados, diminuindo o acoplamento da aplicao.
Exerccios de Fixao
10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Altere as classes InsereEditora e ListaEditoras para que elas utilizem a fbrica de conexo.
Depois, execute-as novamente.
11
1
2
3
4
5
6
7
8
9
10
11
12
13
14
36
www.k19.com.br
37
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
Exerccios Complementares
Altere as classes InsereLivro e ListaLivros para que elas utilizem a fbrica de conexo. Depois, execute-as novamente.
6
www.k19.com.br
37
JDBC
38
Desafios
1
38
www.k19.com.br
CAPTULO
JPA 2 E H IBERNATE
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY autor ASC) AS rownumber,
id, titulo, autor
FROM livros
) WHERE rownumber <= 100
Driver Oracle
JDBC
Driver MySQL
JDBC
39
JPA 2 E H IBERNATE
40
tbl_editoras
Livro
id = 1
titulo = Os Lusadas
autor = Lus Vaz de
Cames
editora = 1
Editora
id
nome
Cultura
FTDA
Globo
Scipione
id = 1
nome = Livraria Cultura
tbl_livros
Livro
id = 2
titulo = Vidas Secas
autor = Graciliano
Ramos
editora = 1
ORIENTAO A OBJETOS
id
titulo
autor
Os Lusadas
editora_id
1
Vidas Secas
Graciliano Ramos
Dom Casmurro
Machado de Assis
O Cortio
Alusio Azevedo
MODELO RELACIONAL
Ferramentas ORM
Para facilitar a comunicao entre aplicaes Java que seguem o modelo orientado a objetos e os
SGDBs que seguem o modelo relacional, podemos utilizar ferramentas que automatizam a transio
de dados entre as aplicaes e os SGDBs. Essas ferramentas so conhecidas como ferramentas ORM
(Object Relational Mapper).
As ferramentas ORM oferecem mecanismos de consultas independentes da linguagem SQL. Dessa
forma, o acoplamento entre as aplicaes e os SGDBs diminui drasticamente. A principal ferramenta
ORM para Java utilizada no mercado o Hibernate. Mas, existem outras que possuem o mesmo objetivo.
40
www.k19.com.br
41
JPA 2 E H IBERNATE
tbl_livros
id
titulo
autor
Os Lusadas
editora_id
1
Vidas Secas
Graciliano Ramos
Dom Casmurro
Machado de Assis
O Cortio
Alusio Azevedo
Livro
FERRAMENTA
id = 1
= Os Lusadas
ORM titulo
autor = Lus Vaz de
Cames
editora = 1
Livro
id = 2
titulo = Vidas Secas
autor = Graciliano
Ramos
editora = 1
Figura 3.3: Transformao dos dados do Modelo Relacional para o Modelo Orientado a Objetos
tbl_livros
Livro
id = 1
titulo = Os Lusadas
autor = Lus Vaz de
Cames
editora = 1
Livro
id = 2
titulo = Vidas Secas
autor = Graciliano
Ramos
editora = 1
id
titulo
FERRAMENTA
1
Os Lusadas
2
Vidas Secas
ORM
autor
editora_id
Graciliano Ramos
Dom Casmurro
Machado de Assis
O Cortio
Alusio Azevedo
Figura 3.4: Transformao dos dados do Modelo Orientado a Objetos para o Modelo Relacional
Bibliotecas
Antes de comear a utilizar o Hibernate, necessrio baixar do site oficial o bundle que inclui os
www.k19.com.br
41
JPA 2 E H IBERNATE
42
jars do hibernate e todas as suas dependncias. Neste curso, utilizaremos a verso 3.5.1. A url do site
oficial do Hibernate http://www.hibernate.org/.
Configurao
Para configurar o Hibernate em uma aplicao, devemos criar um arquivo chamado persistence.xml. O contedo desse arquivo possuir informaes sobre o banco de dados, como a url de
conexo, usurio e senha, alm de dados sobre a implementao de JPA que ser utilizada.
O arquivo persistence.xml deve estar em uma pasta chamada META-INF, que deve estar no
classpath da aplicao. Veja abaixo um exemplo de configurao para o persistence.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<? xml version = " 1.0 " encoding = " UTF -8 " ? >
< persistence version = " 2.0 "
xmlns = " http: // java . sun . com / xml / ns / persistence "
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
xsi:schemaLocation = " http: // java . sun . com / xml / ns / persistence http: // java . sun . com / xml / ns / persistence / persistence_2_0 . xsd " >
< persistence - unit name = " K19 - PU " transaction - type = " RESOURCE_LOCAL " >
< provider > org . hibernate . ejb . HibernatePersistence </ provider >
< properties >
< property name = " hibernate . dialect " value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
< property name = " hibernate . hbm2ddl . auto " value = " create " / >
< property name = " javax . persistence . jdbc . driver " value = " com . mysql . jdbc . Driver " / >
< property name = " javax . persistence . jdbc . user " value = " usuario " / >
< property name = " javax . persistence . jdbc . password " value = " senha " / >
< property name = " javax . persistence . jdbc . url " value = " jdbc:mysql: // localhost:3306 / K19 - DB " / >
</ properties >
</ persistence - unit >
</ persistence >
Cdigo XML 3.1: persistence.xml
A propriedade hibernate.dialect permite que a aplicao escolha qual sintaxe de SQL deve ser
utilizada pelo Hibernate.
Mais Sobre
Consulte o artigo da K19 sobre configurao do Hibernate e MySQL na seguinte url:
http://www.k19.com.br/artigos/configurando-hibernate-com-mysql/.
Mapeamento
Um dos principais objetivos das ferramentas ORM estabelecer o mapeamento entre os conceitos do modelo orientado a objetos e os conceitos do modelo relacional. Esse mapeamento pode ser
definido atravs de XML ou de maneira mais prtica com anotaes Java.
42
www.k19.com.br
43
JPA 2 E H IBERNATE
A seguir, veremos as principais anotaes Java de mapeamento do JPA. Essas anotaes esto no
pacote javax.persistence.
@Entity a principal anotao do JPA. Ela 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
nomes dos atributos. Novamente, podemos alterar esse padro utilizando 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 atributo gerado pelo banco, no momento em que um novo registro inserido.
@Table Utilizada para alterar o nome padro da tabela. Ela recebe o parmetro name para indicar
qual nome deve ser utilizado na tabela. Veja o exemplo:
1
2
3
4
5
@Column Utilizado para alterar o nome da coluna que ser usado na tabela. Caso voc esteja utilizando um banco de dados legado, no qual os nomes das colunas j foram definidos, voc
pode mudar atravs dessa anotao. Alm disso, podemos estabelecer certas restries, como
determinar se o campo pode ou no ser nulo.
1
2
3
4
5
6
@Entity
public class Editora {
@Column ( name = " publisher_name " , nullable = false )
private String nome ;
}
Cdigo Java 3.2: Editora.java
@Transient Serve para indicar que um atributo no deve ser persistido, ou seja, os atributos anotados com @Transient no so mapeados para colunas.
@Lob Utilizado para atributos que armazenam textos muito grandes, ou arquivos binrios contendo
imagens ou sons que sero persistidos no banco de dados. O tipo do atributo deve ser String,
Byte[], byte[] ou java.sql.Blob.
@Temporal Utilizado para atributos do tipo Calendar ou Date. Por padro, tanto data quanto hora
so armazenados no banco de dados. Mas, com a anotao @Temporal, podemos mandar
persistir somente a data ou somente a hora.
www.k19.com.br
43
JPA 2 E H IBERNATE
1
2
3
4
5
6
7
44
@Entity
public class Livro {
@Temporal ( TemporalType . DATE )
private Calendar publicacao ;
// ...
}
Cdigo Java 3.3: Livro.java
Gerando Tabelas
Uma das vantagens de se utilizar o Hibernate que ele capaz de gerar as tabelas do banco para
a nossa aplicao. Ele faz isso de acordo com as anotaes colocadas nas classes e as informaes
presentes no persistence.xml.
As tabelas so geradas atravs de um mtodo da classe Persistence, o createEntityManagerFactory(String entityUnit). O parmetro entityUnit permite escolher, pelo nome, uma unidade de persistncia definida no persistence.xml.
A poltica de criao das tabelas pode ser alterada modificando o valor a propriedade hibernate.hbm2ddl.auto no arquivo persistence.xml. Podemos, por exemplo, fazer com que o Hibernate
sempre sobrescreva as tabelas existentes, bastando definir a propriedade hibernate.hbm2ddl.auto
com o valor create-drop.
1
< property name = " hibernate . hbm2ddl . auto " value = " create - drop " / >
Uma outra opo configurar o Hibernate para simplesmente atualizar as tabelas de acordo
com as mudanas nas anotaes sem remov-las. Nesse caso, o valor da propriedade hibernate.hbm2ddl.auto deve ser update.
1
< property name = " hibernate . hbm2ddl . auto " value = " update " / >
Exerccios de Fixao
Crie um projeto no Eclipse chamado JPA2-Hibernate e feche o projeto JDBC para no gerar
confuso na hora de manipular os arquivos.
1
4
Entre na pasta K19-Arquivos/MySQL-Connector-JDBC da rea de Trabalho e copie o arquivo
mysql-connector-java-5.1.13-bin.jar para pasta lib do projeto JPA2-Hibernate.
5
44
Entre na pasta K19-Arquivos/SLF4J da rea de Trabalho e copie os jars para pasta lib do
www.k19.com.br
45
JPA 2 E H IBERNATE
projeto JPA2-Hibernate.
6
Entre na pasta K19-Arquivos/Log4J da rea de Trabalho e copie o arquivo log4j-1.2.16.jar
para pasta lib do projeto JPA2-Hibernate.
Adicione os jars da pasta lib ao build path do projeto JPA2-Hibernate. Voc deve selecionar
os arquivos e adicion-los no build path.
7
1
2
3
4
5
<? xml version = " 1.0 " encoding = " UTF -8 " ? >
< persistence version = " 2.0 "
xmlns = " http: // java . sun . com / xml / ns / persistence "
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
xsi:schemaLocation = " http: // java . sun . com / xml / ns / persistence http: // java . sun . com / xml / ns / persistence / persistence_2_0 . xsd " >
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
< persistence - unit name = " livraria - pu " transaction - type = " RESOURCE_LOCAL " >
< provider > org . hibernate . ejb . HibernatePersistence </ provider >
< properties >
< property name = " hibernate . dialect " value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
< property name = " hibernate . hbm2ddl . auto " value = " create " / >
< property name = " javax . persistence . jdbc . driver " value = " com . mysql . jdbc . Driver " / >
< property name = " javax . persistence . jdbc . user " value = " root " / >
< property name = " javax . persistence . jdbc . password " value = " root " / >
< property name = " javax . persistence . jdbc . url " value = " jdbc:mysql: // localhost:3306 / livraria " / >
</ properties >
</ persistence - unit >
</ persistence >
Cdigo XML 3.4: persistence.xml
Crie uma classe para modelar as editoras da nossa livraria e acrescente as anotaes necessrias
para fazer o mapeamento. Obs: As anotaes devem ser importadas do pacote javax.persistence.
10
1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Editora {
@Id @GeneratedValue
private Long id ;
private String nome ;
private String email ;
// GETTERS AND SETTERS
}
Cdigo Java 3.4: Editora.java
11
www.k19.com.br
45
JPA 2 E H IBERNATE
1
2
3
4
46
Gere as tabelas atravs da classe Persistence. Para isso, crie uma classe com mtodo main. Obs:
As classes devem ser importadas do pacote javax.persistence.
13
1
2
3
4
5
6
7
8
Atravs do MySQL Query Browser, verifique se a tabela Editora foi criada corretamente.
Manipulando entidades
Para manipular as entidades da nossa aplicao, devemos utilizar um EntityManager que obtido atravs de uma EntityManagerFactory.
1
2
3
4
EntityManagerFactory factory =
Persistence . createEntityManagerFactory ( " K19 " ) ;
EntityManager manager = factory . createEntityManager () ;
Cdigo Java 3.6: Obtendo um EntityManager
Persistindo
Para armazenar as informaes de um objeto no banco de dados, o primeiro passo utilizar o
mtodo persist() do EntityManager.
1
2
3
4
5
importante destacar que o mtodo persist() apenas marca os objetos que devem ser armazenados no banco de dados. Os objetos sero armazenados aps a chamada do mtodo commit(),
como veremos adiante.
46
www.k19.com.br
47
JPA 2 E H IBERNATE
Buscando
Para obter um objeto que contenha informaes do banco de dados, podemos utilizar o mtodo
find() ou o mtodo getReference() do EntityManager.
1
2
H uma diferena entre os dois mtodos bsicos de busca find() e getReference(). O mtodo
find() recupera os dados desejados imediatamente. J o mtodo getReference() posterga essa
tarefa at a primeira chamada de um mtodo get do objeto.
Removendo
Para remover o registro correspondente a um objeto, devemos utilizar o mtodo remove() do
EntityManager.
1
2
Atualizando
Para alterar os dados do registro correspondente a um objeto, basta utilizar os prprios mtodos
setters desse objeto.
1
2
Listando
Para obter uma listagem com todos os objetos referentes aos registros de uma tabela, podemos
utilizar a linguagem de consulta do JPA, a JPQL, que muito parecida com a linguagem SQL. A principal vantagem do JPQL em relao ao SQL que a sintaxe do JPQL no depende do SGDB utilizado.
1
2
www.k19.com.br
47
JPA 2 E H IBERNATE
48
Transaes
As modificaes realizadas nos objetos administrados por um EntityManager so mantidas em
memria. Em certos momentos, necessrio sincronizar os dados da memria com os dados do
banco de dados. Essa sincronizao deve ser realizada atravs de uma transao JPA criada pelo
EntityManager que administra os objetos que desejamos sincronizar.
Para abrir uma transao, utilizamos o mtodo begin().
1
Com uma transao aberta, podemos sincronizar os dados da memria com os dados do banco
atravs do mtodo commit().
1
2
3
4
5
Exerccios de Fixao
No arquivo de configuraes persistence.xml, altere o valor da propriedade hibernate.hbm2ddl.auto para update. Assim, as tabelas no sero recriadas a cada execuo e sim apenas atualizadas.
14
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
48
www.k19.com.br
49
JPA 2 E H IBERNATE
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Repository
A interface EntityManager do JPA oferece recursos suficientes para que os objetos do domnio
sejam recuperados ou persistidos no banco de dados. Porm, em aplicaes com alta complexidade
e grande quantidade de cdigo, espalhar as chamadas aos mtodos do EntityManager pode gerar
dificuldades na manuteno e no entendimento do sistema.
Para melhorar a organizao das nossas aplicaes, diminuindo o custo de manuteno e aumentando a legibilidade do cdigo, podemos aplicar o padro Repository do DDD (Domain Driven
Design).
Conceitualmente, um repositrio representa o conjunto de todos os objetos de um determinado
tipo. Ele deve oferecer mtodos para recuperar e para adicionar elementos.
Os repositrios podem trabalhar com objetos prontos na memria ou reconstru-los com dados
obtidos de um banco de dados. O acesso ao banco de dados pode ser realizado atravs de ferramentas ORM como o Hibernate.
1
2
3
4
5
6
7
8
9
10
11
12
13
class EditoraRepository {
private EntityManager manager ;
public EditoraRepository ( EntityManager manager ) {
this . manager = manager ;
}
public void adiciona ( Editora e ) {
this . manager . persist ( e ) ;
}
public Editora busca ( Long id ) {
return this . manager . find ( Editora . class , id ) ;
}
www.k19.com.br
49
JPA 2 E H IBERNATE
14
15
16
17
18
50
1
2
3
4
5
6
7
EntityManagerFactory factory =
Exerccios de Fixao
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
18
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
50
www.k19.com.br
51
18
19
20
21
22
23
24
25
26
27
28
29
JPA 2 E H IBERNATE
System . out . println ( " Digite o email da editora : " ) ;
novaEditora . setEmail ( entrada . nextLine () ) ;
editoraRepository . adiciona ( novaEditora ) ;
manager . getTransaction () . begin () ;
manager . getTransaction () . commit () ;
manager . close () ;
factory . close () ;
}
}
Cdigo Java 3.19: InsereEditoraComJPA.java
19
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
www.k19.com.br
51
JPA 2 E H IBERNATE
52
52
www.k19.com.br
CAPTULO
W EB C ONTAINER
HTTP
Os usurios de uma aplicao web utilizam navegadores (browsers) para interagir com essa aplicao. A comunicao entre navegadores e uma aplicao web realizada atravs de requisies e
respostas definidas pelo protocolo HTTP. Dessa forma, os desenvolvedores de aplicao web devem
estar preparados para trabalhar com o protocolo HTTP.
Acesso simultneo
Alm disso, na grande maioria dos casos, as aplicaes web devem ser acessadas por diversos
usurios ao mesmo tempo. Consequentemente, os desenvolvedores web devem criar ou utilizar
algum mecanismo eficiente que permita esse tipo de acesso.
Contedo dinmico
As pginas de uma aplicao web devem ser geradas dinamicamente. Por exemplo, quando um
usurio de uma aplicao de email acessa a sua caixa de entrada, ele deseja ver todos os emails
enviados at aquele momento. A pgina contendo a lista de emails deve ser gerada novamente toda
vez que essa pgina for requisitada. Consequentemente, os desenvolvedores web devem criar ou
utilizar algum mecanismo eficiente que permita que o contedo das pginas das aplicaes web seja
gerado dinamicamente.
www.k19.com.br
53
W EB C ONTAINER
54
HT
isi
o
qu
Re
TP
HT
o
isi
qu
Re
TT
aH
st
o
sp
Re
TP
Requisio HTTP
HT
Resposta HTTP
st
a
sp
Re
TP
Aplicao
Web
www.k19.com.br
www.k19.com.br
Cursos
www.k19.com.br
Artigos
Apostilas
Soluo
Resolver os trs problemas apresentados tomaria boa parte do tempo de desenvolvimento, alm
de exigir conhecimentos tcnicos extremamente especficos por parte dos desenvolvedores. Para
facilitar o desenvolvimento de aplicaes web, a plataforma Java oferece uma soluo genrica que
pode ser utilizada para desenvolver aplicaes web. Conheceremos essa soluo a seguir.
Aplicao
Web
HT
ui
o
i
q
Re
TP
HT
o
isi
qu
Re
P
TT
Artigos
H
ta
Cursos
www.k19.com.br
os
www.k19.com.br
sp
Re
TP
Requisio HTTP
HT
Resposta HTTP
po
st
a
Re
TP
Web Container
www.k19.com.br
Apostilas
54
www.k19.com.br
55
W EB C ONTAINER
Web Container
Uma aplicao web Java deve ser implantada em um Web Container para obter os recursos fundamentais que ela necessita. Um Web Container responsvel:
Pelo envio e recebimento de mensagens HTTP.
Por permitir que as aplicaes sejam acessadas simultaneamente por vrios usurios de uma
maneira eficiente.
Por permitir que as pginas de uma aplicao web sejam geradas dinamicamente.
Os dois Web Containers mais importantes do mercado so Tomcat e Jetty. Tambm podemos
utilizar um servidor de aplicao Java EE como o JBoss, Glassfish ou WebSphere, pois eles possuem
um Web Container internamente.
Servlet e Java EE
Como comum na plataforma Java, foi definida uma especificao para padronizar a interface
dos recursos oferecidos pelos Web Containers. Essa especificao chamada Servlet e atualmente
est na verso 3. Para consult-la, acesse http://jcp.org/en/jsr/detail?id=315.
A especificao Servlet faz parte do Java EE. O Java EE uma especificao que agrupa diversas
outras especificaes. Para consult-la, acesse http://jcp.org/en/jsr/detail?id=316.
Apesar das especificaes, os Web Containers possuem algumas diferenas nas configuraes
que devem ser realizadas pelos desenvolvedores. Dessa forma, no h 100% de portabilidade. Contudo, a maior parte das configuraes e do modelo de programao padronizado. Sendo assim, se
voc conhece bem um dos Web Containers, tambm conhece bastante dos outros.
Neste treinamento, optamos pela utilizao do servidor de aplicao Glassfish 3.0. Esse servidor
segue a especificao Java EE 6 e portanto contm um Web Container. Mostraremos, a seguir, a sua
instalao e configurao.
Mais Sobre
Consulte os artigos da K19 sobre instalao e configurao do Glassfish para mais detalhes.
http://www.k19.com.br/artigos/instalando-glassfish/
http://www.k19.com.br/artigos/configurando-o-gassfish-no-ide-eclipse/
Exerccios de Fixao
1
55
W EB C ONTAINER
56
Finalize o Glassfish executando o script stopserv, que est na mesma pasta do script startserv.
5
No Eclipse, abra a view Servers e clique com o boto direito no corpo dela. Escolha a opo
new e configure o Glassfish.
Inicialize o Glassfish pela view Servers e verifique se ele est funcionando, acessando http:
//localhost:8080.
6
K19-App/
WEB-INF/
classes/
lib/
web.xml
A pasta K19-App a raiz da aplicao. Ela pode ter qualquer nome. A pasta WEB-INF deve ser
criada dentro da pasta raiz. O contedo da pasta WEB-INF no pode ser acessado diretamente pelos
usurios da aplicao. Por outro lado, os arquivos dentro da pasta raiz da aplicao mas fora da pasta
WEB-INF podem ser acessados diretamente atravs de um navegador.
As pastas classes e lib devem ser criadas dentro da pasta WEB-INF. O cdigo compilado da
aplicao deve ser salvo na pasta classes. Os jars das bibliotecas extras que sero utilizadas devem
ser colocados na pasta lib. O arquivo web.xml contm configuraes do Web Container e deve ser
criado na pasta WEB-INF.
Em geral, as IDEs criam toda a estrutura de pastas exigidas pelos Web Containers. Ento, na
prtica, no temos o trabalho de criar esses diretrios manualmente.
Mais Sobre
Consulte o artigo da K19 sobre criao de projetos web utilizando o Eclipse.
http://www.k19.com.br/artigos/criando-um-dynamic-web-project/
56
www.k19.com.br
57
W EB C ONTAINER
Exerccios de Fixao
No Eclipse, crie um projeto do tipo Dynamic Web Project chamado K19-App. Escolha Glassfish
como opo para Target runtime. Na ltima tela de criao do projeto, selecione a opo Generate
web.xml deployment descriptor.
8
Adicione o projeto K19-App no Glassfish atravs da view Servers. Clique com o boto direito
do mouse no Glassfish e selecione Add and Remove. . . .
9
Inicialize o Glassfish atravs da view Servers. Clique com o boto direito do mouse sobre o
Glassfish e escolha a opo Start.
10
Processando requisies
Aps implantar a nossa aplicao web Java em um Web Container, as requisies e respostas
HTTP j esto sendo processadas pelo Web Container, que tambm j permite o acesso de mltiplos
usurios nossa aplicao.
Em seguida, devemos definir como o contedo das pginas da aplicao gerado. Para isso,
podemos criar uma Servlet.
Servlet
Para criar uma Servlet, podemos seguir os seguintes passos:
1. Criar uma classe.
2. Herdar da classe javax.servlet.http.HttpServlet.
3. Reescrever o mtodo service().
4. Utilizar a anotao @WebServlet para definir a url que ser utilizada para acessar a Servlet.
Essa anotao existe aps a especificao Servlet 3.0. Antes, essa configurao era realizada
atravs do arquivo web.xml.
1
2
3
4
5
6
7
8
9
www.k19.com.br
57
W EB C ONTAINER
58
O mtodo service() executado toda vez que uma requisio HTTP realizada para a url definida na anotao @WebServlet. Esse mtodo recebe dois parmetros. O primeiro a referncia do
objeto da classe HttpServletRequest que armazena todos os dados da requisio. O segundo parmetro a referncia do objeto da classe HttpServletResponse que armazenar o contedo gerado
pela Servlet.
Exerccios de Fixao
12
13
1
2
3
4
5
6
7
8
9
10
14
http://localhost:8080/K19-App/OlaMundo
Frameworks
Hoje em dia, improvvel que uma empresa decida comear um projeto utilizando diretamente
Servlets, pois a produtividade seria pequena e a manuteno muito custosa. Vrios frameworks fo58
www.k19.com.br
59
W EB C ONTAINER
ram criados para facilitar o desenvolvimento e a manuteno de aplicaes web. Apesar de serem
baseados em Servlets, esses frameworks oferecem diversos recursos adicionais para as aplicaes.
Eis uma lista dos principais frameworks para aplicaes web Java:
JSF
Struts 1.x
Struts 2.x
Spring MVC
Aplicao
Web
Framework
HT
qu
isi
Re
TP
HT
o
isi
qu
Re
TP
Cursos
HT
www.k19.com.br
ta
os
sp
Re
TP
Requisio HTTP
HT
Resposta HTTP
os
ta
sp
Re
TP
Web Container
www.k19.com.br
Artigos
www.k19.com.br
Apostilas
Nos prximos captulos, mostraremos o funcionamento e explicaremos os conceitos relacionados ao framework JSF.
www.k19.com.br
59
W EB C ONTAINER
60
60
www.k19.com.br
CAPTULO
Atualmente, o principal framework para desenvolvimento de aplicaes web em Java o JSF (Java
Server Faces). A especificao desse framework pode ser obtida em http://www.jcp.org/en/jsr/
detail?id=314. Alm disso, recomendamos a consulta ao javadoc da API do JSF que pode ser obtido
no mesmo link. O JSF fortemente baseado nos padres MVC e Front Controller.
Para mais detalhes sobre o padro MVC, uma boa referncia o livro Pattern-Oriented Software
Architecture Volume 1: A System of Patterns (editora Wiley, 1996) dos autores Frank Buschmann, Regine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal e Michael Stal.
No padro Front Controller, todas as requisies do usurio so recebidas pelo mesmo componente. Dessa forma, tarefas que devem ser realizadas em todas as requisies podem ser implementadas por esse componente. Isso evita a repetio de cdigo e facilita a manuteno do sistema.
Para mais informaes sobre esse padro, consulte, por exemplo, o livro Core J2EE Patterns: Best
Practices and Design Strategies (editora Prentice Hall, 2003, segunda edio) dos autores Deepak Alur,
Dan Malks e John Crupi.
61
62
web.xml
A Faces Servlet deve ser configurada no arquivo WEB-INF/web.xml, indicando a classe que a implementa e o padro de url que ser associado a essa servlet.
Por exemplo, na configurao abaixo, todas as requisies cujas urls possuam o sufixo .xhtml
sero processadas pela Faces Servlet.
1
2
3
4
5
6
7
8
faces-config.xml
Devemos adicionar um arquivo chamado faces-config.xml no diretrio WEB-INF. Nesse arquivo, podemos alterar diversas configuraes do JSF. Mas, a princpio, podemos deix-lo apenas
com a tag faces-config.
1
2
3
4
5
6
<? xml version = " 1.0 " encoding = " utf -8 " ? >
< faces - config xmlns = " http: // java . sun . com / xml / ns / javaee "
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
xsi:schemaLocation = " http: // java . sun . com / xml / ns / javaee http: // java . sun . com / xml / ns / javaee / web - facesconfig_2_0 . xsd "
version = " 2.0 " >
</ faces - config >
Cdigo XML 5.2: faces-config.xml
Bibliotecas
Para utilizar os recursos do JSF, necessrio que a aplicao possua uma implementao JSF. Essa
implementao pode ser adicionada manualmente no diretrio WEB-INF/lib da aplicao.
Se um servidor de aplicao Java EE for utilizado, a incluso de uma implementao JSF manualmente no necessria, j que esse tipo de servidor possui, por padro, uma implementao de
JSF.
Managed Beans
Os managed beans so objetos fundamentais de uma aplicao JSF. Suas principais tarefas so:
1. Fornecer dados que sero exibidos nas telas.
2. Receber os dados enviados nas requisies.
62
www.k19.com.br
63
1
2
3
4
5
6
7
...
< managed - bean >
< managed - bean - name > testeBean </ managed - bean - name >
< managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
< managed - bean - scope > request </ managed - bean - scope >
</ managed - bean >
...
Cdigo XML 5.3: faces-config.xml
No registro de um managed bean, devemos definir o nome, a classe e o escopo do managed bean.
O nome que ser utilizado para acessar esse managed bean nas pginas da aplicao. O escopo ser
explicado em detalhes no Captulo 9.
A segunda forma criar uma classe Java com a anotao @ManagedBean do pacote javax.faces.bean.
Essa anotao s pode ser utilizada a partir da verso 2 do JSF. Observe o exemplo abaixo.
1
2
3
4
@ManagedBean
public class TesteBean {
...
}
Cdigo Java 5.2: TesteBean.java
Utilizando a anotao @ManagedBean, por padro, o JSF assumir que o nome do managed bean
o nome da classe com a primeira letra minscula. Para o exemplo acima, o nome padro do managed
bean testeBean. Alm disso, o escopo request ser assumido como padro.
Propriedades
Considere o seguinte managed bean.
1
2
3
4
@ManagedBean
public class TesteBean {
private int numero ;
}
Cdigo Java 5.3: TesteBean.java
www.k19.com.br
63
64
Para acessar o valor do atributo numero em uma tela JSF, precisamos definir um mtodo de leitura.
Esse mtodo deve seguir a conveno de nomenclatura do Java. Veja o exemplo abaixo:
1
2
3
4
5
6
7
8
@ManagedBean
public class TesteBean {
private int numero ;
public int getNumero () {
return numero ;
}
}
Cdigo Java 5.4: TesteBean.java
Note que o nome do mtodo comea com get e seguido pelo nome do atributo com a primeira
letra em caixa alta.
Para alterar o valor do atributo numero com valores obtidos atravs de uma tela JSF, precisamos
definir um mtodo de escrita.
1
2
3
4
5
6
7
8
9
10
11
12
@ManagedBean
public class TesteBean {
private int numero ;
public int setNumero ( int numero ) {
this . numero = numero ;
}
public int getNumero () {
return numero ;
}
}
Cdigo Java 5.5: TesteBean.java
O nome do mtodo de escrita deve necessariamente comear com a palavra set e terminar com
o nome do atributo com a primeira letra em caixa alta.
Com os mtodos de acesso j implementados, podemos exibir o valor do atributo numero utilizando expression language (#{}). Veja o exemplo a seguir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
Valor : #{ testeBean . numero }
</ h : body >
</ html >
Cdigo XHTML 5.1: Exibindo o valor do atributo numero
Para alterar o valor do atributo numero do managed bean testeBean, podemos vincul-lo, por
exemplo, a uma caixa de texto em um formulrio. Observe o cdigo abaixo.
64
www.k19.com.br
65
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Importante
importante destacar que o vnculo com uma propriedade de um managed bean d-se
por meio dos nomes dos mtodos getters e setters, e no pelo nome do atributo.
No exemplo acima, se mantivssemos o nome do atributo do managed bean mas substitussemos os nomes dos mtodos getNumero() e setNumero() por getValor() e setValor(),
respectivamente, ento os trechos de cdigo XHTML em destaque deveriam ser alterados para o
seguinte:
1
2
Aes
Para implementar as lgicas que devem ser executadas assim que o usurio clicar em um boto
ou link, basta criar mtodos nas classes dos managed beans.
Seguindo o exemplo acima, podemos criar um mtodo que incrementa o valor do atributo numero,
como no cdigo abaixo.
1
2
3
4
5
6
7
8
9
10
@ManagedBean
public class TesteBean {
private int numero ;
public void incrementaNumero () {
this . numero = numero + 1;
}
// GETTERS E SETTERS
}
Cdigo Java 5.6: TesteBean.java
www.k19.com.br
65
66
Esses mtodos podem ser void quando desejamos manter os usurios na mesma tela ou devolver
String quando desejamos realizar uma navegao entre telas. Veremos mais detalhes em captulos
posteriores.
Para incrementar o valor do atributo numero do managed bean testeBean, podemos criar uma
pgina que possui um boto para executar essa ao e associ-lo ao mtodo incrementaNumero(),
conforme o cdigo abaixo.
1
2
3
Mais Sobre
Todo managed bean possui um nome nico que utilizado para acess-lo dentro dos trechos escritos com expression language. Quando utilizamos a anotao
@ManagedBean, por padro, o JSF assume que o nome do managed bean o nome da classe
com a primeira letra em caixa baixa. Porm, podemos alterar esse nome acrescentado um argumento na anotao.
1
2
3
4
Restore View: Na primeira requisio de um usurio, uma nova rvore de componentes que representa a tela desse usurio gerada. Nas demais requisies (postback) desse mesmo usurio, a
rvore de componentes que representa a tela anteriormente enviada a ele reconstruda.
Apply Request Values: Nesta etapa, a rvore construda na etapa anterior percorrida e cada um dos
seus componentes decodificado. No processo de decodificao, cada componente extrai da
requisio atual os dados associados a essa componente e se atualiza com essas informaes.
Ainda nessa etapa, os eventos de ao (como um clique em um link ou em um boto, por
exemplo) so identificados. Por padro, esses eventos so adicionados s filas correspondentes
para serem tratados posteriormente (na fase Invoke Application).
Process Validations: Nesta fase, os componentes que possuem valores submetidos pelo usurio
atravs de formulrios so convertidos e validados (caso haja algum validador registrado para
esse componente).
66
www.k19.com.br
67
Se ocorrer algum erro de converso ou validao, mensagens de erro so adicionadas no contexto da requisio atual e o fluxo redirecionado para a fase Render Response. Caso contrrio,
processo continua na fase Update Model Values.
Update Model Values: Os valores contidos em cada componente da rvore, j convertidos e validados na fase anterior, so armazenados em propriedades de objetos definidos pela aplicao
(managed beans)
Invoke Application: Uma vez que os dados dos componentes j foram convertidos, validados e armazenados nos objetos do modelo, as tarefas correspondentes ao evento que disparou a requisio (normalmente um clique em um boto ou link) sero executadas.
Tambm nesta fase, a prxima tela a ser apresentada ao usurio determinada pelo resultado
do mtodo que implementa a lgica de negcio executado nesta fase.
Render Response: Nesta etapa, a prxima tela gerada e enviada ao navegador do usurio. Uma
representao desta tela tambm armazenada a fim de ser usada na fase Restore View da
prxima requisio.
O diagrama abaixo ilustra a estrutura geral de uma aplicao JSF. O processamento de uma requisio enviada por um navegador comea na Faces Servlet logo aps a sua chegada. A Faces Servlet
controla a execuo das seis etapas descritas acima.
www.k19.com.br
67
68
www.k19.com.br
L
HTMscript
a
Jav
CSS
Requisio HTTP
Resposta HTTP
Faces Servlet
Restore
View
Apply Request
Values
Process
Validation
Update
Model
Ivoke
Application
Render
Response
MANAGED BEANS
CONTROLE
MODELO
VISO
TELAS
ENTIDADES
TEMPLATES
REPOSITRIOS
TELAS PARCIAIS
68
www.k19.com.br
69
Os managed beans esto disposio da Faces Servlet durante todo o processamento da requisio. Por exemplo, nas etapas Render Response e Restore View, a Faces Servlet aciona os managed
beans para recuperar os dados que devem ser usados na construo ou reconstruo da rvore de
componentes. Na etapa Update Model, a Faces Servlet armazena nos managed beans os dados j
convertidos e validados. Na etapa Invoke Application, a Faces Servlet dispara um mtodo em um
managed bean responsvel pelo processamento da regra de negcio correspondente requisio
atual.
Todas as regras de negcio so implementadas no modelo, que tambm administra os dados da
aplicao. Os managed beans acionam o modelo para executar alguma regra de negcio, recuperar
ou alterar os dados administrados pelo modelo.
As telas da aplicao so definidas na camada de viso. A Faces Servlet acessa essa camada toda
vez que necessita construir ou reconstruir a rvore de componentes de uma determinada tela. Isso
ocorre nas etapas Restore View e Render Response.
Exemplo Prtico
Com as configuraes j realizadas, implementaremos uma aplicao que mostra o funcionamento bsico do JSF. Essa aplicao dever receber um texto do usurio e exibi-lo em letras maisculas.
Managed Bean
Vamos comear criando um managed bean para armazenar o texto enviado pelo usurio e a
lgica para transform-lo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
A classe que implementa o managed bean deve ser anotada com @ManagedBean. O atributo texto
armazenar o texto enviado pelo usurio e esse texto ser modificado pelo mtodo transformaEmCaixaAlta(). Esse mtodo devolve uma string para indicar qual deve ser a prxima tela a ser enviada
para o usurio.
www.k19.com.br
69
70
A Faces Servlet utilizar o mtodo setTexto() para armazenar o texto enviado pelo usurio no
managed bean. Por outro lado, utilizar o mtodo getTexto() para recuperar o texto e exibi-lo aps
a sua modificao.
Telas
Uma vez que o managed bean foi criado, podemos associ-lo a um formulrio que receber o
texto do usurio.
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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : outputLabel value = " Texto : " / >
<h : inputTextarea value = " #{ textoBean . texto } " / >
<h : commandButton value = " Transformar " action = " #{ textoBean . transformaEmCaixaAlta } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 5.5: formulario.xhtml
Observe nas linhas em destaque a ligao entre essa tela e o managed bean. A caixa de entrada
de texto foi associada propriedade texto do managed bean TextoBean. O boto, por sua vez, foi
associado ao mtodo transformaEmCaixaAlta() do managed bean TextoBean.
Para exibir o texto transformado, podemos criar uma outra tela.
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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : outputText value = " #{ textoBean . texto } " / >
</ h : body >
</ html >
Cdigo XHTML 5.6: resposta.xhtml
Analogamente, a caixa de sada de texto est associada propriedade texto do managed bean
TextoBean.
70
www.k19.com.br
71
Exerccios de Fixao
Como exerccio, desenvolva uma aplicao JSF que (i) receba um nmero inteiro do usurio, (ii)
produza um nmero aleatrio entre zero e o nmero recebido, e (iii) exiba esse nmero na tela do
navegador do usurio.
No Eclipse, crie um Dynamic Web Project chamado K19-Visao-Geral. Na primeira tela, devemos
definir o nome do projeto, selecionar o target runtime e a configurao.
1
71
72
www.k19.com.br
73
Na ltima tela, devemos desabilitar as configuraes de biblioteca e mapear a Faces Servlet para
as urls que seguem o padro *.xhtml.
www.k19.com.br
73
74
Na pasta src, crie um managed bean para armazenar o nmero inteiro n enviado pelo usurio,
gerar um nmero aleatrio entre zero e n e armazen-lo numa propriedade.
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
74
www.k19.com.br
75
Agora, na pasta WebContent, crie um formulrio para que o usurio possa enviar o dado de
entrada.
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : outputLabel value = " Nmero mximo : " / >
<h : inputText value = " #{ numeroAleatorioBean . maximo } " / >
<h : commandButton value = " Gera nmero aleatrio "
action = " #{ numeroAleatorioBean . geraNumeroAleatorio } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 5.7: formulario.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Tambm na pasta WebContent, defina uma tela para exibir o nmero gerado aleatoriamente.
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : outputText value = " #{ numeroAleatorioBean . numeroAleatorio } " / >
</ h : body >
</ html >
Cdigo XHTML 5.8: resposta.xhtml
1. Abra a aba Servers. Para isso, pressione Ctrl+3. Na janela que abrir, digite Servers e pressione Enter.
2. Na aba Servers, clique com o boto direito do mouse no GlassFish e selecione a opo Add
and Remove. . . .
3. Selecione o projeto K19-Visao-Geral e clique em Add >. Em seguida, clique em Finish.
www.k19.com.br
75
76
4. Inicialize o servidor. Para isso, clique mais uma vez no GlassFish com o boto direito e selecione Start.
5. Acesse a aplicao no endereo
http://localhost:8080/K19-Visao-Geral/formulario.xhtml.
76
www.k19.com.br
CAPTULO
C OMPONENTES V ISUAIS
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : outputText value = " Estrutura bsica de uma tela JSF " / >
</ h : body >
</ html >
Cdigo XHTML 6.1: Estrutura Bsica de uma Tela JSF
O contedo da pgina definido no corpo da tag <html>. Esse contedo dividido em duas
partes: o cabealho, delimitado pela tag <h:head> (e no pela tag <head>), e o corpo, delimitado pela
tag <h:body> (e no pela tag <body>).
As bibliotecas de tags que sero utilizadas para construir a pgina devem ser importadas atravs do pseudo-atributo xmlns aplicado tag <html>. Observe no exemplo acima que as trs principais bibliotecas do JSF foram importadas.
www.k19.com.br
77
C OMPONENTES V ISUAIS
78
Mais Sobre
Devemos utilizar a declarao <!DOCTYPE> para informar aos navegadores qual a verso do HTML utilizado na pgina. Com essa informao, os navegadores podem processar o documento corretamente.
Mais Sobre
Quando uma biblioteca de tags importada atravs do pseudo-atributo xmlns, possvel definir um prefixo para essa biblioteca. Esse prefixo utilizado, no documento,
para acessar as tags da biblioteca.
Importante
A utilizao das tags <h:head> e <h:body> fundamental para o funcionamento completo das pginas HTML geradas pelo JSF. Ao processar essas tags, na etapa Render
Response, o JSF adiciona recursos como scripts e arquivos de estilo na tela HTML que ser
enviada para o usurio. Esses recursos so necessrios para o funcionamento correto dos componentes.
Formulrios
Os formulrios no JSF so definidos atravs da tag <h:form> (e no pela tag <form>). Um formulrio composto basicamente por caixas de texto, caixas de seleo, rtulos, botes e links. Ao ser
processado, o componente <h:form> gera um formulrio HTML configurado para o mtodo POST
do HTTP.
Nas sees a seguir, descreveremos os elementos de um formulrio.
Caixas de Texto
O JSF define trs tipos de caixas de texto para coletar dados do usurio.
<h:inputText>
Permite que o usurio digite uma linha de texto.
<h:inputTextarea>
Permite que o usurio digite vrias linhas de texto.
<h:inputSecret>
Igual ao <h:inputText> mas no exibi o que foi digitado.
Uma caixa de texto pode ser associada a uma propriedade de um managed bean atravs do atributo value. Esse vnculo denominado binding. Considere o seguinte managed bean.
1
2
3
78
@ManagedBean
public class UsuarioBean {
private String nome ;
www.k19.com.br
79
4
5
6
7
8
9
10
11
12
C OMPONENTES V ISUAIS
Devemos utilizar expression language (#{}) para estabelecer uma associao entre a propriedade
nome a uma caixa de texto. Observe o cdigo abaixo.
1
Quando o JSF constri a tela a ser enviada para o usurio, ele recupera o valor da propriedade
nome atravs do mtodo getNome() e guarda esse valor na caixa de texto correspondente.
Analogamente, no processamento de uma requisio, o JSF extrai o valor presente na caixa de
texto e utiliza o mtodo setNome() para armazenar esse valor na propriedade nome do managed
bean UsuarioBean.
Rtulos
Rtulos so utilizados para indicar ao usurio o que ele deve preencher em determinada caixa de
texto. Para acrescentar um rtulo em uma pgina, devemos utilizar o componente <h:outputLabel>.
O texto do rtulo definido pelo atributo value e pode ser associado a uma caixa de texto atravs
do atributo for. O valor do atributo for deve ser igual ao valor do atributo id da caixa de texto que
desejamos associar ao rtulo.
1
2
<h : outputLabel value = " Nome : " for = " nome " / >
<h : inputText id = " nome " / >
Cdigo XHTML 6.3: Exemplo de uso do <h:outputLabel>
Exemplos
A seguir, alguns exemplos de utilizao das caixas de texto sero apresentados. Mostraremos o
cdigo XHTML das telas, o cdigo HTML produzido pelo JSF e as telas renderizadas por um navegador.
1. XHTML:
<h : outputLabel value = " Nome : " for = " nome " / >
<h : inputText value = " Jonas K . Hirata " id = " nome " / >
HTML gerado:
< label for = " j_idt6 : nome " > Nome : </ label >
< input id = " j_idt6 : nome " type = " text " name = " j_idt6 : nome " value = " Jonas K . Hirata " / >
www.k19.com.br
79
C OMPONENTES V ISUAIS
80
Resultado:
Nome: Jonas K. Hirata
2. XHTML:
<h : outputLabel value = " Nome : " for = " nome " / >
<h : inputText value = " #{ usuarioBean . nome } " id = " nome " / >
HTML gerado:
< label for = " j_idt6 : nome " > Nome : </ label >
< input id = " j_idt6 : nome " type = " text " name = " j_idt6 : nome " value = " Jonas Hirata " / >
Resultado:
Nome: Jonas Hirata
3. XHTML:
<h : outputLabel value = " Nome : " for = " nome " / >
<h : inputText value = " #{ usuarioBean . nome } " readonly = " true " id = " nome " / >
HTML gerado:
< label for = " j_idt6 : nome " > Nome : </ label >
< input id = " j_idt6 : nome " type = " text " name = " j_idt6 : nome " value = " Jonas Hirata " readonly = " readonly " / >
Resultado:
Nome: Jonas Hirata
4. XHTML:
<h : outputLabel value = " CEP : " for = " cep " / >
<h : inputText value = " #{ usuarioBean . cep } " maxlength = " 9 " id = " cep " / >
HTML gerado:
< label for = " j_idt6 : cep " > Cep : </ label >
< input id = " j_idt6 : cep " type = " text " name = " j_idt6 : cep " value = " 01452 -001 " maxlength = " 9 " / >
Resultado:
CEP: 01452-001
5. XHTML:
<h : outputLabel value = " Texto : " for = " texto " / >
<h : inputTextarea value = " Um texto de vrias linhas " id = " texto " / >
HTML gerado:
< label for = " j_idt6 : texto " > Texto : </ label >
< textarea id = " j_idt6 : texto " name = " j_idt6 : texto " > Um texto de vrias linhas </ textarea >
80
www.k19.com.br
81
C OMPONENTES V ISUAIS
Resultado:
Texto: Um texto de vrias
linhas
6. XHTML:
<h : outputLabel value = " Texto : " for = " texto " / >
<h : inputTextarea value = " Um texto de vrias linhas " cols = " 10 " rows = " 3 " id = " texto " / >
HTML gerado:
< label for = " j_idt6 : texto " > Texto : </ label >
< textarea id = " j_idt6 : texto " name = " j_idt6 : texto " cols = " 10 " rows = " 3 " >
Um texto de vrias linhas
</ textarea >
Resultado:
Texto: Um texto de
vrias linhas
7. XHTML:
<h : outputLabel value = " Senha : " for = " senha " / >
<h : inputSecret value = " #{ usuarioBean . senha } " id = " senha " / >
HTML gerado:
< label for = " j_idt6 : senha " > Senha : </ label >
< input id = " j_idt6 : senha " type = " password " name = " j_idt6 : senha " value = " " / >
Resultado:
Senha:
Campos Ocultos
Podemos adicionar informaes que so submetidas automaticamente quando um formulrio
enviado ao servidor. Essas informaes podem ser inseridas com o componente <h:inputHidden>.
Essa tag possui dois atributos principais: value e id. Podemos vincular um campo oculto a uma
propriedade de um managed bean, como no exemplo abaixo.
1
<h : inputHidden id = " curso - id " value = " #{ cursosBean . curso . id } " / >
Cdigo XHTML 6.11: Exemplo de um campo oculto vinculado a uma propriedade de um managed bean
Caixas de Seleo
www.k19.com.br
81
C OMPONENTES V ISUAIS
82
O atributo itemValue define o que ser enviado para a aplicao se a opo correspondente
for selecionada. O atributo itemLabel define a descrio associada opo correspondente. Essa
descrio exibida para o usurio.
Definir as opes estaticamente pode dificultar a adio ou remoo de opes. Por exemplo,
o cadastramento ou a remoo de um curso no sistema implicaria em uma mudana no arquivo
XHTML.
Seria interessante eliminar essa dependncia fazendo com que o arquivo XHTML recupere dinamicamente todos os cursos cadastrados. Isso pode ser realizado atravs da tag <f:selectItems>.
82
www.k19.com.br
83
1
2
3
4
5
6
7
C OMPONENTES V ISUAIS
<h : selectOneMenu value = " #{ cursosBean . siglaDoCursoEscolhido } " >
<f : selectItems
value = " #{ cursosBean . cursos } "
var = " curso "
itemValue = " #{ curso . sigla } "
itemLabel = " #{ curso . nome } " >
</ h : selectOneMenu >
Cdigo XHTML 6.14: Caixa de seleo com opes definidas dinamicamente
A atributo value da tag <f:selectItems> deve ser associado a uma coleo de itens. Todos os
itens sero percorridos e adicionados como opo na caixa de seleo. O atributo var utilizado
para definir a varivel que armazenar, a cada rodada, o item atual. Essa varivel permite que o
itemValue e o itemLabel de cada opo sejam definidos.
1
2
3
4
5
6
7
@ManagedBean
public class CursosBean {
private String siglaDoCursoEscolhido ;
private List < Curso > cursos ;
// GETTERS E SETTERS
}
Cdigo Java 6.2: CursosBean.java
1
2
3
4
5
6
A propriedade associada caixa de seleo deve ser compatvel com o tipo de dado utilizado no
atributo itemValue. No exemplo acima, as siglas dos cursos so do tipo String. Consequentemente,
a propriedade que armazenar a sigla do curso escolhido tambm deve ser to tipo String.
Agora, suponha que o usurio possa escolher mais do que um curso. Nesse caso, o managed bean
deve estar preparado para guardar uma lista de siglas de cursos ao invs de uma nica sigla. Para isso,
www.k19.com.br
83
C OMPONENTES V ISUAIS
84
devemos adicionar uma propriedade no managed bean CursosBean, como mostra o cdigo abaixo.
1
2
3
4
5
6
7
@ManagedBean
public class CursosBean {
private List < String > siglasDosCursosEscolhidos ;
private List < Curso > cursos ;
// GETTERS E SETTERS
}
Cdigo Java 6.4: CursosBean.java
Para permitir a seleo mltipla, devemos utilizar uma caixa de seleo do tipo <h:selectManyListbox> ou <h:selectManyMenu>. Essa caixa deve ento ser vinculada nova propriedade do managed bean CursoBean. Por exemplo, se optarmos pela <h:selectManyListbox>, poderamos ter o
seguinte cdigo.
1
2
3
4
5
6
7
Para adicionar uma pseudo-opo, basta utilizar a tag <f:selectItem> com o atributo noSelectionOption igual a true. Se essa pseudo-opo estiver selecionada no momento em que o
formulrio for submetido, a propriedade correspondente receber o valor null.
Muitas vezes, a pseudo-opo utilizada simplesmente para exibir uma mensagem ao usurio,
como Escolha uma opo ou Selecione um item.
Exemplos
A seguir, mostraremos exemplos de cada tipo de caixa de seleo.
84
www.k19.com.br
85
C OMPONENTES V ISUAIS
1. XHTML:
1
2
<h : outputLabel value = " Ex - aluno " for = " exaluno " / >
<h : selectBooleanCheckbox value = " #{ cursosBean . exAluno } " id = " exaluno " / >
HTML gerado:
1
2
< label for = " j_idt6 : exaluno " >Ex - aluno </ label >
< input id = " j_idt6 : exaluno " type = " checkbox " name = " j_idt6 : exaluno " / >
Resultado:
Ex-aluno
2. XHTML:
1
2
3
4
5
6
7
8
HTML gerado:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Resultado:
<h : selectOneRadio value = " #{ cursosBean . siglasDosCursosEscolhidos } " layout = " lineDirection " >
<f : selectItems
value = " #{ cursosBean . cursos } "
www.k19.com.br
85
C OMPONENTES V ISUAIS
4
5
6
7
86
HTML gerado:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
type = " radio " name = " j_idt6 : j_idt30 " id = " j_idt6 : j_idt30 :0 " value = " K11 " / >
for = " j_idt6 : j_idt30 :0 " > Orientao a Objetos em Java </ label >
type = " radio " name = " j_idt6 : j_idt30 " id = " j_idt6 : j_idt30 :1 " value = " K12 " / >
for = " j_idt6 : j_idt30 :1 " > Desenvolvimento Web com JSF2 e JPA2 </ label >
type = " radio " name = " j_idt6 : j_idt30 " id = " j_idt6 : j_idt30 :2 " value = " K51 " / >
for = " j_idt6 : j_idt30 :2 " > Design Patterns em Java </ label >
Resultado:
Orientao a Objetos em Java
4. XHTML:
1
2
3
4
5
6
7
8
HTML gerado:
1
2
3
4
5
6
< select name = " j_idt6 : j_idt33 " size = " 1 " >
< option value = " " > Escolha um curso </ option >
< option value = " K11 " > Orientao a Objetos em Java </ option >
< option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >
< option value = " K51 " > Design Patterns em Java </ option >
</ select >
Resultado:
Escolha um curso
Escolha um curso
Orientao a Objetos em Java
Desenvolvimento Web com JSF2 e JPA2
Design Patterns em Java
5. XHTML:
1
2
3
86
www.k19.com.br
87
4
5
6
7
C OMPONENTES V ISUAIS
var = " curso "
itemValue = " #{ curso . sigla } "
itemLabel = " #{ curso . nome } " / >
</ h : selectOneListbox >
HTML gerado:
1
2
3
4
5
< select name = " j_idt6 : j_idt37 " size = " 3 " >
< option value = " K11 " > Orientao a Objetos em Java </ option >
< option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >
< option value = " K51 " > Design Patterns em Java </ option >
</ select >
Resultado:
Orientao a Objetos em Java
Desenvolvimento Web com JSF2 e JPA2
Design Patterns em Java
6. XHTML:
1
2
3
4
5
6
7
HTML gerado:
1
2
3
4
5
< select name = " j_idt6 : j_idt40 " multiple = " multiple " size = " 3 " >
< option value = " K11 " > Orientao a Objetos em Java </ option >
< option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >
< option value = " K51 " > Design Patterns em Java </ option >
</ select >
Resultado:
Orientao a Objetos em Java
Desenvolvimento Web com JSF2 e JPA2
Design Patterns em Java
7. XHTML:
1
2
3
4
5
6
7
8
<h : selectManyMenu value = " #{ cursosBean . siglasDosCursosEscolhidos } " style = " height : 70 px ; " >
<f : selectItem itemLabel = " Escolha um curso " noSelectionOption = " true " / >
<f : selectItems
value = " #{ cursosBean . cursos } "
var = " curso "
itemValue = " #{ curso . sigla } "
itemLabel = " #{ curso . nome } " / >
</ h : selectManyMenu >
HTML gerado:
1
2
3
< select name = " j_idt6 : j_idt43 " multiple = " multiple " size = " 1 " style = " height : 70 px ; " >
< option value = " " selected = " selected " > Escolha um curso </ option >
< option value = " K11 " > Orientao a Objetos em Java </ option >
www.k19.com.br
87
C OMPONENTES V ISUAIS
4
5
6
88
< option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >
< option value = " K51 " > Design Patterns em Java </ option >
</ select >
Resultado:
Orientao a Objetos em Java
Desenvolvimento Web com JSF2 e JPA2
Design Patterns em Java
Botes e Links
O JSF define cinco tipos de botes e links:
<h:commandButton> e <h:commandLink>
Enviam os dados de um formulrio HTML para o servidor atravs do mtodo POST do HTTP.
<h:button> e <h:link>
Realizam requisies HTTP do tipo GET. As URLs das requisies so geradas pelo JSF a partir
do atributo outcome.
<h:outputLink>
Tambm realiza requisies HTTP do tipo GET, mas exige que a URL de destino seja explicitamente especificada.
Os componentes <h:commandButton> e <h:commandLink> so usados para submeter formulrios
HTML por meio do mtodo POST do HTTP. Esses dois componentes podem ser associados a mtodos de ao de um managed bean atravs dos atributos action e actionListener. Esses atributos
sero detalhados em outro captulo.
1
2
<h : commandButton value = " Adiciona curso " action = " #{ cursosBean . adicionaCurso } " / >
<h : commandLink value = " Remove curso " action = " #{ cursosBean . removeCurso } " / >
Cdigo XHTML 6.25: Exemplos de utilizao do <h:commandButton> e do <h:commandLink>
<h : button value = " Lista de cursos " outcome = " lista - cursos " / >
<h : link value = " Home " outcome = " home " / >
Cdigo XHTML 6.26: Exemplos de utilizao do <h:button> e do <h:link>
www.k19.com.br
89
C OMPONENTES V ISUAIS
O componente <h:outputLink> permite apenas a criao de links HTML que realizam requisies do tipo GET. Diferentemente dos componentes <h:button> e <h:link>, a URL da requisio
definida explicitamente no atributo value.
1
<h : outputLink value = " http :// www . k19 . com . br " / >
Cdigo XHTML 6.27: Um link para a pgina da K19
Exemplos
1. XHTML:
1
<h : commandButton value = " Adiciona curso " action = " #{ cursosBean . adicionaCurso } " / >
HTML gerado:
1
< input type = " submit " name = " j_idt59 : j_idt60 " value = " Adiciona curso " / >
Resultado:
Adiciona curso
2. XHTML:
1
<h : commandLink value = " Remove curso " action = " #{ cursosBean . removeCurso } " / >
HTML gerado:
1
2
3
<a href = " # " onclick = " mojarra . jsfcljs ( document . getElementById ( j_idt62 ) ,{ j_idt62 : j_idt66 : j_idt62 : j_idt66 } , ) ; return false " >
Remove curso
</ a >
Resultado:
Remove curso
3. XHTML:
1
<h : button value = " Lista de cursos " outcome = " lista - cursos " / >
HTML gerado:
1
2
3
4
< input
type = " button "
onclick = " window . location . href = / K19 - Componentes - Visuais / lista - cursos . xhtml ; return false ; "
value = " Lista de cursos " / >
Resultado:
Lista de cursos
4. XHTML:
www.k19.com.br
89
C OMPONENTES V ISUAIS
1
90
<h : link value = " Home " outcome = " home " / >
HTML gerado:
1
<a href = " / K19 - Componentes - Visuais / home . xhtml " > Home </ a >
Resultado:
Home
5. XHTML:
1
<h : outputLink value = " http :// www . k19 . com . br " > K19 </ h : outputLink >
HTML gerado:
1
<a href = " http :// www . k19 . com . br " > K19 </ a >
Resultado:
K19
Exerccios de Fixao
1
Crie uma classe chamada UsuarioBean. Essa classe deve possuir dois atributos: um atributo do
tipo String para armazenar o nome do usurio e um atributo do tipo int para armazenar a idade do
usurio.
2
1
2
3
4
5
6
7
@ManagedBean
public class UsuarioBean {
private String nome ;
private int idade ;
// GETTERS E SETTERS
}
Cdigo Java 6.5: UsuarioBean.java
3 Crie um arquivo XHTML no diretrio WebContent chamado usuario.xhtml. Nesse arquivo, crie
um formulrio para o usurio digitar e enviar o seu nome e a sua idade.
1
2
3
4
5
6
7
8
9
10
11
12
90
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : outputLabel value = " Nome : " for = " campo - nome " / >
www.k19.com.br
91
13
14
15
16
17
18
19
20
21
C OMPONENTES V ISUAIS
<h : inputText value = " #{ usuarioBean . nome } " id = " campo - nome " / >
<h : outputLabel value = " Idade : " for = " campo - idade " / >
<h : inputText value = " #{ usuarioBean . idade } " id = " campo - idade " / >
<h : commandButton value = " Enviar " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 6.33: usuario.xhtml
K19-Componentes-Visuais/usuario.xhtml.
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
6
Agora, crie um conversor monetrio. Esse conversor deve receber trs dados de entrada: as
moedas de origem e destino, e o valor a ser convertido. Primeiramente, crie uma classe chamada
ConversorMonetarioBean para implementar esse conversor.
1
2
3
4
5
6
7
8
@ManagedBean
public class ConversorMonetarioBean {
private String de ;
private String para ;
private Double valor ;
// GETTERS E SETTERS
}
Cdigo Java 6.6: ConversorMonetarioBean.java
1
2
@ManagedBean
public class ConversorMonetarioBean {
www.k19.com.br
91
C OMPONENTES V ISUAIS
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
92
private String de ;
private String para ;
private Double valor ;
private Double resultado ;
private Map < String , Double > taxas = new LinkedHashMap < String , Double >() ;
public ConversorMonetarioBean () {
this . taxas . put ( " Real " , 1.0) ;
this . taxas . put ( " Euro " , 2.33) ;
this . taxas . put ( " Peso argentino " , 0.42) ;
this . taxas . put ( " Dlar americano " , 1.84) ;
}
public void converte () {
this . resultado = this . valor * this . taxas . get ( this . de ) / this . taxas . get ( this . para ) ;
}
// GETTERS E SETTERS
}
Cdigo Java 6.7: ConversorMonetarioBean.java
No diretrio WebContent, crie um arquivo chamado conversor-monetario.xhtml. Nesse arquivo, implemente um formulrio para o usurio digitar os dados de entrada e ver o resultado da
converso.
8
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
92
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : commandButton value = " Converter " action = " #{ conversorMonetarioBean . converte } " / >
<h : inputText value = " #{ conversorMonetarioBean . valor } " / >
<h : outputLabel value = " de " for = " de " / >
<h : selectOneMenu value = " #{ conversorMonetarioBean . de } " id = " de " >
<f : selectItems
value = " #{ conversorMonetarioBean . taxas . keySet () } "
var = " moeda "
itemValue = " #{ moeda } "
itemLabel = " #{ moeda } " / >
</ h : selectOneMenu >
<h : outputLabel value = " para " for = " para " / >
<h : selectOneMenu value = " #{ conversorMonetarioBean . para } " id = " para " >
<f : selectItems
value = " #{ conversorMonetarioBean . taxas . keySet () } "
var = " moeda "
itemValue = " #{ moeda } "
itemLabel = " #{ moeda } " / >
</ h : selectOneMenu >
</ h : form >
Resultado : #{ conversorMonetarioBean . resultado }
</ h : body >
www.k19.com.br
93
41
C OMPONENTES V ISUAIS
</ html >
Cdigo XHTML 6.35: conversor-monetario.xhtml
xhtml
Exerccios Complementares
Considere o servio de atendimento ao consumidor de uma loja virtual. Voc deve criar um
formulrio para que o consumidor possa se comunicar com a loja. Esse formulrio deve ter campos
para o usurio informar o seu nome, e-mail, telefone, sexo e nmero do pedido. Alm disso, deve
existir um campo para o usurio selecionar um assunto e outro para ele escrever o seu comentrio.
1
Textos e Imagens
Para inserir textos em uma pgina, podemos usar os componentes <h:outputText> e <h:outputFormat>. O texto exibido por tais componentes definido pelo atributo value. Em particular, o
<h:outputFormat> permite diversos tipos de formatao do texto que ser exibido.
1
2
3
4
<h : outputFormat value = " Preo do produto {0}: R$ {1} " >
<f : param value = " #{ lojaBean . produto . nome } " / >
<f : param value = " #{ lojaBean . produto . preco } " / >
</ h : outputFormat >
Cdigo XHTML 6.37: Exemplo de utilizao do <h:outputFormat>
<h : graphicImage value = " / imagens / k19 - treinamentos . png " / >
Cdigo XHTML 6.38: Exemplo de insero de imagem
Para padronizar a organizao dos recursos da sua aplicao, o JSF 2 permite a criao de bibliotecas de imagens. Para criar uma biblioteca, basta adicionar um diretrio na pasta /resources (na
raiz da aplicao). Por exemplo, se criarmos o diretrio /resources/imagens-k19/ e adicionarmos
a imagem k19-treinamentos.png nesse diretrio, podemos inseri-la em uma pgina da seguinte
forma:
1
<h : graphicImage library = " imagens - k19 " name = " k19 - treinamentos . png " / >
Cdigo XHTML 6.39: Exemplo de insero de imagem usando o atributo library
Mais Sobre
Todos os componentes do JSF possuem um atributo booleano chamado rendered.
Esse atributo indica se o componente deve ser renderizado durante a etapa Render
www.k19.com.br
93
C OMPONENTES V ISUAIS
94
Response do processamento de uma requisio. O valor padro desse atributo true, o que
indica que o componente deve ser exibido.
O preo de alguns produtos vendidos pela Amazon.com, por exemplo, no so exibidos na pgina de apresentao do produto. Para um produto desse tipo, o usurio precisa adicion-lo ao
carrinho de compras para ento poder ver o seu preo.
Como exemplo, suponha que um objeto do tipo Produto possua uma propriedade booleana
chamada mostraPreco. Ela indica se o preo daquele produto deve ser exibido ou no. Assim,
podemos associar o atributo rendered do componente responsvel pela exibio do preo do
produto a essa propriedade. Isso pode ser feito usando expression language, como no exemplo
abaixo.
1
2
3
4
5
Exemplos
1. XHTML:
1
<h : outputText value = " Curso : #{ curso . sigla } - #{ curso . descricao } " / >
HTML gerado:
1
2. XHTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
<h : outputFormat value = " {0} amava {1} que amava {2} que amava {3}
que amava {4} que amava {5} que no amava ningum . {0} foi
para os Estados Unidos , {1} para o convento , {2} morreu de
desastre , {3} ficou para tia , {4} suicidou - se e {5} casou
com J . Pinto Fernandes que no tinha entrado na histria . " >
<f : param value = " Joo " / >
<f : param value = " Teresa " / >
<f : param value = " Raimundo " / >
<f : param value = " Maria " / >
<f : param value = " Joaquim " / >
<f : param value = " Lili " / >
</ h : outputFormat >
HTML gerado:
1
2
3
4
Joo amava Teresa que amava Raimundo que amava Maria que amava Joaquim que amava
Lili que no amava ningum . Joo foi para os Estados Unidos , Teresa para o
convento , Raimundo morreu de desastre , Maria ficou para tia , Joaquim suicidou - se
e Lili casou com J . Pinto Fernandes que no tinha entrado na histria .
3. XHTML:
94
www.k19.com.br
95
1
C OMPONENTES V ISUAIS
<h : graphicImage value = " / imagens / k19 - treinamentos . png " / >
HTML gerado:
1
< img src = " / K19 - Componentes - Visuais / imagens / k19 - treinamentos . png " / >
Resultado:
Exerccios de Fixao
No arquivo conversor-monetario.xhtml do projeto K19-Componentes-Visuais, use a tag <h:outputFormat> para exibir o resultado do conversor monetrio.
10
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
<! 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 "
xmlns :f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : commandButton value = " Converter " action = " #{ conversorMonetarioBean . converte } " / >
<h : inputText value = " #{ conversorMonetarioBean . valor } " / >
<h : outputLabel value = " de " for = " de " / >
<h : selectOneMenu value = " #{ conversorMonetarioBean . de } " id = " de " >
<f : selectItems
value = " #{ conversorMonetarioBean . taxas . keySet () } "
var = " moeda "
itemValue = " #{ moeda } "
itemLabel = " #{ moeda } " / >
</ h : selectOneMenu >
<h : outputLabel value = " para " for = " para " / >
<h : selectOneMenu value = " #{ conversorMonetarioBean . para } " id = " para " >
<f : selectItems
value = " #{ conversorMonetarioBean . taxas . keySet () } "
var = " moeda "
itemValue = " #{ moeda } "
itemLabel = " #{ moeda } " / >
</ h : selectOneMenu >
</ h : form >
<h : outputFormat value = " {0} em {1} equivale a {2} em {3} "
rendered = " #{ conversorMonetarioBean . resultado != null } " >
<f : param value = " #{ conversorMonetarioBean . valor } " / >
<f : param value = " #{ conversorMonetarioBean . de } " / >
<f : param value = " #{ conversorMonetarioBean . resultado } " / >
<f : param value = " #{ conversorMonetarioBean . para } " / >
www.k19.com.br
95
C OMPONENTES V ISUAIS
44
45
46
47
96
Componentes de Organizao
O JSF define dois componentes que nos ajudam a organizar visualmente os elementos de uma
pgina JSF.
<h:panelGrid>
Organiza os elementos em uma grade.
<h:panelGroup>
Permite que diversos componentes sejam tratados como um nico componente.
O <h:panelGrid> usado para organizar componentes em forma de uma grade. O uso de um
<h:panelGrid> bastante simples. Basicamente, devemos configurar a quantidade de colunas que
desejamos. Para isso, utilizamos o atributo columns.
1
2
3
4
5
6
7
8
9
10
11
12
96
www.k19.com.br
97
C OMPONENTES V ISUAIS
Exemplos
1. XHTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
HTML gerado:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Resultado:
Nome do curso:
Descrio:
Carga horria:
Cadastrar
Tabelas
www.k19.com.br
97
C OMPONENTES V ISUAIS
98
O JSF fornece o componente <h:dataTable> para a criao de tabelas. Podemos associar uma
lista de elementos a um <h:dataTable> atravs do atributo value. Automaticamente, esse componente gera uma linha para cada item da lista. Os itens da lista podem ser acessados atravs de uma
varivel definida pelo atributo var.
As colunas da tabela so definidas pelo componente <h:column>. Podemos acrescentar cabealhos e rodaps tabela e a cada coluna usando o componente <f:facet>.
Veja um exemplo a seguir.
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
<h : dataTable value = " #{ cursosBean . cursos } " var = " curso " >
<f : facet name = " header " > Lista de cursos </ f : facet >
<h : column >
<f : facet name = " header " > Sigla </ f : facet >
#{ curso . sigla }
</ h : column >
<h : column >
<f : facet name = " header " > Nome </ f : facet >
#{ curso . nome }
</ h : column >
<h : column >
<f : facet name = " header " > Descrio </ f : facet >
#{ curso . descricao }
</ h : column >
<h : column >
<f : facet name = " header " > Adicionar turma </ f : facet >
<h : commandLink
value = " Adicionar turma "
action = " #{ cursosBean . adicionarTurma ( curso ) } " / >
</ h : column >
</ h : dataTable >
Cdigo XHTML 6.48: Exemplo de criao de tabela com o componente <h:dataTable>
Observe, no exemplo acima, que a tabela est associada propriedade cursos do managed
bean cursosBean. A varivel curso utilizada para acessar cada um dos elementos da propriedade
cursos.
O cabealho Lista de cursos da tabela est definido com o componente <f:facet> assim como
o cabealho de cada coluna (Sigla, Nome, Descrio e Adicionar turma).
O HTML gerado pelo JSF a partir do cdigo acima seria mais ou menos assim:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
98
www.k19.com.br
99
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
C OMPONENTES V ISUAIS
< td > Orientao a Objetos em Java </ td >
< td >
Com este curso voc vai obter uma base slida de
conhecimentos de Java e de Orientao a Objetos
</ td >
< td >
< input
type = " submit " name = " j_idt100 : j_idt101 :0: j_idt114 "
value = " Adicionar turma " / >
</ td >
</ tr >
< tr >
< td > K12 </ td >
< td > Desenvolvimento Web com JSF2 e JPA2 </ td >
< td >
Depois deste curso , voc estar apto a desenvolver
aplicaes Web com os padres da plataforma Java
</ td >
< td >
< input
type = " submit " name = " j_idt100 : j_idt101 :1: j_idt114 "
value = " Adicionar turma " / >
</ td >
</ tr >
< tr >
< td > K21 </ td >
< td > Persistncia com JPA2 e Hibernate </ td >
< td >
Neste curso de Java Avanado , abordamos de maneira profunda
os recursos de persistncia do JPA2 e do Hibernate
</ td >
< td >
< input
type = " submit " name = " j_idt100 : j_idt101 :2: j_idt114 "
value = " Adicionar turma " / >
</ td >
</ tr >
</ tbody >
</ table >
Cdigo HTML 6.24: Cdigo HTML gerado pelo JSF
Lista de cursos
Descrio
Adicionar
Turma
Sigla
Nome
K11
Orientao a Objetos em
Java
Adiciona turma
K12
Desenvolvimento Web
com JSF2 e JPA2
Adiciona turma
K21
Adiciona turma
www.k19.com.br
99
C OMPONENTES V ISUAIS
100
Exerccios de Fixao
No projeto K19-Componentes-Visuais, crie uma pgina que contenha um formulrio para adicionar cursos e que exiba os cursos j adicionados. Primeiramente, crie uma classe chamada Curso
para representar um curso. Essa classe deve ter dois atributos do tipo String: um para armazenar o
nome e outro para armazenar a sigla do curso.
11
1
2
3
4
5
6
Crie uma classe chamada CursosBean para armazenar uma lista de cursos. Para que os cursos
adicionados sejam mantidos nessa varivel entre uma requisio e outra, marque a classe com a
anotao @SessionScoped. No Captulo 9 discutiremos sobre escopos de managed beans.
12
1
2
3
4
5
6
7
@ManagedBean
@SessionScoped
public class CursosBean {
private List < Curso > cursos = new ArrayList < Curso >() ;
// GETTER E SETTER
}
Cdigo Java 6.10: CursosBean.java
13 Na classe CursosBean, adicione dois atributos do tipo String para armazenar o nome e a sigla
de um curso e crie um mtodo para adicionar um curso com esse nome e essa sigla.
1
2
3
4
5
6
7
8
9
10
11
12
13
@ManagedBean
@SessionScoped
public class CursosBean {
private List < Curso > cursos = new ArrayList < Curso >() ;
private Curso curso = new Curso () ;
public void adicionaCurso () {
this . cursos . add ( this . curso ) ;
this . curso = new Curso () ;
}
// GETTERS E SETTERS
}
Cdigo Java 6.11: CursosBean.java
1
2
3
4
5
100
<! 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 "
www.k19.com.br
101
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
C OMPONENTES V ISUAIS
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Nome : " for = " campo - nome " / >
<h : inputText value = " #{ cursosBean . curso . nome } " id = " campo - nome " / >
<h : outputLabel value = " Sigla : " for = " campo - sigla " / >
<h : inputText value = " #{ cursosBean . curso . sigla } " id = " campo - sigla " / >
<h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } " / >
</ h : panelGrid >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 6.49: cursos.xhtml
No arquivo cursos.xhtml, insira um trecho de cdigo para exibir os cursos j adicionados. Use
a tag <h:dataTable> para apresentar os cursos. Voc pode usar o atributo rendered desse componente para exibir a tabela apenas quando a lista de cursos no est vazia.
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
39
40
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Sigla : " for = " campo - sigla " / >
<h : inputText value = " #{ cursosBean . curso . sigla } " id = " campo - sigla " / >
<h : outputLabel value = " Nome : " for = " campo - nome " / >
<h : inputText value = " #{ cursosBean . curso . nome } " id = " campo - nome " / >
<h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } " / >
</ h : panelGrid >
</ h : form >
<h : dataTable value = " #{ cursosBean . cursos } " var = " curso "
rendered = " #{ not empty cursosBean . cursos } " >
<f : facet name = " header " > Lista de Cursos </ f : facet >
<h : column >
<f : facet name = " header " > Sigla </ f : facet >
#{ curso . sigla }
</ h : column >
<h : column >
<f : facet name = " header " > Nome </ f : facet >
#{ curso . nome }
</ h : column >
</ h : dataTable >
</ h : body >
</ html >
Cdigo XHTML 6.50: cursos.xhtml
www.k19.com.br
101
C OMPONENTES V ISUAIS
102
http://localhost:8080/K19-Componentes-Visuais/cursos.xhtml
Exerccios Complementares
2
Usando o componente <h:dataTable>, liste os produtos de uma loja virtual. A tabela deve
mostrar o nome e o preo de cada produto. No diretrio src, crie uma classe chamada Produto. Essa
classe deve ter um atributo do tipo String para armazenar o nome do produto e um atributo do tipo
Double para guardar o preo do produto. Crie uma classe chamada ProdutosBean para guardar uma
lista de produtos. Implemente a listagem de produtos em um arquivo chamado lista-de-produtos.xhtml no diretrio WebContent.
Na classe Produto, acrescente uma propriedade do tipo Boolean para indicar se o preo do
produto deve ser exibido. Modifique a tabela de listagem dos produtos para considerar essa nova
restrio. Se o preo de um produto no puder ser exibido, ento o texto Adicione o produto ao
carrinho para ver o preo deve aparecer no lugar do preo do produto.
3
Mensagens
Durante o processamento de uma requisio, podemos adicionar mensagens que podem ser exibidas na pgina de resposta. Uma mensagem pode ser adicionada, por exemplo, da seguinte forma:
1
2
O primeiro parmetro do mtodo addMessage() define qual componente ser associado mensagem adicionada. Quando o valor null passado nesse parmetro, a mensagem considerada
global, ou seja, ela no ser associada a nenhum componente especfico.
Na tela, podemos exibir todas as mensagens geradas no processamento da requisio atravs do
componente <h:messages>. Se desejarmos exibir apenas as mensagens globais, devemos utilizar o
atributo globalOnly da seguinte forma:
1
www.k19.com.br
103
C OMPONENTES V ISUAIS
<h : outputScript name = " k19 . js " library = " javascript " target = " head " / >
<h : outputStylesheet name = " k19 . css " library = " css " / >
Cdigo XHTML 6.54: Exemplo de adio de cdigo JavaScript e arquivo CSS na pgina da aplicao
Outros Componentes
<ui:remove>
Para comentar (ou excluir) partes de cdigo XHTML de uma aplicao, o JSF prov a tag <ui:remove>. Qualquer trecho de cdigo dentro dessa tag removido durante o processamento de uma
pgina JSF. No exemplo abaixo, a caixa para inserir o sobrenome do usurio no ser processada e,
portanto, no ser exibida na pgina gerada.
1
2
3
4
Nome : Jonas
Cdigo HTML 6.25: Trecho de cdigo HTML gerado pelo JSF
Alternativamente, podemos usar os delimitadores <!-- e --> do XML para comentar o cdigo.
Nesse caso, contudo, o trecho de cdigo comentado ser processado pelo JSF. Por exemplo, a partir
do cdigo
1
2
3
4
Nome : Jonas
<! -<h : outputText value = " Sobrenome : Hirata " / >
-- >
Cdigo HTML 6.26: Trecho de cdigo HTML gerado pelo JSF
Note que o cdigo dentro do comentrio foi processado pelo JSF. A string "Hirata" foi obtida da
propriedade sobrenome do managed bean testeBean.
www.k19.com.br
103
C OMPONENTES V ISUAIS
104
<ui:repeat>
A tag <ui:repeat> usada para iterar sobre colees. Ela possui dois atributos obrigatrios:
value e var. O atributo value deve ser associado a uma coleo de objetos e o atributo var deve
definir o nome da varivel. Essa varivel ser usada para referenciar cada um dos elementos da
coleo. No exemplo abaixo, temos um cdigo para gerar uma lista HTML no ordenada a partir de
uma coleo de cursos.
1
2
3
4
5
6
7
8
Exerccios de Fixao
No projeto K19-Componentes-Visuais, crie um arquivo CSS para formatar a pgina que lista
os cursos. No diretrio WebContent, crie um diretrio chamado resources. Dentro de resources,
crie um diretrio chamado css. Crie um arquivo chamado k19.css contendo o estilo desejado e
adicione-o ao diretrio WebContent/resources/css.
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
body {
font - family : arial , helvetica , sans - serif ;
font - size : 14 px ;
}
h1 {
color : #006699;
font - size : 18 px ;
}
ul {
list - style - type : square ;
}
input {
background - color : # E6E6FA ;
border : solid 1 px #000000;
}
Cdigo CSS 6.1: k19.css
104
www.k19.com.br
105
C OMPONENTES V ISUAIS
Use a tag <h:outputStylesheet> para incluir o arquivo de estilos na pgina definida por cursos.xhtml. Use a tag <ui:repeat> para exibir os cursos.
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
37
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : outputStylesheet name = " k19 . css " library = " css " / >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Sigla : " for = " campo - sigla " / >
<h : inputText value = " #{ cursosBean . sigla } " id = " campo - sigla " / >
<h : outputLabel value = " Nome : " for = " campo - nome " / >
<h : inputText value = " #{ cursosBean . nome } " id = " campo - nome " / >
<h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } " / >
</ h : panelGrid >
</ h : form >
< h1 > Alguns cursos da K19 : </ h1 >
< ul >
< ui : repeat value = " #{ cursosBean . cursos } " var = " curso " >
< li >
<h : outputText value = " #{ curso . sigla }: #{ curso . nome } " / >
</ li >
</ ui : repeat >
</ ul >
</ h : body >
</ html >
Cdigo XHTML 6.58: cursos.xhtml
Exerccios Complementares
Considere novamente a pgina de adio e listagem de cursos. Modifique sua aplicao de forma
que uma mensagem de confirmao seja exibida na tela aps o usurio adicionar um novo curso.
4
www.k19.com.br
105
C OMPONENTES V ISUAIS
106
106
www.k19.com.br
CAPTULO
T EMPLATES E M ODULARIZAO
Certamente, voc j ouviu algum falar da importncia da reutilizao de cdigo no desenvolvimento de software. Os objetivos principais dessa reutilizao so diminuir o tempo e o custo do
desenvolvimento e da manuteno das aplicaes.
Com essa ideia em mente, um projeto chamado Facelets foi desenvolvido com o objetivo principal de facilitar todo o processo de desenvolvimento e manuteno das telas de uma aplicao JSF. O
Facelets j faz parte do JSF 2 e a engine padro para o gerenciamento das telas de aplicaes web
JSF 2.
Templates
A reutilizao do cdigo das telas realizada principalmente pelo uso de templates. A ideia
identificar um padro em um determinado conjunto de telas e defini-lo atravs de um esqueleto
(template). Esse esqueleto formado por trechos estticos e dinmicos. O posicionamento desses
trechos sempre fixo. Contudo, ao contrrio do contedo de um trecho esttico, o contedo de um
trecho dinmico pode diferir de tela para tela.
Por exemplo, considere uma aplicao na qual todas as telas so divididas em trs partes: cabealho, corpo e rodap. Essas partes esto sempre posicionadas da mesma forma. O cabealho
posicionado no topo da pgina, o rodap, no final e o corpo, entre os dois anteriores. O contedo do
cabealho e do rodap sempre o mesmo em todas as telas da aplicao. Por outro lado, o contedo
do corpo varia de tela para tela.
www.k19.com.br
107
T EMPLATES E M ODULARIZAO
108
Pgina 2
Lorem ipsum dolor sit
amet, consectetur
adipiscing elit.
Aenean rutrum
accumsan lorem, non
euismod ligula
aliquet in. Proin vitae
ultricies sapien.
Donec volutpat lacus
eleifend sapien
vestibulum eu
dapibus mi pharetra
Pgina 2
Pgina 1
Lorem ipsum dolor sit
amet, consectetur
adipiscing elit.
Aenean rutrum
accumsan lorem, non
euismod ligula
aliquet in. Proin vitae
ultricies sapien.
Donec volutpat lacus
eleifend sapien
vestibulum eu
dapibus mi pharetra
Pgina 3
Lorem ipsum dolor sit
amet, consectetur
adipiscing elit.
Aenean rutrum
accumsan lorem, non
euismod ligula
aliquet in. Proin vitae
ultricies sapien.
Donec volutpat lacus
eleifend sapien
vestibulum eu
dapibus mi pharetra
Pgina 1
Template
Pgina 3
Pgina 4
Lorem ipsum dolor sit
amet, consectetur
adipiscing elit.
Aenean rutrum
accumsan lorem, non
euismod ligula
aliquet in. Proin vitae
ultricies sapien.
Donec volutpat lacus
eleifend sapien
vestibulum eu
dapibus mi pharetra
Pgina 4
Figura 7.1: Template utilizado por diversas pginas
Criando um template
A criao de um template simples. Basta criar um arquivo XHTML e definir o posicionamento
dos trechos estticos e dinmicos. O contedo dos trechos estticos tambm deve ser definido da
forma usual dentro do template. Por outro lado, o contedo dos trechos dinmicos s ser definido
nas telas. Para indicar o posicionamento dos trechos dinmicos, devemos utilizar a tag <ui:insert>.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
108
<! 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 "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< div id = " header " >
< img src = " k19 - logo . png " / >
< hr / >
</ div >
www.k19.com.br
109
17
18
19
20
21
22
23
24
25
T EMPLATES E M ODULARIZAO
< ui : insert name = " corpo - da - pagina " > Espao para o contedo da tela </ ui : insert >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2010 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML 7.1: template.xhtml
Utilizando templates
Para criar uma tela que usa um determinado template, devemos criar um arquivo XHTML e adicionar a tag <ui:composition> a esse arquivo. O arquivo do template desejado deve ser indicado
atravs do atributo template da tag <ui:composition>.
1
2
3
4
Todo contedo no contido na tag <ui:composition> ser descartado pelo JSF no processo de
construo da tela.
O contedo de um trecho dinmico pode ser definido atravs do componente <ui:define>. Esse
componente possui o atributo name que utilizado para indicar qual trecho dinmico do template
queremos definir.
No exemplo acima, podemos definir o contedo do trecho dinmico corpo-da-pagina da seguinte forma:
1
2
3
4
5
6
7
8
9
10
11
www.k19.com.br
109
T EMPLATES E M ODULARIZAO
110
Exerccios de Fixao
Crie um projeto do tipo Dynamic Web Project chamado K19-Templates-e-Modularizacao seguindo os passos vistos no exerccio do Captulo 5.
1
Crie um diretrio chamado templates na pasta WEB-INF. Crie um template chamado template.xhtml na pasta WEB-INF/templates. Copie o arquivo k19-logo.png da pasta K19-Arquivos/imagens,
que est na rea de Trabalho, para a pasta WebContent do projeto K19-Templates-e-Modularizacao.
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<! 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 "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< div id = " header " > < img src = " k19 - logo . png " / >
< hr / >
</ div >
< ui : insert name = " conteudo " > Espao para o contedo da tela </ ui : insert >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2012 K19 . Todos os direitos reservados . </ div >
</ h : body >
</ html >
Cdigo XHTML 7.4: template.xhtml
Monte uma tela que use o template criado no exerccio anterior. O nome do arquivo deve ser
formulario.xhtml.
1
2
3
4
5
110
< ui : composition template = " / WEB - INF / templates / template . xhtml "
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
www.k19.com.br
111
6
7
8
9
10
11
12
13
T EMPLATES E M ODULARIZAO
< ui : define name = " conteudo " >
<h : form >
<h : outputLabel value = " Nome : " for = " campo - nome " / >
<h : inputText id = " campo - nome " / >
<h : commandButton value = " Enviar " / >
</ h : form >
</ ui : define >
</ ui : composition >
Cdigo XHTML 7.5: formulario.xhtml
http://localhost:8080/K19-Templates-e-Modularizacao/formulario.xhtml
Modularizao
Os trechos estticos ou dinmicos definidos em um template possuem posio fixa. Em determinadas situaes, necessrio tornar flexvel o posicionamento de um determinado trecho.
Por exemplo, considere uma aplicao com 50 pginas diferentes. Os usurios dessa aplicao
podem enviar mensagens para o administrador do sistema quando identificarem algum problema.
Essas mensagens so enviadas atravs de um formulrio HTML. Esse formulrio de contato deve ser
exibido em todas as telas da aplicao.
Nesse caso, poderamos pensar em criar um template e definir o formulrio de contato como um
trecho esttico desse template. Contudo, h uma restrio importante que descarta essa abordagem.
O formulrio de contato deve ser exibido em posies diferentes nas telas da aplicao. Por exemplo,
em algumas telas o formulrio aparecer no topo e em outras ele aparecer no centro.
Suspendisse tristique
dolor sit amet felis
vehicula rutrum.
Phasellus fringilla
mauris eu turpis
sodales congue.
Etiam ultricies nisl in
Mdulo / Partial
Lorem ipsum
Lorem ipsum dolor sit
amet, consectetur
adipiscing elit.
Aenean rutrum
accumsan lorem, non
euismod ligula
aliquet in. Proin vitae
ultricies sapien.
Donec volutpat lacus
eleifend sapien
vestibulum eu
dapibus mi pharetra
Lorem ipsum
Suspendisse tristique
dolor sit amet felis
vehicula rutrum.
Phasellus fringilla
mauris eu turpis
sodales congue.
Suspendisse tristique
dolor sit amet felis
vehicula rutrum.
Phasellus fringilla
mauris eu turpis
sodales congue.
Pgina 1
Pgina 2
Lorem ipsum
Suspendisse tristique
dolor sit amet felis
vehicula rutrum.
Suspendisse tristique
dolor sit amet felis
vehicula rutrum.
Pgina 3
111
T EMPLATES E M ODULARIZAO
1
2
3
4
5
6
7
8
9
10
11
12
13
112
< ui : composition
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : form >
<h : panelGrid >
<h : outputLabel value = " Mensagem : " for = " mensagem " / >
<h : inputTextarea id = " mensagem " value = " #{ mensagensBean . mensagem } " / >
<h : commandButton value = " Enviar " action = " #{ mensagensBean . envia } " / >
</ h : panelGrid >
</ h : form >
</ ui : composition >
Cdigo XHTML 7.6: formulario-de-contato.xhtml
Com o formulrio de contato definido em um arquivo separado, podemos utilizar a tag <ui:in-
...
< ui : include src = " / formulario - de - contato . xhtml " / >
...
Cdigo XHTML 7.7: Inserindo o formulrio de contato
Parmetros
Em algumas situaes necessrio passar parmetros de um arquivo XHTML para outro. Por
exemplo, considere a aplicao de uma livraria. Na primeira pgina dessa aplicao, uma lista com
livros mais vendidos exibida no canto direito. Em outra pgina, uma lista com os livros mais caros
exibida no canto esquerdo.
Podemos criar um arquivo XHTML e atribuir a ele a tarefa de exibir uma lista qualquer de livros
independentemente de posicionamento.
1
2
3
4
5
6
7
8
9
< ui : composition
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : dataTable value = " #{ livros } " var = " livro " >
...
</ h : dataTable >
</ ui : composition >
Cdigo XHTML 7.8: lista-livros.xhtml
Observe, no cdigo acima, que o componente <h:dataTable> foi vinculado a uma varivel chamada livros. Essa varivel um parmetro do arquivo lista-livros.xhtml.
Na primeira pgina da aplicao da livraria, podemos adicionar o arquivo lista-livros.xhtml
com a tag <ui:include>, passando como parmetro a lista dos livros mais vendidos. Para isso, devemos utilizar o componente <ui:param>.
1
2
3
112
...
< ui : include src = " / lista - livros . xhtml " >
< ui : param name = " livros " value = " #{ livrosBean . listaDosLivrosMaisVendidos } " / >
www.k19.com.br
113
4
5
T EMPLATES E M ODULARIZAO
</ ui : include >
...
Cdigo XHTML 7.9: Inserindo a lista dos livros mais vendidos
...
< ui : include src = " / lista - livros . xhtml " >
< ui : param name = " livros " value = " #{ livrosBean . listaDosLivrosMaisCaros } " / >
</ ui : include >
...
Cdigo XHTML 7.10: Inserindo a lista dos livros mais caros
Exerccios de Fixao
4
Vamos implementar uma listagem de instrutores no nosso projeto K19-Templates-e-Modularizacao. O primeiro passo criar uma classe para modelar os instrutores. Crie um pacote chamado
model no projeto K19-Templates-e-Modularizacao e adicione nele uma classe chamada Instrutor
package model ;
public class Instrutor {
private String nome ;
private String dataDeNascimento ;
// GETTERS E SETTERS
}
Cdigo Java 7.1: Instrutor.java
Faa um managed bean que fornea uma lista de instrutores para uma tela de listagem de instrutores. Crie um pacote chamado managedbeans no projeto K19-Templates-e-Modularizacao e
adicione nele uma classe chamada InstrutorBean com seguinte cdigo:
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package managedbeans ;
import
import
import
import
@ManagedBean
public class InstrutorBean {
private List < Instrutor > instrutores = new ArrayList < Instrutor >() ;
public InstrutorBean () {
Instrutor rafael = new Instrutor () ;
rafael . setNome ( " Rafael Cosentino " ) ;
rafael . setDataDeNascimento ( " 30/10/1984 " ) ;
Instrutor marcelo = new Instrutor () ;
marcelo . setNome ( " Marcelo Martins " ) ;
marcelo . setDataDeNascimento ( " 02/04/1985 " ) ;
www.k19.com.br
113
T EMPLATES E M ODULARIZAO
22
23
24
25
26
27
28
29
30
31
32
33
114
Crie uma tela parcial para mostrar os dados de apenas um instrutor dentro de um item de uma
lista HTML. O arquivo deve ser adicionado na pasta WebContent do projeto K19-Templates-e-Modularizacao e se chamar instrutor-info.xhtml.
6
1
2
3
4
5
6
7
8
9
10
11
< ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
< li >
<h : outputText value = " Nome : #{ instrutor . nome } " / >
< br / >
<h : outputText value = " Data Nascimento : #{ instrutor . dataDeNascimento } " / >
</ li >
</ ui : composition >
Cdigo XHTML 7.11: instrutor-info.xhtml
Faa a tela principal da listagem de instrutores. Crie um arquivo na pasta WebContent do projeto K19-Templates-e-Modularizacao com o nome listagem-de-instrutores.xhtml e com o seguinte cdigo.
7
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
< ui : composition template = " / WEB - INF / templates / template . xhtml "
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
< ui : define name = " conteudo " >
< ul >
< ui : repeat var = " instrutor " value = " #{ instrutorBean . instrutores } " >
< ui : include src = " instrutor - info . xhtml " >
< ui : param name = " instrutor " value = " #{ instrutor } " / >
</ ui : include >
</ ui : repeat >
</ ul >
</ ui : define >
</ ui : composition >
Cdigo XHTML 7.12: listagem-de-instrutores.xhtml
http://localhost:8080/K19-Templates-e-Modularizacao/listagem-de-instrutores.xhtml
Exerccios Complementares
114
www.k19.com.br
115
T EMPLATES E M ODULARIZAO
Usando templates, voc deve criar uma pgina para exibir os detalhes dos produtos de uma
loja virtual. A pgina de apresentao dos produtos deve ter o seguinte formato. Uma imagem do
produto deve ser apresentada do lado esquerdo da pgina. O nome e o preo do produto devem ser
exibidos do lado direito da imagem. Uma descrio do produto deve aparecer abaixo de tudo. Alm
disso, o logotipo da loja deve aparecer no topo da pgina e, logo abaixo, deve haver uma caixa de
seleo para escolher o produto cujos detalhes sero exibidos.
1
www.k19.com.br
115
T EMPLATES E M ODULARIZAO
116
116
www.k19.com.br
CAPTULO
N AVEGAO
Navegar entre as telas de uma aplicao web preciso. O mecanismo de navegao do JSF bem
sofisticado e permite vrios tipos de transies entre telas. A ideia muito simples: no clique de um
boto ou link, muda-se a tela apresentada ao usurio.
www.k19.com.br/artigo
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aenean rutrum accumsan lorem, non euismod ligula
aliquet in. Proin vitae ultricies sapien. Donec volutpat
lacus eleifend sapien vestibulum eu dapibus mi pharetra.
Nunc at quam erat. Sed vel dui a tortor ultricies fringilla
eget et ipsum. Maecenas at sem at nunc pharetra
consectetur. Nulla enim nisi, tristique ac rhoncus vel,
rhoncus a dolor. Ut dignissim, nisi vitae varius dictum,
www.k19.com.br
Lorem ipsum dolor sit amet,
consectetur adipiscing elit.
Aenean rutrum accumsan
lorem, non euismod ligula
aliquet in.
LEIA MAIS
COMPRAR
www.k19.com.br/loja
Navegao Implcita
Na navegao implcita, quando o usurio clica em algum boto ou link, um sinal (outcome)
enviado para o JSF. Esse sinal uma string que ser utilizada pelo tratador de navegao do JSF para
definir a prxima tela que ser apresentada ao usurio.
Considere, por exemplo, um link ou boto de uma tela (definida pelo arquivo pagina1.xhtml)
que envia o outcome pagina2. Quando um usurio clicar nesse link ou boto, ele ser redirecionado para a tela definida pelo arquivo pagina2.xhtml. Esse arquivo deve estar no mesmo diretrio
do arquivo pagina1.xhtml. Nesse caso, o outcome igual ao nome do arquivo de resposta sem o
sufixo .xhtml.
www.k19.com.br
117
N AVEGAO
118
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > K19 Pgina 1 </ h1 >
<h : form >
<h : commandButton value = " Pgina 2 " action = " pagina2 " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 8.1: pagina1.xhtml
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 : h = " http :// java . sun . com / jsf / html " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > K19 Pgina 2 </ h1 >
<h : link outcome = " pagina1 " >
<h : outputText value = " Pgina 1 " / >
</ h : link >
</ h : body >
</ html >
Cdigo XHTML 8.2: pagina2.xhtml
...
<h : commandButton value = " Pgina 2 " action = " / diretorio1 / diretorio2 / pagina2 " / >
...
Cdigo XHTML 8.3: pagina1.xhtml
1
2
3
...
<h : commandButton value = " Pgina 2 " action = " diretorio2 / pagina2 " / >
...
Cdigo XHTML 8.4: pagina1.xhtml
118
www.k19.com.br
119
N AVEGAO
Note que, no primeiro cdigo, o caminho definido a partir do diretrio raiz da aplicao web.
J no segundo cdigo, o caminho definido relativamente ao diretrio atual.
Navegao Explcita
Na navegao explcita, podemos associar um outcome a um arquivo de resposta independentemente do nome ou do caminho desse arquivo. Essa associao deve ser registrada no arquivo de
configurao do JSF, o faces-config.xml.
Para registrar uma navegao explcita, podemos adicionar trs informaes no arquivo de configurao do JSF:
O caminho do arquivo que define a tela de origem.
O outcome.
O caminho do arquivo que define a tela de resposta.
Veja o exemplo abaixo.
1
2
3
4
5
6
7
8
Aps o registro da navegao acima, podemos adicionar um boto ou link no arquivo pagina1.xhtml com o outcome proxima para navegar para o arquivo pagina2.xhtml.
1
2
3
...
<h : commandButton value = " Prxima tela " action = " proxima " / >
...
Cdigo XHTML 8.5: pagina1.xhtml
Importante
O JSF utiliza a seguinte lgica para determinar a pgina de resposta. Primeiro, ele verifica se o outcome compatvel com alguma regra de navegao registrada no arquivo
faces-config.xml. Caso seja, o JSF realizar uma navegao explcita processando essa regra.
Caso contrrio, o JSF tentar realizar uma navegao implcita, procurando um arquivo compatvel com o outcome. Se esse arquivo no existir, a tela atual ser reapresentada.
Mais Sobre
Podemos registrar uma regra de navegao para diversos arquivos utilizando
wildcards. Considere o exemplo abaixo.
www.k19.com.br
119
N AVEGAO
1
2
3
4
5
6
7
8
120
O caractere * na tag <from-view-id> indica que essa regra de navegao ser aplicada para
todo arquivo do diretrio /K19.
Mais Sobre
Podemos criar navegaes condicionais. Considere, por exemplo, uma aplicao em
que os usurios podem escolher a verso da interface que desejam utilizar. As regras de
navegao podem ento considerar a preferncia do usurio. Para isso, podemos adicionar a tag
<if> na definio de uma regra de navegao. Veja o exemplo abaixo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Exerccios de Fixao
1
Crie um projeto do tipo Dynamic Web Project chamado K19-Navegacao seguindo os passos
vistos nos exerccios de fixao do Captulo 5.
Na pasta WebContent do projeto K19-Navegacao, crie trs arquivos XHTML: componentes-visuais.xhtml, templates-e-modularizacao.xhtml e navegacao.xhtml. A partir de qualquer um
deles, deve ser possvel navegar para qualquer outro. Podemos criar uma espcie de menu para
navegar entre as pginas:
2
120
...
www.k19.com.br
121
2
3
4
5
N AVEGAO
<h : link value = " Componentes Visuais " outcome = " componentes - visuais " / > <h : link value = " Templates e Modularizao " outcome = " templates -e - modularizacao " / > <h : link value = " Navegao " outcome = " navegacao " / >
...
Cdigo XHTML 8.6: Menu para navegar entre as pginas.
Para facilitar, podemos definir um template para criar essas trs pginas. Crie um arquivo chamado template.xhtml no diretrio /WEB-INF/templates/.
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
< html xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< div id = " header " style = " text - align : center " >
< h1 > K19 - Desenvolvimento Web com JSF2 e JPA2 </ h1 >
</ div >
<h : link value = " Componentes Visuais " outcome = " componentes - visuais " / > <h : link value = " Templates e Modularizao " outcome = " templates -e - modularizacao " / > <h : link value = " Navegao " outcome = " navegacao " / >
< ui : insert name = " corpo - da - pagina " > Espao para o contedo da tela </ ui : insert >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2010 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML 8.7: template.xhtml
Agora, use esse template para criar as pginas componentes-visuais.xhtml, templates-e-modularizacao.xhtml e navegacao.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
www.k19.com.br
121
N AVEGAO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
122
1
2
3
4
5
6
7
8
9
10
11
12
13
14
http://localhost:8080/K19-Navegacao/componentes-visuais.xhtml
5 Suponha que a sequncia dos tpicos seja Componentes Visuais, Templates e Modularizao
e Navegao. Queremos adicionar dois botes s pginas: um para avanar para o prximo tpico
e outro para voltar para o tpico anterior. Para isso, configure uma navegao explcita no arquivo
faces-config.xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
122
...
< navigation - rule >
< from - view - id > componentes - visuais . xhtml </ from - view - id >
< navigation - case >
< from - outcome > proximo </ from - outcome >
<to - view - id > templates -e - modularizacao . xhtml </ to - view - id >
</ navigation - case >
</ navigation - rule >
< navigation - rule >
< from - view - id > templates -e - modularizacao . xhtml </ from - view - id >
< navigation - case >
< from - outcome > proximo </ from - outcome >
<to - view - id > navegacao . xhtml </ to - view - id >
</ navigation - case >
< navigation - case >
< from - outcome > anterior </ from - outcome >
<to - view - id > componentes - visuais . xhtml </ to - view - id >
www.k19.com.br
123
22
23
24
25
26
27
28
29
30
31
32
33
N AVEGAO
</ navigation - case >
</ navigation - rule >
< navigation - rule >
< from - view - id > navegacao . xhtml </ from - view - id >
< navigation - case >
< from - outcome > anterior </ from - outcome >
<to - view - id > templates -e - modularizacao . xhtml </ to - view - id >
</ navigation - case >
</ navigation - rule >
...
Cdigo XML 8.4: faces-config.xml
No arquivo /WEB-INF/template.xhtml, adicione dois botes. O primeiro deve ser usado para
navegar para o tpico anterior (logo, deve emitir o sinal anterior). O segundo boto deve ser
usado para navegar para o prximo tpico (portanto, deve emitir o sinal proximo).
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
<! 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 "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< div id = " header " style = " text - align : center " >
< h1 > K19 - Desenvolvimento Web com JSF2 e JPA2 </ h1 >
</ div >
<h : form >
<h : commandButton value = " Anterior " action = " anterior " / >
<h : commandButton value = " Prximo " action = " proximo " / >
</ h : form >
<h : link value = " Componentes Visuais " outcome = " componentes - visuais " / > <h : link value = " Templates e Modularizao " outcome = " templates -e - modularizacao " / > <h : link value = " Navegao " outcome = " navegacao " / >
< ui : insert name = " corpo - da - pagina " > Espao para o contedo da tela </ ui : insert >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2010 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML 8.11: template.xhtml
http://localhost:8080/K19-Navegacao/componentes-visuais.xhtml
123
N AVEGAO
124
At agora, utilizamos apenas navegaes estticas, pois os outcomes foram definidos nos botes
e links. Dessa forma, toda vez que um boto ou link clicado, ele emite sempre o mesmo outcome.
Por exemplo, o boto abaixo sempre emite o outcome k19.
1
<h : commandButton value = " K19 " action = " k19 " / >
Cdigo XHTML 8.12: Boto com navegao esttica
Podemos tornar esse comportamento dinmico, fazendo com que os outcomes sejam diferentes
a cada clique. Para isso, os botes e links devem ser associados a mtodos de ao de managed beans
atravs de expression language. Veja o exemplo abaixo.
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 : h = " http :// java . sun . com / jsf / html " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > K19 Cara ou Coroa </ h1 >
<h : form >
<h : commandButton value = " Lanar Moeda " action = " #{ caraOuCoroaBean . lanca } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 8.13: cara-ou-coroa.xhtml
1
2
3
4
5
6
7
8
9
10
@ManagedBean
public class CaraOuCoroaBean {
public String lanca () {
if ( Math . random () < 0.5) {
return " cara " ;
} else {
return " coroa " ;
}
}
}
Cdigo Java 8.1: CaraOuCoroaBean.java
Toda vez que o boto Lanar Moeda for clicado, o mtodo lanca() do managed bean caraOuCoroaBean ser chamado. A string devolvida por esse mtodo ser considerada o outcome a ser
utilizado na navegao.
Mais Sobre
Vimos que a pgina de resposta depende tanto da pgina de origem quanto do outcome. No caso da navegao dinmica, a pgina de resposta tambm pode depender
do mtodo de ao que produziu o outcome. Para isso, basta acrescentar a tag <from-action>
na definio da regra de navegao. Veja o exemplo abaixo.
1
2
3
4
124
www.k19.com.br
125
5
6
7
8
9
10
11
12
13
14
15
N AVEGAO
1
2
3
4
...
<h : commandLink value = " Lista cursos " action = " #{ cursosBean . lista } " / >
<h : commandLink value = " Lista alunos " action = " #{ alunosBean . lista } " / >
...
Cdigo XHTML 8.14: index.xhtml
Se o link Lista cursos for clicado, o mtodo lista() do managed bean cursosBean ser
acionado. Suponha que esse mtodo devolva lista. De acordo com a regra de navegao
definida no faces-config.xml, o usurio ser direcionado pgina definida pelo arquivo
/lista-cursos.xhtml.
Por outro lado, se o usurio clicar no link Lista alunos, o mtodo lista() do managed bean
alunosBean ser invocado. Se esse mtodo devolver lista, o usurio ser direcionado
pgina definida pelo arquivo /lista-alunos.xhtml, conforme a regra de navegao definida
no faces-config.xml.
Exerccios de Fixao
Implemente um managed bean que, de forma aleatria, escolha entre dois outcomes. Crie um
pacote chamado managedbeans no projeto K19-Navegacao e adicione uma classe chamada CaraOuCoroaBean.
8
1
2
3
4
5
6
7
8
9
10
@ManagedBean
public class CaraOuCoroaBean {
public String proxima () {
if ( Math . random () < 0.5) {
return " cara " ;
} else {
return " coroa " ;
}
}
}
Cdigo Java 8.2: CaraOuCoroaBean.java
Crie uma tela principal com um boto que chama o managed bean do exerccio anterior para escolher o outcome que deve ser emitido para o JSF. Para isso, faa um arquivo chamado cara-ou-coroa.xhtml na pasta WebContent do projeto K19-Navegacao.
9
www.k19.com.br
125
N AVEGAO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
126
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > K19 Cara ou Coroa </ h1 >
<h : form >
<h : commandButton value = " Lanar Moeda " action = " #{ caraOuCoroaBean . proxima } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 8.15: cara-ou-coroa.xhtml
10
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 : h = " http :// java . sun . com / jsf / html " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Deu Cara ! </ h1 >
<h : form >
<h : commandButton value = " voltar " action = " cara - ou - coroa " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 8.16: cara.xhtml
O arquivo coroa.xhtml:
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 : h = " http :// java . sun . com / jsf / html " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Deu Coroa ! </ h1 >
<h : form >
<h : commandButton value = " voltar " action = " cara - ou - coroa " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 8.17: coroa.xhtml
11
126
127
N AVEGAO
http://localhost:8080/Navegacao/cara-ou-coroa.xhtml
Exerccios Complementares
Considere uma aplicao em que o usurio pode escolher entre acessar uma verso simples
ou avanada da aplicao. O usurio pode alterar essa preferncia em uma pgina especfica da
aplicao. Crie uma aplicao web que tenha trs pginas. Uma das pginas deve permitir que o
usurio altere suas preferncias. As outras duas devem ser a pgina principal da aplicao, sendo
uma para a verso simples e outra para a verso avanada. Cada uma das pginas deve ter um menu
para que o usurio possa navegar entre a pgina principal e a pgina de configuraes. O link para a
pgina principal deve levar em considerao a preferncia do usurio. Use navegao implcita.
1
Dica: Para armazenar a preferncia do usurio, voc pode usar um managed bean. Anote a classe
que implementar esse managed bean com @SessionScoped para que a preferncia do usurio seja
mantida entre uma requisio e outra da aplicao.
2
www.k19.com.br
127
N AVEGAO
128
128
www.k19.com.br
CAPTULO
E SCOPOS
Request
No escopo request, as instncias dos managed beans so criadas durante o processamento de
uma requisio assim que forem necessrias e descartadas no final desse mesmo processamento.
Assim, os dados no so mantidos de uma requisio para outra.
A partir do JSF 2, os managed beans podem ser registrados atravs da anotao @ManagedBean.
O JSF utiliza o escopo request como padro quando managed beans so registrados usando essa
anotao. Mesmo sendo o padro, podemos deixar explcito a escolha do escopo request atravs da
anotao @RequestScoped.
1
2
3
4
5
6
7
Por outro lado, se o managed bean for registrado da maneira tradicional, no arquivo faces-config.xml, a escolha de um escopo obrigatria e realizada atravs da tag managed-bean-scope.
1
2
3
4
5
6
7
...
< managed - bean >
< managed - bean - name > testeBean </ managed - bean - name >
< managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
< managed - bean - scope > request </ managed - bean - scope >
</ managed - bean >
...
Cdigo XML 9.1: faces-config.xml
www.k19.com.br
129
E SCOPOS
130
Navegador
Aplicao
Requisio HTTP
Resposta HTTP
Cria
MB
MB
Mata
JSF
View
O escopo view foi adicionado no JSF 2. A ideia manter determinados dados enquanto o usurio
no mudar de tela. As instncia dos managed beans em escopo view so eliminadas somente quando
h uma navegao entre telas.
Analogamente, para escolher o escopo view, devemos utilizar a anotao @ViewScoped ou a tag
managed-bean-scope.
1
2
3
4
5
6
7
1
2
3
4
5
6
7
...
< managed - bean >
< managed - bean - name > testeBean </ managed - bean - name >
< managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
< managed - bean - scope > view </ managed - bean - scope >
</ managed - bean >
...
130
www.k19.com.br
131
E SCOPOS
Navegador
Aplicao
index.xhtml
Requisio HTTP
MB
ia
Cr
Resposta HTTP
index.xhtml
Requisio HTTP
JSF
Resposta HTTP
produtos.xhtml
Requisio HTTP
Resposta HTTP
a
at
MB
Session
Certas informaes devem ser mantidas entre as requisies de um determinado usurio em um
determinado navegador. Por exemplo, considere uma aplicao que utiliza carrinho de compras.
Um usurio faz diversas requisies para escolher os produtos e coloc-los no seu carrinho. Durante
todo esse tempo, a aplicao deve manter a informao de quais produtos j foram escolhidos por
esse usurio.
Da surge o escopo session. Cada usurio possui um espao na memria do servidor que chamado de session. Tecnicamente, possvel existir duas ou mais sessions de um mesmo usurio, por
exemplo, se ele estiver utilizando dois ou mais navegadores.
As instncias dos managed beans configurados com o escopo session so criadas quando necessrias durante o processamento de uma requisio e armazenadas na session do usurio que fez a
requisio.
Essas instncias so eliminadas basicamente em duas situaes: a prpria aplicao decide por
algum motivo especfico apagar a session de um usurio (por exemplo, quando o usurio faz logout)
ou o servidor decide apagar a session de um usurio quando esse usurio no faz requisies por um
determinado perodo de tempo. Esse tempo pode ser configurado com o Web Container.
Para escolher o escopo session, devemos utilizar a anotao @SessionScoped ou a tag mana-
ged-bean-scope.
1
2
3
4
5
www.k19.com.br
131
E SCOPOS
6
7
132
...
}
Cdigo Java 9.3: TesteBean.java
1
2
3
4
5
6
7
...
< managed - bean >
< managed - bean - name > testeBean </ managed - bean - name >
< managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
< managed - bean - scope > session </ managed - bean - scope >
</ managed - bean >
...
Cdigo XML 9.3: faces-config.xml
Temos que tomar um cuidado maior ao utilizar o escopo session, pois podemos acabar sobrecarregando o servidor. Portanto, a dica evitar utilizar o escopo session quando possvel. Para no
consumir excessivamente os recursos de memria do servidor, o escopo request mais apropriado.
Navegador
Aplicao
index.xhtml
Requisio HTTP
MB
a
Cri
Resposta HTTP
produtos.xhtml
Requisio HTTP
Resposta HTTP
usuario.xhtml
Requisio HTTP
Resposta HTTP
JSF
at
a
30 minutos
depois
MB
132
www.k19.com.br
133
E SCOPOS
Application
As instncias dos managed beans configurados com escopo application so criadas no primeiro
momento em que elas so utilizadas e mantidas at a aplicao ser finalizada.
Ao contrrio do que ocorre com escopos discutidos anteriormente, as instncias dos managed
beans registrados com escopo application so compartilhadas por todos os usurios da aplicao. O
JSF cria apenas uma instncia de cada managed bean em escopo de application.
Analogamente, para escolher o escopo application, devemos utilizar a anotao @ApplicationScoped ou a tag managed-bean-scope.
1
2
3
4
5
6
7
1
2
3
4
5
6
7
...
< managed - bean >
< managed - bean - name > testeBean </ managed - bean - name >
< managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
< managed - bean - scope > application </ managed - bean - scope >
</ managed - bean >
...
Cdigo XML 9.4: faces-config.xml
Mais Sobre
Por padro, a instncia de um managed bean em escopo application criada no momento em que ela usada pela primeira vez. Podemos alterar esse comportamento,
fazendo com que essa instncia seja criada quando a aplicao inicializada. Para isso, basta
acrescentar a propriedade eager com o valor true na anotao @ManagedBean. Veja o exemplo abaixo.
1
2
3
4
5
6
7
Exerccios de Fixao
www.k19.com.br
133
E SCOPOS
134
Crie um projeto do tipo Dynamic Web Project chamado K19-Escopos seguindo os passos vistos
no exerccio do Captulo 5.
1
Vamos criar uma pgina para adicionar carros e visualiz-los. Na pasta src, faa um pacote
chamado model.
2
No pacote model, crie uma classe chamada Carro para modelar os carros. Essa classe deve ter
dois atributos do tipo String: um para armazenar a marca e outro para guardar o modelo do carro.
3
1
2
3
4
5
6
7
8
package model ;
public class Carro {
private String marca ;
private String modelo ;
// GETTERS E SETTERS
}
Cdigo Java 9.6: Carro.java
5
No pacote managedbeans, crie uma classe chamada CarrosBean para armazenar uma lista de
carros.
1
2
3
4
5
6
7
8
package managedbeans ;
@ManagedBean
public class CarrosBean {
private List < Carro > carros = new ArrayList < Carro >() ;
// GETTER E SETTER
}
Cdigo Java 9.7: CarrosBean.java
Na classe CarrosBean, acrescente um atributo do tipo Carro para armazenar o carro a ser adicionado. Implemente tambm um mtodo chamado adicionaCarro() para inserir um novo carro na
lista.
6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package managedbeans ;
@ManagedBean
public class CarrosBean {
private List < Carro > carros = new ArrayList < Carro >() ;
private Carro carro = new Carro () ;
public void adicionaCarro () {
this . carros . add ( this . carro ) ;
this . carro = new Carro () ;
}
// GETTERS E SETTERS
}
Cdigo Java 9.8: CarrosBean.java
134
www.k19.com.br
135
E SCOPOS
Defina o escopo do managed bean carrosBean como sendo request. Para isso, use a anotao
@RequestScoped.
7
1
2
3
4
5
6
7
package managedbeans ;
@ManagedBean
@RequestScoped
public class CarrosBean {
...
}
Cdigo Java 9.9: CarrosBean.java
8
No diretrio WebContent, crie um arquivo XHTML chamado carros.xhtml. Implemente um
formulrio para adicionar um novo carro.
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 "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Marca : " for = " campo - marca " / >
<h : inputText value = " #{ carrosBean . carro . marca } " id = " campo - marca " / >
<h : outputLabel value = " Modelo : " for = " campo - modelo " / >
<h : inputText value = " #{ carrosBean . carro . modelo } " id = " campo - modelo " / >
<h : commandButton value = " Adicionar " action = " #{ carrosBean . adicionaCarro } " / >
</ h : panelGrid >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 9.1: carro.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
www.k19.com.br
135
E SCOPOS
21
22
23
24
25
26
27
28
29
30
31
32
33
34
136
<h : commandButton value = " Adicionar " action = " #{ carrosBean . adicionaCarro } " / >
</ h : panelGrid >
</ h : form >
<h : panelGroup rendered = " #{ not empty carrosBean . carros } " >
< h1 > Lista de carros : </ h1 >
< ul >
< ui : repeat value = " #{ carrosBean . carros } " var = " carro " >
< li > <h : outputText value = " #{ carro . marca } #{ carro . modelo } " / > </ li >
</ ui : repeat >
</ ul >
</ h : panelGroup >
</ h : body >
</ html >
Cdigo XHTML 9.2: carros.xhtml
10
http://localhost:8080/K19-Escopos/carros.xhtml
Adicione alguns carros e observe a lista de carros. O que acontece?
Mude o escopo do managed bean carrosBean de request para view. Para isso, use a anotao
@ViewScoped.
11
1
2
3
4
5
6
7
package managedbeans ;
@ManagedBean
@ViewScoped
public class CarrosBean {
...
}
Cdigo Java 9.10: CarrosBean.java
12
http://localhost:8080/K19-Escopos/carros.xhtml
Adicione alguns carros e observe a lista de carros. O que acontece?
No diretrio WebContent, crie um arquivo chamado menu.xhtml. Esse arquivo deve definir uma
pgina que possua um link para a pgina definida por carros.xhtml.
13
1
2
3
4
5
6
7
8
9
10
11
12
13
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : link value = " Adicionar carros " outcome = " carros " / >
</ h : body >
</ html >
Cdigo XHTML 9.3: menu.xhtml
14
136
137
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
E SCOPOS
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : link value = " Menu " outcome = " menu " / >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Marca : " for = " campo - marca " / >
<h : inputText value = " #{ carrosBean . carro . marca } " id = " campo - marca " / >
<h : outputLabel value = " Modelo : " for = " campo - modelo " / >
<h : inputText value = " #{ carrosBean . carro . modelo } " id = " campo - modelo " / >
<h : commandButton value = " Adicionar " action = " #{ carrosBean . adicionaCarro } " / >
</ h : panelGrid >
</ h : form >
<h : panelGroup rendered = " #{ not empty carrosBean . carros } " >
< h1 > Lista de carros : </ h1 >
< ul >
< ui : repeat value = " #{ carrosBean . carros } " var = " carro " >
< li > <h : outputText value = " #{ carro . marca } #{ carro . modelo } " / > </ li >
</ ui : repeat >
</ ul >
</ h : panelGroup >
</ h : body >
</ html >
Cdigo XHTML 9.4: carros.xhtml
15
http://localhost:8080/K19-Escopos/carros.xhtml
Certifique-se de que o escopo do managed bean carrosBean seja view. Mais uma vez, adicione
alguns carros e observe a lista de carros. Use os links criados para navegar entre as pginas definidas
por carros.xhtml e menu.xhtml. O que acontece?
Mude o escopo do managed bean carrosBean de view para session. Para isso, use a anotao
@SessionScoped.
16
1
2
3
4
5
6
7
package managedbeans ;
@ManagedBean
@SessionScoped
public class CarrosBean {
...
}
Cdigo Java 9.11: CarrosBean.java
17
http://localhost:8080/K19-Escopos/carros.xhtml
www.k19.com.br
137
E SCOPOS
138
Novamente, adicione alguns carros e observe a lista de carros. Use os links que voc criou para
navegar entre as pginas definidas por carros.xhtml e menu.xhtml. O que acontece?
Agora, acesse a aplicao a partir de navegadores diferentes. Adicione alguns carros a partir dos
diferentes navegadores. O que voc observa?
18
Mude o escopo do managed bean carrosBean de session para application. Para isso, use a
anotao @ApplicationScoped.
19
1
2
3
4
5
6
7
package managedbeans ;
@ManagedBean
@ApplicationScoped
public class CarrosBean {
...
}
Cdigo Java 9.12: CarrosBean.java
20
138
Novamente, usando navegadores diferentes, adicione alguns carros. O que voc pode observar?
www.k19.com.br
CAPTULO
C ONVERSO E VALIDAO
10
Converso
Quando um usurio preenche um formulrio, os valores preenchidos so enviados para uma
aplicao. De acordo com o HTTP, protocolo de comunicao utilizado entre os navegadores e as
aplicaes web, esses dados no possuem tipagem. Eles so tratados como texto puro. Dessa forma,
quando uma aplicao recebe valores preenchidos em formulrios HTML, ela precisa realizar a converso dos dados que deseja tratar de forma especfica.
Por exemplo, considere um formulrio que possui um campo para os usurios digitarem a sua
idade. A informao digitada nesse campo tratada como texto puro at chegar na aplicao, que
deve converter esse dado para algum tipo adequado do Java como int ou long.
Eventualmente, os dados que so enviados para a aplicao no podem ser convertidos, pois
no esto no formato esperado. Por exemplo, se o texto preenchido em um campo numrico possui
caracteres no numricos, a converso falhar.
Podemos observar o processo de converso de outro ponto de vista. Nem sempre o formato das
informaes que esto em uma aplicao web Java corresponde ao formato que desejamos que seja
apresentado aos usurios. Novamente, os dados devem ser convertidos antes de serem enviados
para os navegadores.
Felizmente, o JSF oferece um mecanismo automatizado de converso de dados. Veremos a seguir
o funcionamento desse mecanismo.
Conversores Padro
Para facilitar o trabalho de desenvolvimento de uma aplicao, o JSF define um conjunto de conversores padro. Alguns desses conversores so aplicados automaticamente. Outros conversores so
aplicados apenas se forem explicitamente indicados.
O JSF aplica automaticamente conversores padro para os seguintes tipos fundamentais do Java:
BigDecimal
BigInteger
Boolean e boolean
Byte e byte
Character e char
Double e double
www.k19.com.br
139
C ONVERSO E VALIDAO
140
Float e float
Integer e int
Long e long
Short e short
No exemplo abaixo, o contedo digitado na caixa de texto ser convertido para o tipo double
automaticamente, pois a propriedade numero do tipo double.
1
2
3
4
5
6
7
@ManagedBean
public class TesteBean {
private double numero ;
// GETTERS E SETTERS
}
Cdigo Java 10.1: TesteBean.java
1
2
<! -- O valor digitado nesse campo ser convertido para double -- >
<h : inputText value = " #{ testeBean . numero } " / >
Cdigo XHTML 10.1: Caixa de texto vinculada propriedade numero
<f:convertNumber>
A tag <f:convertNumber> permite que converses mais sofisticadas sejam feitas em valores numricos.
Para estipular que um valor numrico seja exibido com um nmero mximo de casas decimais,
podemos usar o atributo maxFractionDigits da tag <f:convertNumber>. No exemplo abaixo, a
propriedade numero do managed bean testeBean exibida com no mximo duas casas decimais.
1
2
3
Analogamente, podemos definir o nmero mnimo de casas decimais com o atributo minFractionDigits.
Podemos tambm definir a formatao de um nmero por meio de uma espcie de expresso
regular. Isso pode ser feito usando o atributo pattern, como no exemplo abaixo.
1
2
140
www.k19.com.br
141
3
C ONVERSO E VALIDAO
</ h : outputText >
Para apresentar dados na forma de porcentagem, podemos usar o atributo type e defini-lo com
o valor percent.
1
2
3
<f:convertDateTime>
A tag <f:convertDateTime> permite que converses de datas sejam realizadas. Esse conversor
pode ser aplicado em dados do tipo java.util.Date e java.sql.Date. Essa tag possui o atributo
pattern, que permite a definio do formato da data que desejamos utilizar.
1
2
3
Para mais detalhes sobre o uso do atributo pattern, consulte a pgina http://docs.oracle.
com/javase/7/docs/api/java/text/SimpleDateFormat.html.
Uma outra maneira de escolher o formato de data a ser utilizado por meio do atributo locale.
No exemplo abaixo, ao definir o valor do atributo locale como pt_BR, o padro de data utilizado
ser dd/MM/yyyy.
1
2
3
Exerccios de Fixao
1
Crie um projeto do tipo Dynamic Web Project chamado K19-Conversao-e-Validacao seguindo
os passos vistos no exerccio do Captulo 5.
2
Crie uma classe chamada Funcionario para modelar funcionrios e adicione-a ao pacote model.
www.k19.com.br
141
C ONVERSO E VALIDAO
1
2
3
4
5
6
7
8
9
142
package model ;
public class Funcionario {
private Double salario ;
private Integer codigo ;
private Date aniversario ;
// GETTERS E SETTERS
}
Cdigo Java 10.2: Funcionario.java
Acrescente um pacote na pasta src chamado managedbeans e adicione a seguinte classe a esse
pacote:
4
1
2
3
4
5
6
7
8
package managedbeans ;
@ManagedBean
public class FuncionarioBean {
private Funcionario funcionario = new Funcionario () ;
// GETTER E SETTER
}
Cdigo Java 10.3: FuncionarioBean.java
Crie uma tela para cadastrar funcionrios. Adicione um arquivo chamado cadastro.xhtml na
pasta WebContent.
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
31
32
33
34
35
36
142
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Cadastro de Funcionrio </ h1 >
<h : form >
<h : panelGrid columns = " 3 " >
<h : outputLabel value = " Salrio : R$ " for = " campo - salario " / >
<h : inputText id = " campo - salario " value = " #{ funcionarioBean . funcionario . salario } " >
<f : convertNumber locale = " pt_BR " / >
</ h : inputText >
<h : message for = " campo - salario " / >
<h : outputLabel value = " Cdigo : " for = " campo - codigo " / >
<h : inputText id = " campo - codigo " value = " #{ funcionarioBean . funcionario . codigo } " / >
<h : message for = " campo - codigo " / >
<h : outputLabel value = " Data : ( dd / MM / yyyy ) " for = " campo - aniversario " / >
<h : inputText id = " campo - aniversario "
value = " #{ funcionarioBean . funcionario . aniversario } " >
<f : convertDateTime pattern = " dd / MM / yyyy " / >
</ h : inputText >
<h : message for = " campo - aniversario " / >
<h : commandButton value = " Cadastrar " / >
</ h : panelGrid >
<h : messages / >
</ h : form >
</ h : body >
www.k19.com.br
143
37
C ONVERSO E VALIDAO
</ html >
Cdigo XHTML 10.8: cadastro.xhtml
http://localhost:8080/K19-Conversao-e-Validacao/cadastro.xhtml
Preencha o formulrio com valores inadequados diversas vezes e observe as mensagens de erros.
Exerccios Complementares
Crie um formulrio para registrar a cotao do dlar. Esse formulrio deve ter trs campos
obrigatrios. No primeiro, o usurio deve digitar o valor do dlar em reais. Esse campo deve estar
associado a um conversor de nmeros cujo tipo seja a moeda brasileira (use os atributos locale e
type da tag <f:convertNumber>). O segundo campo deve guardar a variao do dlar, em porcentagem, com no mximo cinco dgitos na parte fracionria. No terceiro campo, o usurio deve colocar
o horrio e a data da cotao, cujo formato deve ser HH:mm dd-MM-yyyy.
1
Mensagens de Erro
Eventualmente, as informaes preenchidas pelos usurios em formulrios no so adequadas,
impedindo a converso dos dados. Nesses casos, geralmente, desejamos apresentar mensagens relacionadas aos erros no preenchimento das informaes.
<h:message>
Para exibir erros relacionados a um determinado campo, podemos utilizar o componente <h:message>. Esse componente deve ser associado ao campo correspondente aos erros que desejamos
exibir. Para estabelecer essa ligao, devemos definir o valor do atributo for do componente <h:message> igual ao valor do atributo id do campo em questo.
1
2
3
4
5
6
7
@ManagedBean
public class TesteBean {
private Double numero ;
// GETTERS E SETTERS
}
Cdigo Java 10.6: TesteBean.java
1
2
<h : inputText value = " #{ testeBean . numero } " id = " campo - numero " / >
<h : message for = " campo - numero " / >
Cdigo XHTML 10.11: Exibindo mensagens de erro relacionadas a um campo de texto
www.k19.com.br
143
C ONVERSO E VALIDAO
144
As imagens abaixo exibem o campo de texto com o valor digitado pelo usurio e aps o processamento da requisio.
K19 Treinamentos
Enviar
Figura 10.1: Campo de texto associado a uma propriedade numrica de um managed bean
K19 Treinamentos
Mais Sobre
Os textos padro das mensagens de erro so definidos no resource bundle
javax.faces.Messages.
Mais Sobre
Cada mensagem de erro possui duas verses: uma detalhada e outra resumida. Por padro, apenas a mensagem detalhada exibida quando a tag <h:message> aplicada.
Para modificar esse comportamento, podemos alterar os valores dos atributos showSummary e
showDetail. O primeiro atributo indica se a mensagem resumida deve ser apresentada, enquanto o segundo indica se a mensagem detalhada deve ser exibida. Esses atributos devem assumir valores true ou false. Veja o exemplo abaixo.
1
2
<h : inputText value = " #{ testeBean . numero } " id = " campo - numero " / >
<h : message for = " campo - numero " showSummary = " true " showDetail = " false " / >
Cdigo XHTML 10.12: Definindo o tipo de mensagem de erro a ser apresentada
Note que as mensagens detalhada e resumida podem ser exibidas ao mesmo tempo. Para isso,
basta que esses dois atributos possuam o valor true.
<h:messages>
Como vimos, a tag <h:message> permite que os erros relacionados a um determinado campo
sejam exibidos. Para exibir os erros de todos os campos, podemos incluir uma tag <h:message> para
cada campo. Entretanto, podemos fazer o mesmo de uma forma mais prtica. A tag <h:messages>
exibe todas as mensagens.
1
144
www.k19.com.br
145
C ONVERSO E VALIDAO
javax . faces . converter . BooleanConverter . BOOLEAN ={1} : {0} must be true or false .
Cdigo XML 10.1: Exemplo de arquivo de mensagens
...
< application >
< message - bundle > resources . Messages </ message - bundle >
</ application >
...
Cdigo XML 10.2: faces-config.xml
Mais Sobre
Suponha que uma aplicao tenha um arquivo de mensagens registrado no
www.k19.com.br
145
C ONVERSO E VALIDAO
146
Mais Sobre
Podemos definir, de maneira especfica, a mensagem que deve ser utilizada quando
um erro de converso ocorrer em um determinado campo. Para isso, basta utilizar o
atributo converterMessage. Observe o seguinte exemplo.
1
2
3
<h : inputText value = " #{ testeBean . numero } " id = " campo - numero "
converterMessage = " Por favor , digite um nmero " / >
<h : message for = " campo - numero " / >
Cdigo XHTML 10.14: Definindo uma mensagem para um erro de converso
Exerccios de Fixao
No projeto K19-Conversao-e-Validacao, faa um pacote chamado resources na pasta src.
Adicione a esse pacote um arquivo de mensagens chamado Messages.properties com o seguinte
contedo.
7
1
2
3
4
5
6
1
2
3
4
5
...
< application >
< message - bundle > resources . Messages </ message - bundle >
</ application >
...
Cdigo XML 10.4: faces-config.xml
Preencha o formulrio vrias vezes com valores inadequados e observe as novas mensagens.
Validao
146
www.k19.com.br
147
C ONVERSO E VALIDAO
Como vimos, um dado enviado atravs de uma requisio HTTP chega na aplicao no formato
de texto. O processo de converso consiste em transformar esse texto em algum tipo especfico do
Java. Aps a converso, podemos verificar se os valores obtidos respeitam determinadas restries
impostas pelas regras da aplicao.
Por exemplo, considere um campo para o usurio digitar sua idade. Como discutido anteriormente, o valor digitado ser tratado como texto at chegar na aplicao. Em seguida, esse dado ser
convertido para um tipo numrico do Java (como int ou long por exemplo).
Obviamente, a idade de um usurio deve ser um valor no-negativo. Contudo, essa condio no
verificada na etapa de converso. Dessa forma, depois da converso dos dados, mais uma etapa
necessria para que essa verificao seja realizada. Essa etapa conhecida como validao.
Validadores Padro
Novamente, para facilitar o trabalho de desenvolvimento de uma aplicao, o JSF define um conjunto de validadores padro. A seguir, veremos alguns detalhes sobre esses validadores.
<h : inputText value = " #{ testeBean . nome } " id = " campo - nome " required = " true " / >
<h : message for = " campo - nome " / >
Cdigo XHTML 10.15: Campo de texto obrigatrio
Uma outra forma de registrar um validador desse tipo por meio da tag <f:validateRequired>,
conforme o exemplo abaixo.
1
2
3
4
<h : inputText value = " #{ testeBean . nome } " id = " campo - nome " >
<f : validateRequired / >
</ h : inputText >
<h : message for = " campo - nome " / >
Cdigo XHTML 10.16: Outra forma de exigir que um campo seja obrigatrio
<f:validateLongRange>
O validador <f:validateLongRange> utilizado para verificar se um valor numrico inteiro pertence a um determinado intervalo de nmeros. No exemplo abaixo, o validador ir verificar se o valor
da propriedade idade est entre 10 e 130.
1
2
3
4
<h : inputText value = " #{ testeBean . idade } " id = " campo - idade " >
<f : validateLongRange minimum = " 10 " maximum = " 130 " / >
</ h : inputText >
<h : message for = " campo - idade " / >
www.k19.com.br
147
C ONVERSO E VALIDAO
148
Cdigo XHTML 10.17: A propriedade idade deve receber um nmero entre 10 e 130
<f:validateDoubleRange>
O validador <f:validateDoubleRange> funciona de forma anloga ao <f:validateLongRange>.
Ele utilizado para verificar se um valor numrico real pertence a um determinado intervalo de
nmeros. No exemplo abaixo, o validador verificar se o valor da propriedade preco do managed
bean testeBean est entre 20.57 e 200.56.
1
2
3
4
<h : inputText value = " #{ testeBean . preco } " id = " campo - preco " >
<f : validateDoubleRange minimum = " 20.57 " maximum = " 200.56 " / >
</ h : inputText >
<h : message for = " campo - preco " / >
Cdigo XHTML 10.18: A propriedade preco deve receber um nmero entre 20.57 e 200.56
<f:validateLength>
O validador <f:validateLength> verifica se uma string possui uma quantidade mnima ou mxima de caracteres. Veja o exemplo abaixo.
1
2
3
4
<h : inputText value = " #{ testeBean . nome } " id = " campo - nome " >
<f : validateLength minimum = " 6 " maximum = " 20 " / >
</ h : inputText >
<h : message for = " campo - nome " / >
Cdigo XHTML 10.19: Restrio no nmero de caracteres da propriedade nome
Nesse exemplo, a restrio imposta a de que a propriedade nome do managed bean testeBean
seja uma string com pelo menos 6 e no mximo 20 caracteres.
<f:validateRegex>
O validador <f:validateRegex> usado para verificar se um texto respeita uma determinada expresso regular. No exemplo abaixo, o validador verificar se a propriedade codigo tem pelo menos
6 e no mximo 20 caracteres, alm de ser formada apenas por letras.
1
2
3
4
<h : inputText value = " #{ testeBean . codigo } " id = " campo - codigo " >
<f : validateRegex pattern = " [a - zA - Z ]{6 ,20} " / >
</ h : inputText >
<h : message for = " campo - codigo " / >
Cdigo XHTML 10.20: Expresso regular para restringir o dado de entrada de um campo de texto
Exerccios de Fixao
148
www.k19.com.br
149
C ONVERSO E VALIDAO
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Cadastro de Funcionrio </ h1 >
<h : form >
<h : panelGrid columns = " 3 " >
<h : outputLabel value = " Salrio : R$ " for = " campo - salario " / >
<h : inputText id = " campo - salario " value = " #{ funcionarioBean . funcionario . salario } "
required = " true " >
<f : convertNumber locale = " pt_BR " / >
<f : validateDoubleRange minimum = " 0 " / >
</ h : inputText >
<h : message for = " campo - salario " / >
<h : outputLabel value = " Cdigo : " for = " campo - codigo " / >
<h : inputText id = " campo - codigo " value = " #{ funcionarioBean . funcionario . codigo } "
required = " true " >
<f : validateLongRange minimum = " 5 " maximum = " 19 " / >
</ h : inputText >
<h : message for = " campo - codigo " / >
<h : outputLabel value = " Data : ( dd / MM / yyyy ) " for = " campo - aniversario " / >
<h : inputText id = " campo - aniversario "
value = " #{ funcionarioBean . funcionario . aniversario } "
required = " true " >
<f : convertDateTime pattern = " dd / MM / yyyy " / >
</ h : inputText >
<h : message for = " campo - aniversario " / >
<h : commandButton value = " Cadastrar " / >
</ h : panelGrid >
<h : messages / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 10.21: cadastro.xhtml
11
http://localhost:8080/K19-Conversao-e-Validacao/cadastro.xhtml
Teste o formulrio com diversos valores e observe o que acontece.
www.k19.com.br
149
C ONVERSO E VALIDAO
150
Exerccios Complementares
Crie um formulrio para o cadastro de produtos. Um produto tem quatro atributos: nome,
cdigo, tamanho e volume. O nome deve ser formado apenas por letras e espaos. O cdigo deve
ter pelo menos quatro e no mximo dez caracteres. O primeiro caractere desse cdigo deve ser uma
letra maiscula e os demais devem ser nmeros. O tamanho deve ser um nmero inteiro entre 1 e
32. O volume deve ser um nmero real maior ou igual a 0.1. Todos os campos do formulrio devem
ser obrigatrios.
3
Bean Validation
Uma nova abordagem para definir validaes foi adicionada no JSF 2. A ideia declarar as regras
de validao nas classes do modelo ao invs de inseri-las nos arquivos XHTML que definem as telas.
A grande vantagem das validaes definidas nas classes do modelo que elas podem ser utilizadas
em diversas partes da aplicao. Esse novo recurso chamado Bean Validation e foi definido pela
especificao JSR 303, que pode ser obtida atravs da url http://jcp.org/en/jsr/detail?id=303.
Para definir as validaes com bean validation, basta adicionar anotaes nas classes do modelo.
No cdigo abaixo, o atributo nome foi marcado com a anotao @NotNull. Com essa anotao, o JSF
verificar se o valor do atributo nome no nulo.
1
2
3
4
5
Mais Sobre
Considere uma caixa de texto vinculada a uma propriedade do tipo String. Por padro,
quando essa caixa no preenchida, o JSF considera o seu contedo como sendo a
string vazia () e no como o valor null. Assim, a anotao @NotNull no pode ser utilizada
para obrigar que o usurio preencha essa caixa de texto.
Podemos alterar o comportamento padro do JSF fazendo com que ele considere o contedo de
uma caixa de texto no preenchida como null. Para isso, devemos acrescentar o seguinte trecho
no arquivo de configurao da aplicao web (web.xml).
1
2
3
4
5
6
7
8
...
< context - param >
< param - name >
javax . faces . INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
</ param - name >
< param - value > true </ param - value >
</ context - param >
...
Cdigo XML 10.5: web.xml
150
www.k19.com.br
151
C ONVERSO E VALIDAO
Mais Sobre
Para desabilitar bean validations em um componente particular de um formulrio, podemos usar a tag <f:validateBean>. Isso pode ser feito atribuindo o valor true ao
atributo disabled dessa tag. Considere o seguinte managed bean.
1
2
3
4
5
6
www.k19.com.br
151
C ONVERSO E VALIDAO
152
No exemplo abaixo, a validao introduzida pela anotao @NotNull do atributo nome da classe
Funcionario desabilitada.
1
2
3
No exemplo acima, a mensagem de erro de validao est definida de maneira fixa. Pode ser mais
apropriado defini-la em um arquivo de mensagens. Nesse caso, devemos criar um arquivo chamado
ValidationMessages.properties no classpath da aplicao. No exemplo abaixo, a mensagem O
nome do funcionrio no pode ser nulo est associada chave br.com.k19.Funcionario.nome.
1
Finalmente, devemos definir o valor do atributo message com a chave associada mensagem que
desejamos exibir. O identificador da mensagem deve estar entre chaves, como mostrado a seguir.
1
2
3
4
5
A mensagem O nome do funcionrio no pode ser nulo especfica para o caso acima. Agora,
suponha que desejamos criar uma mensagem comum associada ao validador @NotNull. Como o valor padro da propriedade message desse validador "{javax.validation.constraints.NotNull.message}", basta definir uma mensagem com essa chave no arquivo ValidationMessages.properties.
1
152
www.k19.com.br
153
C ONVERSO E VALIDAO
Podemos tambm alterar as mensagens dos demais validadores do bean validation. As chaves
das mensagens associadas a esses validadores so listadas abaixo:
@AssertFalse: "{javax.validation.constraints.AssertFalse.message}"
@AssertTrue: "{javax.validation.constraints.AssertTrue.message}"
@DecimalMax: "{javax.validation.constraints.DecimalMax.message}"
@DecimalMin: "{javax.validation.constraints.DecimalMin.message}"
@Digits: "{javax.validation.constraints.Digits.message}"
@Future: "{javax.validation.constraints.Future.message}"
@Max: "{javax.validation.constraints.Max.message}"
@Min: "{javax.validation.constraints.Min.message}"
@Null: "{javax.validation.constraints.Null.message}"
@Past: "{javax.validation.constraints.Past.message}"
@Pattern: "{javax.validation.constraints.Pattern.message}"
@Size: "{javax.validation.constraints.Size.message}"
Exerccios de Fixao
12
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
www.k19.com.br
153
C ONVERSO E VALIDAO
31
32
33
34
35
154
13 Usando bean validation, modifique a classe Funcionario para considerar as restries do exerccio anterior, isto :
package model ;
public class Funcionario {
@NotNull
@Min ( value = 0)
private Double salario ;
@NotNull
@Min ( value = 5)
@Max ( value = 19)
private Integer codigo ;
@NotNull
private Date aniversario ;
// GETTERS E SETTERS
}
Cdigo Java 10.13: Funcionario.java
14
http://localhost:8080/K19-Conversao-e-Validacao/cadastro.xhtml
Teste o formulrio com diversos valores e observe o que acontece.
154
www.k19.com.br
155
C ONVERSO E VALIDAO
Um nmero de telefone divido em trs partes: o cdigo do pas, o cdigo da rea e o nmero
local. A interface da nossa aplicao utilizar o seguinte formato para apresentar ou receber nmeros
de telefone:
CodigoDoPais
CodigoDeArea
NumeroLocal
As trs partes so separadas por espaos. Tanto o cdigo do pas quanto o cdigo de rea so
formados apenas por dgitos. O nmero local, por outro lado, formado por dgitos e, opcionalmente, por hifens. No exemplo abaixo, o nmero de telefone da K19 mostrado nesse formato. Veja
abaixo alguns exemplos de como o nmero de telefone da K19 poderia ser apresentado seguindo
esse formato.
55 11 2387-3791
55 11 23873791
55 11 23-87-37-91
Para automatizar o processo de transformao das strings digitadas pelos usurios em objetos da
classe Telefone e vice-e-versa, podemos implementar um conversor JSF.
O primeiro passo para implementar um conversor JSF criar uma classe que implementa a interface javax.faces.convert.Converter. Nessa classe, devemos adicionar a anotao @FacesConverter para indicar a classe associada a esse conversor, como no cdigo abaixo.
1
2
3
4
A interface Converter exige a implementao de dois mtodos: getAsObject() e getAsString(). O primeiro mtodo deve transformar um objeto do tipo String em um objeto Java (em nosso
caso, um objeto do tipo Telefone). J o mtodo getAsString() deve converter um objeto Java em
um objeto do tipo String (em nosso caso, criar uma String a partir de um Telefone).
Uma possvel implementao para o conversor de nmeros de telefone apresentada a seguir.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
www.k19.com.br
155
C ONVERSO E VALIDAO
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
156
Exerccios de Fixao
Considere um formulrio que possua uma caixa de texto para receber um nmero de CPF (Cadastro de Pessoas Fsicas). Um nmero de CPF dividido em duas partes. A primeira parte do nmero formada por nove dgitos. Chamaremos essa parte de nmero de identificao. A segunda
parte formada por dois dgitos, que so chamados de dgitos verificadores. Esses dois ltimos dgitos so usados para verificar o nmero de identificao e prevenir erros. Um nmero de CPF
apresentado com a primeira parte separada da segunda por um hfen.
15
1
2
3
4
5
6
7
8
9
package model ;
public class CPF {
private int numeroDeIdentificacao ;
private int primeiroDigitoVerificador ;
private int segundoDigitoVerificador ;
// GETTERS E SETTERS
}
Cdigo Java 10.17: CPF.java
17
Agora, dentro do pacote converters, crie uma classe chamada ConversorDeCPF para implementar o conversor de nmeros de CPF. Um nmero de CPF deve respeitar o seguinte formato:
18
156
www.k19.com.br
157
C ONVERSO E VALIDAO
XXXXXXXXX-XX. Lembre que essa classe deve ser anotada com @FacesConverter e implementar a
interface javax.faces.convert.Converter.
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
package converters ;
@FacesConverter ( forClass = CPF . class )
public class ConversorDeCPF implements Converter {
@Override
public Object getAsObject ( FacesContext context , UIComponent component ,
String value ) {
value = value . trim () ;
if (! Pattern . matches ( " [0 -9]{9} -[0 -9]{2} " , value ) ) {
FacesMessage mensagem = new FacesMessage ( " Nmero de CPF invlido " ) ;
mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
throw new ConverterException ( mensagem ) ;
}
String partesDoCPF [] = value . split ( " -" ) ;
int numeroDeIdentificacao = Integer . parseInt ( partesDoCPF [0]) ;
int primeiroDigitoVerificador = Integer . parseInt ( partesDoCPF [1]. substring (0 , 1) ) ;
int segundoDigitoVerificador = Integer . parseInt ( partesDoCPF [1]. substring (1 , 2) ) ;
CPF cpf = new CPF () ;
cpf . setNumeroDeIdentificacao ( numeroDeIdentificacao ) ;
cpf . setPrimeiroDigitoVerificador ( primeiroDigitoVerificador ) ;
cpf . setSegundoDigitoVerificador ( segundoDigitoVerificador ) ;
return cpf ;
}
@Override
public String getAsString ( FacesContext context , UIComponent component ,
Object value ) {
CPF cpf = ( CPF ) value ;
return cpf . getNumeroDeIdentificacao () + " + " + cpf . getPrimeiroDigitoVerificador ()
+ cpf . getSegundoDigitoVerificador () ;
}
}
Cdigo Java 10.18: ConversorDeCPF.java
19
No pacote managedbeans, crie uma classe chamada CPFBean para implementar o managed bean
que dar suporte ao formulrio.
20
1
2
3
4
5
6
7
8
package managedbeans ;
@ManagedBean
public class CPFBean {
private CPF cpf ;
// GETTER E SETTER
}
Cdigo Java 10.19: CPFBean.java
1
2
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
www.k19.com.br
157
C ONVERSO E VALIDAO
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
158
< html xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Formulrio </ h1 >
<h : form >
<h : outputLabel value = " CPF : " for = " cpf " / >
<h : inputText id = " cpf " value = " #{ cPFBean . cpf } " / >
<h : commandButton value = " Enviar " / >
</ h : form >
<h : message for = " cpf " style = " color : red " / >
</ h : body >
</ html >
Cdigo XHTML 10.25: formulario.xhtml
22
http://localhost:8080/K19-Conversao-e-Validacao/formulario.xhtml
Teste o formulrio com diversos valores para campo de CPF. Observe as mensagens de erro de
converso para valores invlidos.
Exerccios Complementares
Em 2010, foi lanado um novo de documento de identificao no Brasil, o Registro de Identidade
Civil (RIC). Esse documento tem um nmero que identifica unicamente cada cidado. O nmero
RIC tem duas partes. A primeira parte formada por dez dgitos e a segunda, o dgito verificador,
formada por um nico dgito. A primeira parte opcionalmente separada da segunda por um
hfen. Primeiro, voc deve criar uma classe para modelar esse documento. Em seguida, voc deve
implementar um conversor para esse tipo de objeto. Por fim, voc deve implementar um formulrio
para testar o seu conversor.
4
www.k19.com.br
159
1
2
3
4
5
6
C ONVERSO E VALIDAO
package br . com . k19 ;
@FacesValidator ( " br . com . k19 . ValidadorDeNumerosPrimos " )
public class ValidadorDeNumerosPrimos implements Validator {
...
}
Cdigo Java 10.23: ValidadorDeNumerosPrimos.java
Uma forma simples de verificar se determinado nmero primo testar se ele divisvel por
algum nmero maior do que 1 e menor ou igual raiz quadrada desse nmero. Se ele for divisvel
por algum desses nmeros, ento ele no primo. Caso contrrio, ele um nmero primo. No
cdigo abaixo, apresentamos uma implementao para esse validador.
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
Se o nmero que estamos validando no for primo ento precisamos lanar uma exceo do
tipo javax.faces.validator.ValidatorException. Analogamente ao que fizemos na elaborao
de um conversor, lanamos uma exceo contendo uma FacesMessage com uma mensagem de erro.
Para associar um validador a um determinado campo de um formulrio, podemos usar a tag
<f:validator>. Essa tag possui um atributo chamado validatorId cujo valor deve ser igual ao valor
registrado na anotao @FacesValidator. Em nosso caso particular, esse valor "br.com.k19.ValidadorDeNumerosPrimos".
O cdigo XHTML abaixo define um formulrio com uma caixa de texto e vincula essa caixa ao
validador de nmeros primos.
1
2
3
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
www.k19.com.br
159
C ONVERSO E VALIDAO
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
160
< html xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : outputLabel value = " Digite um nmero primo : " for = " numero - primo " / >
<h : inputText value = " #{ testeBean . numeroPrimo } " id = " numero - primo " >
<f : validator validatorId = " br . com . k19 . ValidadorDeNumerosPrimos " / >
</ h : inputText >
<h : commandButton value = " Enviar " / >
< br / >
<h : message for = " numero - primo " style = " color : red " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 10.27: Associando um validador a uma propriedade
<h : inputText value = " #{ testeBean . data } " id = " campo - data " >
<f : attribute name = " inicio " value = " 01/05/2014 " / >
<f : attribute name = " fim " value = " 30/08/2014 " / >
</ h : inputText >
Cdigo XHTML 10.28: Adicionando atributos a um componente visual
Esses atributos podem ser recuperados no mtodo validade() do validador da seguinte forma:
1
2
3
4
5
6
7
@Override
public void validate ( FacesContext context , UIComponent component , Object value ) {
String inicio = ( String ) component . getAttributes () . get ( " inicio " ) ;
String fim = ( String ) component . getAttributes () . get ( " fim " ) ;
...
}
Cdigo Java 10.25: Recuperando atributos de um componente visual
160
www.k19.com.br
161
C ONVERSO E VALIDAO
Exerccios de Fixao
Agora, crie um validador de nmeros de CPF. Como dissemos no exerccio anterior, os dois
ltimos dgitos do CPF (dgitos verificadores) so usados para validar os demais dgitos (nmero de
identificao). Os dgitos verificadores so gerados por um algoritmo chamado Mdulo 11 a partir
do nmero de identificao.
23
O primeiro dgito verificador obtido da seguinte forma. Suponha que o nmero de identificao
seja x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 , onde x i representa o i -simo dgito da direita para a esquerda do nmero
de identificao. Seja y o valor dado por
y = 2x 1 + 3x 2 + 4x 3 + 5x 4 + 6x 5 + 7x 6 + 8x 7 + 9x 8 + 10x 9 .
Se o valor do resto da diviso de y por 11 (y%11 em Java) for menor do que 2, ento o primeiro dgito
verificador d 1 = 0. Caso contrrio, o primeiro dgito verificador d 1 igual a 11 menos o resto da
diviso de y por 11.
O segundo dgito verificador obtido de forma anloga, mas aplicando o algoritmo acima ao
nmero x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 d 1 . Nesse caso, o novo valor de y ser
y = 2d 1 + 3x 1 + 4x 2 + 5x 3 + 6x 4 + 7x 5 + 8x 6 + 9x 7 + 10x 8 + 11x 9 .
Crie um pacote chamado validators no diretrio src.
24 No pacote validators, crie uma classe chamada ValidadorDeCPF. Lembre que essa classe deve
ser anotada com @FacesValidator e implementar a interface javax.faces.validator.Validator.
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
package validators ;
@FacesValidator ( value = " br . com . k19 . validators . ValidadorDeCPF " )
public class ValidadorDeCPF implements Validator {
@Override
public void validate ( FacesContext context , UIComponent component ,
Object value ) throws ValidatorException {
CPF
int
int
int
www.k19.com.br
161
C ONVERSO E VALIDAO
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
162
25
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
26
http://localhost:8080/K19-Conversao-e-Validacao/formulario.xhtml
Submeta o formulrio com valores invlidos para o nmero de CPF e observe as mensagens de
erro de validao.
Exerccios Complementares
Considere um formulrio que possua um campo de texto para o usurio digitar uma data. Essa
data deve pertencer a um determinado intervalo. Implemente um validador que considere essa res5
162
www.k19.com.br
163
C ONVERSO E VALIDAO
trio. As datas que definem o intervalo devem ser passadas como parmetro para o validador com
o uso da tag <f:attribute>.
static
static
static
static
Note que a anotao @Primo vinculada ao validador definido pela classe ValidadorDePrimo.
Esse vnculo estabelecido atravs da propriedade validatedBy da anotao @Constraint.
Observe tambm que, de acordo com o cdigo acima, a mensagem definida pela chave br.com.k19.Primo.message ser utilizada por padro quando um erro for identificado na validao.
A classe que define o validador de nmeros primos deve implementar a interface javax.validation.ConstraintValidator. Essa interface possui dois mtodos: initialize() e isValid(). O
primeiro utilizado para extrair, se necessrio, os valores dos atributos da anotao. O segundo deve
implementar a validao propriamente dita.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
www.k19.com.br
163
C ONVERSO E VALIDAO
17
18
19
20
21
22
164
return false ;
}
}
return true ;
}
}
Cdigo Java 10.30: ValidadorDePrimo.java
Exerccios de Fixao
Seguindo o exerccio anterior, crie um bean validator para validar nmeros de CPF. Primeiro,
crie um pacote chamado beanvalidators no diretrio src.
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static
static
static
static
1
2
3
4
5
6
7
8
9
164
package beanvalidators ;
import javax . validation . ConstraintValidator ;
import javax . validation . ConstraintValidatorContext ;
public class CPFBeanValidator implements
ConstraintValidator < beanvalidators . CPF , model . CPF > {
@Override
www.k19.com.br
165
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
C ONVERSO E VALIDAO
public void initialize ( beanvalidators . CPF constraintAnnotation ) {
}
@Override
public boolean isValid ( model . CPF value , ConstraintValidatorContext context ) {
model . CPF cpf = ( model . CPF ) value ;
int numeroDeIdentificacao = cpf . getNumeroDeIdentificacao () ;
int primeiroDigitoVerificador = cpf . getPrimeiroDigitoVerificador () ;
int segundoDigitoVerificador = cpf . getSegundoDigitoVerificador () ;
return this . validaCPF ( numeroDeIdentificacao , primeiroDigitoVerificador ,
segundoDigitoVerificador ) ;
}
private boolean validaCPF ( int numeroDeIdentificacao ,
int primeiroDigitoVerificador , int segundoDigitoVerificador ) {
long primeiroDigito = this . modulo11 (( long ) numeroDeIdentificacao ) ;
long segundoDigito = this . modulo11 (( long ) numeroDeIdentificacao * 10
+ primeiroDigito ) ;
return primeiroDigitoVerificador == primeiroDigito
&& segundoDigitoVerificador == segundoDigito ;
}
private long modulo11 ( long numero ) {
long soma = 0;
long multiplicador = 2;
while ( numero > 0) {
long digito = numero % 10;
soma += multiplicador * digito ;
numero /= 10;
multiplicador ++;
}
long resto = soma % 11;
if ( resto < 2)
return 0;
else
return 11 - resto ;
}
}
Cdigo Java 10.32: CPFBeanValidator.java
Na classe CPFBean, adicione a anotao @CPF ao atributo cpf para usar o validador que voc
acabou de criar.
30
1
2
3
4
5
6
7
8
9
10
11
12
13
package managedbeans ;
import javax . faces . bean . ManagedBean ;
import model . CPF ;
@ManagedBean
public class CPFBean {
@beanvalidators . CPF
private CPF cpf ;
// GETTER E SETTER
}
Cdigo Java 10.33: CPFBean.java
31
Crie um formulrio com uma caixa de texto para digitar um nmero de CPF.
1
2
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
www.k19.com.br
165
C ONVERSO E VALIDAO
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
166
< html xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Formulrio </ h1 >
<h : form >
<h : outputLabel value = " CPF : " for = " cpf " / >
<h : inputText id = " cpf " value = " #{ cPFBean . cpf } " / >
<h : commandButton value = " Enviar " / >
</ h : form >
<h : message for = " cpf " style = " color : red " / >
</ h : body >
</ html >
Cdigo XHTML 10.32: formulario.xhtml
32
http://localhost:8080/K19-Conversao-e-Validacao/formulario.xhtml
166
www.k19.com.br
CAPTULO
E VENTOS
11
Aplicaes JSF so fortemente baseadas em eventos. Esses eventos podem ser gerados pelos
usurios da aplicao ou pelo prprio JSF. Veja abaixo alguns exemplos de eventos gerados pelos
usurios.
Um clique em um boto ou link.
A troca do valor preenchido em uma caixa de texto.
A troca da opo escolhida em uma caixa de seleo.
Veja abaixo alguns exemplos de eventos gerados pelo JSF.
Inicializao da aplicao.
Finalizao da aplicao.
Erro no processamento de uma requisio.
Um evento pode ser associado a procedimentos que sero executados quando esse evento ocorrer. No JSF, os eventos so divididos em trs categorias: FacesEvent, PhaseEvent e SystemEvent.
FacesEvent
H dois tipos de FacesEvents: ActionEvent e ValueChangeEvent. Apresentaremos a seguir o
funcionamento desses tipos de eventos.
ActionEvent
Um ActionEvent gerado quando um boto ou link pressionado pelo usurio. Mtodos de um
managed bean podem ser associados a esses eventos. Toda vez que um evento ocorrer os mtodos
associados a ele sero executados. Para associar mtodos de um managed bean a um ActionEvent,
podemos utilizar os atributos action ou actionListener dos componentes <h:commandButton> e
<h:commandLink>
O atributo action deve ser associado a um mtodo pblico do tipo void ou String de um managed bean. Se esse mtodo devolver uma String, ela ser utilizada para determinar a navegao
das pginas (veja Captulo 8). Conceitualmente, o atributo action deve ser associado a mtodos que
representam alguma regra de negcio da aplicao.
No exemplo abaixo, o boto Salva est associado ao mtodo salva() do managed bean produtoBean atravs do atributo action da tag <h:commandButton>. Esse mtodo implementa a lgica de
negcio para cadastrar produtos. A String lista-produtos devolvida pelo mtodo salva() ser
utilizada para determinar a navegao das pginas.
www.k19.com.br
167
E VENTOS
1
168
<h : commandButton value = " Salva " action = " #{ produtoBean . salva } " / >
Cdigo XHTML 11.1: Boto associado ao mtodo salva() do managed bean produtoBean
1
2
3
4
5
6
7
8
9
10
11
12
13
@ManagedBean
public class ProdutoBean {
private Produto produto = new Produto () ;
private List < Produto > produtos = new ArrayList < Produto >() ;
public String salva () {
this . produtos . add ( this . produto ) ;
this . produto = new Produto () ;
return " lista - produtos " ;
}
// GETTERS E SETTERS
}
Cdigo Java 11.1: ProdutoBean.java
O atributo actionListener, por sua vez, deve ser associado a um mtodo pblico do tipo void
que receba um ActionEvent como parmetro. Conceitualmente, o atributo actionListener deve
ser associado a mtodos que implementam alguma lgica associada interface do usurio.
No exemplo abaixo, o boto Clique Aqui est associado ao mtodo mudaTexto() do managed
bean cliqueBean atravs do atributo actionListener da tag <h:commandButton>. Esse mtodo altera o texto do boto para Clicado.
1
<h : commandButton value = " Clique Aqui " actionListener = " #{ cliqueBean . mudaTexto } " / >
Cdigo XHTML 11.2: Boto associado ao mtodo mudaTexto() do managed bean cliqueBean
1
2
3
4
5
6
7
@ManagedBean
public class CliqueBean {
public void mudaTexto ( ActionEvent e ) {
UICommand c = ( UICommand ) e . getComponent () ;
c . setValue ( " Clicado " ) ;
}
}
Cdigo Java 11.2: CliqueBean.java
Os atributos action e actionListener permitem que no mximo dois mtodos sejam associados a um evento de ao. Para associar mais do que dois mtodos a um evento de ao, podemos
usar a tag <f:actionListener>. O valor do atributo type dessa tag deve ser o nome de uma classe
que implemente a interface javax.faces.event.ActionListener. Essa interface exige a criao de
um mtodo chamado processAction(). Veja o exemplo abaixo.
1
2
3
<h : commandLink value = " Enviar " action = " ... " actionListener = " ... " >
<f : actionListener type = " br . com . k19 . MudaCorDaFonte " / >
</ h : commandLink >
Cdigo XHTML 11.3: Link associado ao mtodo processAction() da classe MudaCorDaFonte
1
2
3
4
5
168
www.k19.com.br
169
6
7
8
9
E VENTOS
UICommand c = ( UICommand ) e . getComponent () ;
c . getAttributes () . put ( " style " , " color : red ; " ) ;
}
}
Cdigo Java 11.3: MudaCorDaFonte.java
Nesse exemplo, usamos a tag <f:actionListener> para associar o link ao mtodo processAction() da classe br.com.k19.MudaCorDaFonte.
Importante
Os mtodos associados a um evento de ao so executados na seguinte ordem:
1. O mtodo associado com o atributo actionListener.
2. Mtodos associados com tag <f:actionListener> de acordo com a ordem em
que elas aparecem no arquivo XHTML.
3. O mtodo indicado pelo atributo action.
Importante
Por padro, os mtodos associados a eventos de ao so executados na fase Invoke
Application do processamento de uma requisio (veja o Captulo 5 para mais informaes).
ValueChangeEvent
Um ValueChangeEvent produzido quando o valor de uma caixa de texto ou a opo de uma
caixa de seleo so alterados. Podemos associar mtodos de um managed bean a esses eventos.
Tais mtodos devem receber um parmetro do tipo ValueChangeEvent e serem pblicos. Para estabelecer essa associao, podemos utilizar o atributo valueChangeListener das caixas de texto ou de
seleo ou a tag <f:valueChangeListener>.
Considere um formulrio usado para editar as informaes dos produtos de uma loja. No exemplo abaixo, associamos uma caixa de texto ao mtodo mudaPreco() do managed bean produtoBean
atravs do atributo valueChangeListener da tag <h:inputText>. Esse mtodo registra a mudana
do preo de um produto.
1
2
<h : outputLabel value = " Preo : " for = " preco " / >
<h : inputText valueChangeListener = " #{ produtoBean . mudaPreco } " id = " preco " / >
Cdigo XHTML 11.4: Caixa de texto associada ao mtodo mudaPreco() do managed bean produtoBean
1
2
3
4
5
6
@ManagedBean
public class ProdutoBean {
public void mudaPreco ( ValueChangeEvent e ) {
System . out . println ( " Preo antigo : " + e . getOldValue () ) ;
System . out . println ( " Preo novo : " + e . getNewValue () ) ;
}
www.k19.com.br
169
E VENTOS
7
170
}
Cdigo Java 11.4: ProdutoBean.java
O mesmo pode ser feito com o uso da tag <f:valueChangeListener>. No exemplo abaixo, criamos uma classe chamada RegistraAlteracao, que implementa a interface ValueChangeListener,
e associamos a caixa de texto ao mtodo processValueChange() dessa classe.
1
2
3
4
<h : outputLabel value = " Preo : " for = " preco " / >
<h : inputText id = " preco " >
<f : valueChangeListener type = " br . com . k19 . RegistraAlteracao " / >
</ h : inputText >
Cdigo XHTML 11.5: Caixa de texto associada ao mtodo processValueChange() da classe RegistraAlteracao
1
2
3
4
5
6
7
8
9
Importante
Os mtodos associados a um evento de mudana de valor so executados na seguinte
ordem:
1. O mtodo associado com o atributo valueChangeListener.
2. Mtodos associados com tag <f:valueChangeListener> na ordem em que elas aparecem no arquivo XHTML.
Importante
Os mtodos associados a eventos de mudana de valor so executados na fase Process
Validations do processamento de uma requisio. Veja o Captulo 5 para mais informaes sobre o processamento de uma requisio.
Exerccios de Fixao
Crie um projeto do tipo Dynamic Web Project chamado K19-Eventos seguindo os passos vistos
no exerccio do Captulo 5.
1
Criaremos uma pgina com trs botes. Um dos botes estar habilitado e os outros dois desabilitados. Quando o usurio pressionar o boto habilitado, a aplicao deve escolher aleatoriamente
qual dos trs botes estar habilitado da prxima vez e desabilitar os outros dois.
2
170
www.k19.com.br
171
E VENTOS
<! 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 > K19 - Eventos </ title >
</ h : head >
<h : body >
<h : form >
<h : commandButton
id = " botao - jonas "
value = " Jonas "
disabled = " false "
actionListener = " #{ botaoBean . sorteiaBotao } " / >
<h : commandButton
id = " botao - marcelo "
value = " Marcelo "
disabled = " true "
actionListener = " #{ botaoBean . sorteiaBotao } " / >
<h : commandButton
id = " botao - rafael "
value = " Rafael "
disabled = " true "
actionListener = " #{ botaoBean . sorteiaBotao } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 11.6: botoes.xhtml
Crie um managed bean para implementar o tratamento dos botes. Adicione em um pacote
chamado managedbeans a seguinte classe:
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@ManagedBean
public class BotaoBean {
public void sorteiaBotao ( ActionEvent event ) {
UIComponent formulario = event . getComponent () . getParent () ;
UIComponent botaoJonas = formulario . findComponent ( " botao - jonas " ) ;
UIComponent botaoMarcelo = formulario . findComponent ( " botao - marcelo " ) ;
UIComponent botaoRafael = formulario . findComponent ( " botao - rafael " ) ;
botaoJonas . getAttributes () . put ( " disabled " , true ) ;
botaoMarcelo . getAttributes () . put ( " disabled " , true ) ;
botaoRafael . getAttributes () . put ( " disabled " , true ) ;
double numero = Math . random () ;
if ( numero < 1.0/3.0) {
botaoJonas . getAttributes () . put ( " disabled " , false ) ;
} else if ( numero < 2.0/3.0) {
botaoMarcelo . getAttributes () . put ( " disabled " , false ) ;
} else {
botaoRafael . getAttributes () . put ( " disabled " , false ) ;
}
}
}
Cdigo Java 11.6: BotaoBean.java
www.k19.com.br
171
E VENTOS
4
172
http://localhost:8080/K19-Eventos/botoes.xhtml
PhaseEvent
Os PhaseEvents so eventos disparados automaticamente pelo JSF antes e depois de cada uma
das fases do processamento de uma requisio. Esses eventos so teis basicamente para monitorar
a execuo dessas fases.
Para tratar um PhaseEvent, podemos criar uma classe que implemente a interface javax.faces.event.PhaseListener. Alm disso, precisamos registrar essa classe no arquivo faces-config.xml. A interface PhaseListener obriga a implementao de trs mtodos: afterPhase(), beforePhase() e getPhaseId().
O mtodo getPhaseId() deve devolver a referncia de um objeto do tipo javax.faces.event.PhaseId, que indica em quais fases do processamento de uma requisio estamos interessados.
Se estivermos interessados nos eventos da fase Apply Request Values, por exemplo, podemos fazer
esse mtodo devolver PhaseId.APPLY_REQUEST_VALUES. Os valores que podem ser utilizados so:
PhaseId.RESTORE_VIEW
PhaseId.APPLY_REQUEST_VALUES
PhaseId.INVOKE_APPLICATION
PhaseId.PROCESS_VALIDATIONS
PhaseId.UPDATE_MODEL_VALUES
PhaseId.RENDER_RESPONSE
PhaseId.ANY_PHASE
O mtodo beforePhase() recebe a referncia de um PhaseEvent como parmetro e executado
antes das fases especificadas pelo mtodo getPhaseId(). O mtodo afterPhase() anlogo ao
beforePhase() e executado aps as fases especificadas pelo mtodo getPhaseId().
No exemplo abaixo, criamos a classe MonitorPhaseListener que implementa a interface PhaseListener. No mtodo getPhaseId(), devolvemos PhaseId.ANY_PHASE, que indica que estamos
interessados nos eventos relacionados a todas as fases.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
172
www.k19.com.br
173
17
18
19
20
21
E VENTOS
@Override
public PhaseId getPhaseId () {
return PhaseId . ANY_PHASE ;
}
}
Cdigo Java 11.7: MonitorPhaseListener.java
...
< lifecycle >
< phase - listener > br . com . k19 . MonitorPhaseListener </ phase - listener >
</ lifecycle >
...
Cdigo XML 11.1: faces-config.xml
Exerccios de Fixao
5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1
2
3
4
5
...
< lifecycle >
< phase - listener > phaselisteners . MonitorPhaseListener </ phase - listener >
</ lifecycle >
...
Cdigo XML 11.2: faces-config.xml
Acesse a pgina botoes.xhtml, clique nos botes e verifique as mensagens impressas no con-
sole.
SystemEvent
www.k19.com.br
173
E VENTOS
174
SystemEvents so similares aos PhaseEvents no sentido de que ambos esto relacionados a pontos especficos de execuo de uma aplicao JSF. Contudo, os eventos de sistema so gerados em
diversos pontos no cobertos pelos eventos de fase. Todas as classes que definem eventos de sistema
so subclasses de javax.faces.event.SystemEvent. Apresentamos abaixo algumas dessas classes.
PostConstructApplicationEvent
gerado imediatamente aps o incio da aplicao, depois que todas as configuraes so
processadas.
PreDestroyApplicationEvent
Esse tipo de evento gerado imediatamente antes da aplicao ser finalizada.
ExceptionQueuedEvent
Esse evento gerado assim que uma exceo no esperada lanada durante o processamento
de uma requisio. Alguns exemplos de excees esperadas durante o processamento de uma
requisio so aquelas relacionadas converso e validao dos dados.
PreValidateEvent e PostValidateEvent
Esses eventos so gerados imediatamente antes e logo aps um componente ser validado, respectivamente.
As trs primeiras classes listadas acima so subclasses diretas de SystemEvent, enquanto que as
duas ltimas so subclasses de javax.faces.event.ComponentSystemEvent.
Uma das formas para se registrar um interessado em eventos de sistema usando a tag <f:event>.
Essa tag possui dois atributos: type e listener. O atributo type usado para indicar o tipo de
evento. Alguns dos possveis valores para esse atributo so preValidate e postValidate. O atributo
listener deve indicar um mtodo que ser chamado quando o evento for processado. Esse mtodo
deve ser pblico, do tipo void, e receber como parmetro uma referncia para um objeto do tipo
javax.faces.event.ComponentSystemEvent.
O evento PostValidateEvent pode ser til na validao de mltiplos campos, por exemplo. Considere uma aplicao bancria que permite gerar extratos da conta corrente. Os dados de entrada so
duas datas e o resultado o extrato referente ao perodo determinado por essas datas. Uma restrio
que devemos impor que a data final no pode vir antes da data inicial.
No formulrio do cdigo abaixo, usamos a tag <f:event> para indicar que o mtodo validaDatas() do managed bean extratoBean deve ser chamado assim que o evento postValidate for
processado.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
174
www.k19.com.br
175
16
E VENTOS
</ h : form >
O mtodo validaDatas() do managed bean extratoBean registrado para receber eventos do tipo
PostValidateEvent
Na classe ExtratoBean, definimos o mtodo validaDatas() que recebe uma referncia para
um ComponentSystemEvent como parmetro. Aps verificar se as datas inicial e final so validas
(tarefa executada pelo validador de datas padro de cada um dos componentes), prosseguimos com
a verificao da nossa restrio adicional, isto , a data inicial deve vir antes da data final.
Se essa restrio no for respeitada, no devemos exibir extrato algum. Dessa forma, adicionamos uma mensagem no contexto do processamento da requisio e redirecionamos o fluxo para a
ltima fase do processamento, isto , para a fase Render Response.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package managedbeans ;
@ManagedBean
public class ExtratoBean {
private Date dataInicial ;
private Date dataFinal ;
public void validaDatas ( ComponentSystemEvent event ) {
UIComponent source = event . getComponent () ;
UIInput dataInicialInput = ( UIInput ) source . findComponent ( " data - inicial " ) ;
UIInput dataFinalInput = ( UIInput ) source . findComponent ( " data - final " ) ;
if ( dataInicialInput . isValid () && dataFinalInput . isValid () ) {
Date dataInicialEscolhida = ( Date ) dataInicialInput . getLocalValue () ;
Date dataFinalEscolhida = ( Date ) dataFinalInput . getLocalValue () ;
if ( dataFinalEscolhida . before ( dataInicialEscolhida ) ) {
FacesMessage message =
new FacesMessage ( " A data final no pode vir antes da data inicial " ) ;
message . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
FacesContext context = FacesContext . getCurrentInstance () ;
context . addMessage ( source . getClientId () , message ) ;
context . renderResponse () ;
}
}
}
public void geraExtrato () {
FacesMessage message = new FacesMessage ( " extrato gerado com sucesso " ) ;
message . setSeverity ( FacesMessage . SEVERITY_INFO ) ;
FacesContext context = FacesContext . getCurrentInstance () ;
context . addMessage ( null , message ) ;
}
// GETTERS E SETTERS
}
Cdigo Java 11.9: ExtratoBean.java
Exerccios de Fixao
8
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
www.k19.com.br
175
E VENTOS
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
176
" 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 > K19 - Eventos </ title >
</ h : head >
<h : body >
<h : form >
<f : event type = " postValidate " listener = " #{ extratoBean . validaDatas } " / >
<h : outputLabel value = " Data inicial : " for = " data - inicial " / >
<h : inputText
value = " #{ extratoBean . dataInicial } "
id = " data - inicial "
required = " true " >
<f : convertDateTime pattern = " dd / MM / yyyy " / >
</ h : inputText >
<h : outputLabel value = " Data final : " for = " data - final " / >
<h : inputText
value = " #{ extratoBean . dataFinal } "
id = " data - final "
required = " true " >
<f : convertDateTime pattern = " dd / MM / yyyy " / >
</ h : inputText >
<h : commandButton value = " Ver extrato " action = " #{ extratoBean . geraExtrato } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 11.8: extrato.xhtml
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
176
www.k19.com.br
177
30
31
32
33
34
35
36
37
38
39
E VENTOS
10
Immediate
Por padro, a converso e a validao dos dados de um componente de entrada (<h:inputText>,
por exemplo) so realizadas na fase Process Validation. Alm disso, os eventos de mudana de valor
(ValueChangeEvent) tambm ocorrem nessa fase.
Tambm por padro, os eventos de ao (ActionEvent) associados aos componentes <h:commandButton> ou <h:commandLink> so disparados no final da fase Invoke Application do processamento de uma requisio.
Porm, esse comportamento pode ser alterado atravs do atributo immediate desses componentes. Se o valor do atributo immediate de um componente de entrada for true, ento a converso e validao dos dados desse componente iro ocorrer durante a fase Apply Request Values, onde tambm
iro ser disparados possveis eventos de mudana de valor. No caso dos links e botes, os eventos de
ao sero disparados no final da fase Apply Request Values.
Exerccios de Fixao
Crie um formulrio para o cadastro de pessoas. Esse formulrio deve possuir trs campos obrigatrios. O primeiro deve ser uma caixa de texto para receber o nome de uma pessoa. O segundo deve
ser uma caixa de seleo para o usurio escolher um estado. O terceiro campo tambm deve ser uma
caixa de seleo, que permitir ao usurio escolher uma cidade. A caixa de seleo de cidade deve
exibir apenas as cidades do estado escolhido. Ou seja, quando o usurio selecionar determinado
estado, a lista de cidades deve ser atualizada de acordo.
11
Na pasta src do projeto K19-Eventos, crie um pacote chamado managedbeans e outro chamado
model.
No pacote model, crie uma classe chamada Estado para modelar um estado. Essa classe deve
ter como atributos o nome e a sigla do estado, bem como uma lista de cidades.
12
1
2
3
4
5
6
package model ;
public class Estado {
private String nome ;
private String sigla ;
private List < String > cidades = new ArrayList < String >() ;
www.k19.com.br
177
E VENTOS
7
8
9
178
// GETTERS E SETTERS
}
Cdigo Java 11.11: Estado.java
No pacote managedbeans, crie uma classe chamada CadastroBean, que dar suporte ao formulrio de cadastro. Essa classe tambm deve armazenar uma lista de estados que podero ser escolhidos no formulrio. Anote essa classe com @SessionScoped para que os dados do formulrio sejam
mantidos entre uma requisio e outra.
13
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
package managedbeans ;
@ManagedBean
@SessionScoped
public class CadastroBean {
private String nome ;
private String cidade ;
private String siglaDoEstadoEscolhido ;
private Estado estadoSelecionado = new Estado () ;
private List < Estado > estados = new ArrayList < Estado >() ;
public CadastroBean () {
Estado sp = new Estado () ;
sp . setSigla ( " SP " ) ;
sp . setNome ( " So Paulo " ) ;
sp . getCidades () . add ( " So Paulo " ) ;
sp . getCidades () . add ( " Campinas " ) ;
Estado rj = new Estado () ;
rj . setSigla ( " RJ " ) ;
rj . setNome ( " Rio de Janeiro " ) ;
rj . getCidades () . add ( " Rio de Janeiro " ) ;
rj . getCidades () . add ( " Niteri " ) ;
Estado rn = new Estado () ;
rn . setSigla ( " RN " ) ;
rn . setNome ( " Rio Grande do Norte " ) ;
rn . getCidades () . add ( " Natal " ) ;
rn . getCidades () . add ( " Mossor " ) ;
this . estados . add ( sp ) ;
this . estados . add ( rj ) ;
this . estados . add ( rn ) ;
}
public void mudaEstado ( ValueChangeEvent event ) {
this . siglaDoEstadoEscolhido = event . getNewValue () . toString () ;
for ( Estado e : this . estados ) {
if ( e . getSigla () . equals ( this . siglaDoEstadoEscolhido ) ) {
this . estadoSelecionado = e ;
break ;
}
}
}
// GETTERS E SETTERS
}
Cdigo Java 11.12: CadastroBean.java
178
www.k19.com.br
179
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
E VENTOS
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Cadastro </ h1 >
<h : form >
<h : panelGrid columns = " 3 " >
<h : outputLabel value = " Nome : " for = " nome " / >
<h : inputText value = " #{ cadastroBean . nome } " required = " true " id = " nome " / >
<h : message for = " nome " / >
<h : outputLabel value = " Estado : " for = " estado " / >
<h : selectOneMenu id = " estado "
value = " #{ cadastroBean . siglaDoEstadoEscolhido } "
valueChangeListener = " #{ cadastroBean . mudaEstado } "
onchange = " this . form . submit () ; "
required = " true " >
<f : selectItem itemLabel = " Escolha um estado " noSelectionOption = " true " / >
<f : selectItems
value = " #{ cadastroBean . estados } "
var = " estado "
itemLabel = " #{ estado . nome } "
itemValue = " #{ estado . sigla } " / >
</ h : selectOneMenu >
<h : message for = " estado " / >
<h : outputLabel value = " Cidade : " for = " cidade " / >
<h : selectOneMenu id = " cidade " value = " #{ cadastroBean . cidade } " required = " true " >
<f : selectItem itemLabel = " Escolha uma cidade " noSelectionOption = " true " / >
<f : selectItems value = " #{ cadastroBean . estadoSelecionado . cidades } " / >
</ h : selectOneMenu >
<h : message for = " cidade " / >
</ h : panelGrid >
<h : commandButton value = " Cadastrar " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 11.9: cadastro.xhtml
Para que a lista de cidades seja atualizada assim que o usurio selecionar um novo estado, usamos os atributos onchange e valueChangeListener do componente <h:selectOneMenu>. Definimos o valor do atributo onchange como sendo "this.form.submit();", o que significa que o formulrio ser submetido toda vez que um novo estado for selecionado. Alm disso, o atributo valueChangeListener est associado ao mtodo mudaEstado(), o que significa que esse mtodo ser
chamado quando o evento de mudana de valor for gerado no processamento da requisio. Nesse
mtodo, alteramos o valor da propriedade estadoSelecionado para refletir a escolha atual do usurio, o que implica que a caixa de seleo de cidade exibir as cidades desse estado. Veja as linhas em
destaque no cdigo acima.
15
http://localhost:8080/K19-Eventos/cadastro.xhtml
www.k19.com.br
179
E VENTOS
180
Assim, precisamos (i) antecipar a converso e validao dessa caixa de seleo e, logo em seguida,
(ii) desviar o fluxo do processamento da requisio para a fase Render Response. A primeira tarefa
pode ser feita definindo como true o valor do atributo immediate do componente <h:selectOneMenu>. O fluxo do processamento da requisio pode ser desviado para a fase Render Response se chamarmos o mtodo renderResponse() da instncia da classe FacesContext logo aps atualizarmos
o valor do atributo estadoSelecionado do managed bean cadastroBean.
1
2
3
4
5
6
7
8
9
10
11
12
13
...
<h : selectOneMenu id = " estado "
value = " #{ cadastroBean . siglaDoEstadoEscolhido } "
required = " true "
valueChangeListener = " #{ cadastroBean . mudaEstado } "
onchange = " this . form . submit () ; "
immediate = " true " >
<f : selectItem itemLabel = " Escolha um estado " noSelectionOption = " true " / >
<f : selectItems value = " #{ cadastroBean . estados } " var = " estado "
itemLabel = " #{ estado . nome } " itemValue = " #{ estado . sigla } " / >
</ h : selectOneMenu >
...
Cdigo XHTML 11.10: cadastro.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
...
public void mudaEstado ( ValueChangeEvent event ) {
this . siglaDoEstadoEscolhido = event . getNewValue () . toString () ;
for ( Estado e : this . estados ) {
if ( e . getSigla () . equals ( this . siglaDoEstadoEscolhido ) ) {
this . estadoSelecionado = e ;
break ;
}
}
FacesContext . getCurrentInstance () . renderResponse () ;
}
...
Cdigo Java 11.13: CadastroBean.java
180
www.k19.com.br
CAPTULO
A JAX
12
No exemplo acima, uma requisio AJAX ser realizada toda vez que o valor da caixa de texto for
modificado, j que o evento padro associado ao componente <h:inputText> o onchange.
Por outro lado, podemos explicitar o evento que deve disparar as requisies AJAX atravs do
atributo event da tag <f:ajax>. Devemos tomar cuidado pois nem todos os eventos so aceitos por
todos os componentes.
1
www.k19.com.br
181
A JAX
2
3
182
<f : ajax event = " keyup " / >
</ h : inputText >
Cdigo XHTML 12.2: Definindo o tipo de evento que deve disparar requisies AJAX
Quando temos vrios componentes para os quais desejamos oferecer o suporte do AJAX, podemos agrup-los atravs da tag <f:ajax>.
1
2
3
4
5
No exemplo acima, quando o boto Enviar for pressionado, uma requisio AJAX ser realizada.
No servidor, o formulrio e todos os componentes definidos dentro dele sero avaliados.
182
www.k19.com.br
183
A JAX
No exemplo acima, uma requisio AJAX realizada quando o boto Gera Nmero pressionado. Quando a resposta dessa requisio chega no navegador, apenas o componente <h:outputText> com o identificador numero ser atualizado. J no cdigo abaixo, dois componentes <h:outputText> so atualizados. Mais especificamente, os componentes com os identificadores numero1 e
numero2 so atualizados.
1
2
3
4
5
No exemplo acima, as requisies AJAX realizadas atravs do boto Salva foram associadas ao
mtodo salva() do managed bean produtoBean.
Palavras especiais
Como podemos passar uma lista de componentes para os atributos render e execute, o JSF criou
palavras chaves associadas a grupos especiais de componentes.
www.k19.com.br
183
A JAX
184
Podemos alterar o cdigo do formulrio anterior para utilizar a palavra especial @form no lugar
do identificador do formulrio.
1
2
3
4
5
6
7
8
9
Exerccios de Fixao
Crie um projeto do tipo Dynamic Web Project chamado K19-Ajax seguindo os passos vistos no
exerccio do Captulo 5.
1
Criaremos um formulrio com a validao dos campos realizadas com AJAX. Na pasta WebContent,
adicione um arquivo XHTML com o seguinte contedo:
2
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
184
<! 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 > K19 - Ajax </ title >
</ h : head >
<h : body >
<h : form >
<h : panelGrid columns = " 2 " >
<h : inputText id = " caixa " >
<f : ajax event = " keyup " execute = " caixa " render = " mensagem " / >
<f : validateLength minimum = " 5 " maximum = " 10 " / >
</ h : inputText >
<h : message id = " mensagem " for = " caixa " style = " color : red " / >
<h : commandButton value = " Enviar " / >
</ h : panelGrid >
</ h : form >
</ h : body >
</ html >
www.k19.com.br
185
A JAX
http://localhost:8080/K19-Ajax/formulario.xhtml
www.k19.com.br
185
A JAX
186
186
www.k19.com.br
CAPTULO
13
Como vimos nos primeiros captulos, os SGDBs so utilizados para armazenar os dados manipulados pelas aplicaes. At agora, os dados manipulados pelas aplicaes JSF desenvolvidas nos
exerccios no foram armazenados em um SGDB. Adicionaremos essa capacidade s aplicaes JSF
neste captulo. Para isso, mostraremos uma maneira de integrar os recursos do JSF e do JPA.
Bibliotecas
Para utilizar os recursos do JPA em uma aplicao JSF, os jars do provedor JPA e do driver JDBC
que sero utilizados devem estar no classpath da aplicao. Nos captulos anteriores, as aplicaes
JSF desenvolvidas nos exerccios foram implantadas no Glassfish 3.0.1 que um servidor de aplicao Java EE 6.
Por padro, a verso 3.0.1 do Glassfish possui os jars do provedor JPA EclipseLink. Dessa forma, as
aplicaes JSF implantadas nessa verso do Glassfish utilizaro o EclipseLink como implementao
do JPA. Contudo, queremos utilizar o provedor JPA Hibernate. Podemos facilmente substituir os jars
do EclipseLink pelos jars do Hibernate atravs da interface de administrao do Glassfish.
Mais Sobre
Consulte o artigo da K19 sobre a substituio dos jars do provedor JPA EclipseLink pelos
jars do provedor JPA Hibernate.
http://www.k19.com.br/artigos/configurando-hibernate-no-glassfish-3-1/
Utilizaremos o MySQL Server como SGDB. Dessa forma, devemos adicionar o driver JDBC do
MySQL Server no classpath das aplicaes JSF. O Glassfish 3.0.1 no possui os jars desse driver JDBC.
Contudo, podemos adicion-los manualmente. Para isso, basta acrescentar os jars do driver JDBC
do MySQL em uma pasta apropriada do Glassfish. Nos exerccios deste captulo, mostraremos como
realizar tal tarefa.
Configurao
Como vimos no Captulo 3, devemos configurar as unidades de persistncia utilizadas atravs do
arquivo persistence.xml da pasta META-INF do classpath da aplicao.
1
2
3
4
<? xml version = " 1.0 " encoding = " UTF -8 " ? >
< persistence version = " 2.0 "
xmlns = " http: // java . sun . com / xml / ns / persistence "
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
www.k19.com.br
187
xsi:schemaLocation = " http: // java . sun . com / xml / ns / persistence http: // java . sun . com / xml / ns / persistence / persistence_2_0 . xsd " >
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
188
< persistence - unit name = " K19 - PU " transaction - type = " RESOURCE_LOCAL " >
< provider > org . hibernate . ejb . HibernatePersistence </ provider >
< properties >
< property name = " hibernate . dialect " value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
< property name = " hibernate . hbm2ddl . auto " value = " create " / >
< property name = " javax . persistence . jdbc . driver " value = " com . mysql . jdbc . Driver " / >
< property name = " javax . persistence . jdbc . user " value = " usuario " / >
< property name = " javax . persistence . jdbc . password " value = " senha " / >
< property name = " javax . persistence . jdbc . url " value = " jdbc:mysql: // localhost:3306 / K19 - DB " / >
</ properties >
</ persistence - unit >
</ persistence >
Cdigo XML 13.1: persistence.xml
Mapeamento
Tambm devemos definir o mapeamento das entidades. No Captulo 3, vimos como utilizar as
anotaes do JPA para estabelecer esse mapeamento.
1
2
3
4
5
6
7
8
9
10
11
@Entity
public class Produto {
@Id @GeneratedValue
private Long id ;
private String nome ;
private Double preco ;
// GETTERS e SETTERS
}
Cdigo Java 13.1: Produto.java
Inicializao e Finalizao
As unidades de persistncia devem ser inicializadas antes de serem utilizadas, e finalizadas quando
no forem mais necessrias. A inicializao e a finalizao de uma unidade de persistncia devem
ser realizadas apenas uma vez durante a execuo da aplicao.
Para implementar essa caracterstica em aplicaes web Java, podemos utilizar um filtro. Os
filtros de uma aplicao web Java so inicializados automaticamente depois que a aplicao implantada no Web Container e antes da primeira requisio HTTP. Alm disso, eles so finalizados ao
trmino da execuo da aplicao.
Para adicionar um filtro em uma aplicao web Java, necessrio criar uma classe que implemente a interface javax.servlet.Filter.
188
www.k19.com.br
189
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Um filtro pode ser registrado no Web Container atravs da anotao @WebFilter. Com essa anotao, podemos definir qual servlet ser associada ao filtro. No exemplo acima, o filtro definido pela
classe JPAFilter foi associado a servlet Faces Servlet.
O mtodo init() chamado automaticamente na inicializao do filtro. No exemplo acima, esse
mtodo inicializa a unidade de persistncia K19-PU. O mtodo destroy() chamado automaticamente para desativar o filtro no encerramento da aplicao. No exemplo acima, finalizamos a unidade de persistncia K19-PU.
Transaes
Como vimos no Captulo 3, para atualizar as informaes armazenadas no SGDB de acordo com
os dados da memria da aplicao, devemos abrir uma transao e confirm-la atravs do mtodo
commit().
O filtro criado anteriormente para controlar a inicializao e finalizao das unidades de persistncia pode tambm gerenciar a abertura e a confirmao das transaes da aplicao. Para isso,
utilizaremos o mtodo doFilter() desse filtro.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
www.k19.com.br
189
190
@Override
public void doFilter ( ServletRequest request , ServletResponse response ,
FilterChain chain ) throws IOException , ServletException {
// CHEGADA
EntityManager manager = this . factory . createEntityManager () ;
request . setAttribute ( " EntityManager " , manager ) ;
entityManager . getTransaction () . begin () ;
// CHEGADA
// FACES SERVLET
chain . doFilter ( request , response ) ;
// FACES SERVLET
// SADA
try {
entityManager . getTransaction () . commit () ;
} catch ( Exception e ) {
entityManager . getTransaction () . rollback () ;
} finally {
entityManager . close () ;
}
// SADA
}
}
Cdigo Java 13.3: JPAFilter.java
No exemplo acima, o mtodo doFilter() chamado toda vez que uma requisio realizada
para a servlet Faces Servlet. Antes de repassar a requisio para a Faces Servlet, o mtodo doFilter()
cria um EntityManager, armazena-o na requisio e abre uma transao. Depois que a Faces Servlet processou a requisio, o mtodo doFilter() tenta confirmar a transao atravs do mtodo
commit(). Se um erro ocorrer nessa tentativa, o mtodo rollback() chamado para cancelar a
transao.
Exerccios de Fixao
Entre na pasta K19-Arquivos/MySQL-Connector-JDBC da rea de Trabalho e copie o arquivo
mysql-connector-java-5.1.13-bin.jar para pasta glassfishv3/glassfish/lib tambm da sua rea
de Trabalho. OBS: O Glassfish deve ser reiniciado para reconhecer o driver JDBC do MySQL.
1
190
191
1
2
3
4
5
<? xml version = " 1.0 " encoding = " UTF -8 " ? >
< persistence version = " 2.0 "
xmlns = " http: // java . sun . com / xml / ns / persistence "
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
xsi:schemaLocation = " http: // java . sun . com / xml / ns / persistence http: // java . sun . com / xml / ns / persistence / persistence_2_0 . xsd " >
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
< persistence - unit name = " K19 - PU " transaction - type = " RESOURCE_LOCAL " >
< provider > org . hibernate . ejb . HibernatePersistence </ provider >
< properties >
< property name = " hibernate . dialect " value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
< property name = " hibernate . hbm2ddl . auto " value = " update " / >
< property name = " javax . persistence . jdbc . driver " value = " com . mysql . jdbc . Driver " / >
< property name = " javax . persistence . jdbc . user " value = " root " / >
< property name = " javax . persistence . jdbc . password " value = " root " / >
< property name = " javax . persistence . jdbc . url " value = " jdbc:mysql: // localhost:3306 / K19 - DB " / >
</ properties >
</ persistence - unit >
</ persistence >
Cdigo XML 13.2: persistence.xml
Abra um terminal; entre no cliente do MySQL Server; apague se existir a base de dados K19-DB;
e crie uma base de dados nova chamada K19-DB.
5
No pacote filters, crie uma classe chamada JPAFilter com o seguinte contedo:
1
2
3
4
5
6
7
package filters ;
@WebFilter ( servletNames ={ " Faces Servlet " })
public class JPAFilter implements Filter {
private EntityManagerFactory factory ;
www.k19.com.br
191
192
@Override
public void init ( FilterConfig filterConfig ) throws ServletException {
this . factory = Persistence . createEntityManagerFactory ( " K19 - PU " ) ;
}
@Override
public void destroy () {
this . factory . close () ;
}
@Override
public void doFilter ( ServletRequest request , ServletResponse response ,
FilterChain chain ) throws IOException , ServletException {
// CHEGADA
EntityManager manager = this . factory . createEntityManager () ;
request . setAttribute ( " EntityManager " , manager ) ;
manager . getTransaction () . begin () ;
// CHEGADA
// FACES SERVLET
chain . doFilter ( request , response ) ;
// FACES SERVLET
// SADA
try {
manager . getTransaction () . commit () ;
} catch ( Exception e ) {
manager . getTransaction () . rollback () ;
} finally {
manager . close () ;
}
// SADA
}
}
Cdigo Java 13.5: JPAFilter.java
No pacote model, crie uma classe chamada Carro com o seguinte contedo:
1
2
3
4
5
6
7
8
9
10
11
12
package model ;
@Entity
public class Carro {
@Id @GeneratedValue
private Long id ;
private String marca ;
private String modelo ;
// GETTERS E SETTERS
}
Cdigo Java 13.6: Carro.java
10
No pacote model, crie uma classe chamada CarroRepository com o seguinte contedo:
1
2
3
4
5
6
7
8
package model ;
192
www.k19.com.br
193
9
10
11
12
13
14
15
16
17
18
19
11
12
No pacote managedbeans, crie uma classe chamada CarroBean com o seguinte cdigo:
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
package managedbeans ;
@ManagedBean
public class CarroBean {
private Carro carro = new Carro () ;
public void adicionaCarro () {
EntityManager manager = this . getEntityManager () ;
CarroRepository repository = new CarroRepository ( manager ) ;
repository . adiciona ( this . carro ) ;
this . carro = new Carro () ;
}
public List < Carro > getCarros () {
EntityManager manager = this . getEntityManager () ;
CarroRepository repository = new CarroRepository ( manager ) ;
return repository . buscaTodos () ;
}
private EntityManager getEntityManager () {
FacesContext fc = FacesContext . getCurrentInstance () ;
ExternalContext ec = fc . getExternalContext () ;
HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
return manager ;
}
// GETTERS E SETTERS
}
Cdigo Java 13.8: CarroBean.java
No diretrio WebContent, crie um arquivo XHTML chamado carros.xhtml com o seguinte contedo:
13
1
2
3
4
5
6
7
8
9
10
11
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
< html xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
www.k19.com.br
193
194
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
15
http://localhost:8080/K19-Integracao-JSF-JPA/carros.xhtml
Adicione alguns carros e verifique se eles foram adicionados no SGDB.
www.k19.com.br
195
Durante o processamento de uma requisio, os mtodos getters so chamados pelo JSF. A quantidade de chamadas no pode ser controlada pela aplicao. A lgica implementada nos getters pode
comprometer a performance da aplicao. Por exemplo, nos exerccios anteriores, toda vez que o
mtodo getCarros() do managed bean carroBean chamado, uma consulta realizada no SGBD
atravs do repositrio de carros.
Podemos diminuir a quantidade de consultas armazenando o resultado da primeira chamada em
um atributo da classe CarroBean. Esse resultado pode ser mantido at que alguma alterao na listagem de carros ocorra. Por exemplo, se um carro for adicionado ou removido, a listagem armazenada
deve ser descartada e recuperada novamente do SGDB. Veja o cdigo abaixo.
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
package managedbeans ;
@ManagedBean
public class CarroBean {
private Carro carro = new Carro () ;
private List < Carro > carros ;
public void adicionaCarro () {
EntityManager manager = this . getEntityManager () ;
CarroRepository repository = new CarroRepository ( manager ) ;
repository . adiciona ( this . carro ) ;
this . carro = new Carro () ;
this . carros = null ;
}
public List < Carro > getCarros () {
if ( this . carros == null ) {
EntityManager manager = this . getEntityManager () ;
CarroRepository repository = new CarroRepository ( manager ) ;
this . carros = repository . buscaTodos () ;
}
return this . carros ;
}
private EntityManager getEntityManager () {
FacesContext fc = FacesContext . getCurrentInstance () ;
ExternalContext ec = fc . getExternalContext () ;
HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
return manager ;
}
// GETTERS E SETTERS
}
No cdigo acima, o atributo carros armazena a ltima lista carregada do SGDB. No mtodo
getCarros(), verificamos se j existe uma lista carregada no atributo carros. Se no existir uma
lista carregada ento utilizamos o repositrio de carros para recuperar os dados do SGDB e carregar a lista. Caso contrrio, simplesmente utilizamos a lista que j estava carregada. No mtodo
adicionaCarro(), depois que o repositrio de carros acionado para persistir um carro, descartamos o contedo do atributo carros. Dessa forma, na prxima chamada do mtodo getCarros(), a
lista ser carregada novamente e conter o carro que acabou de ser adicionado.
www.k19.com.br
195
196
Exerccios de Fixao
Vamos monitorar a quantidade de chamadas ao mtodo getCarros() do managed bean carroBean.
Altere a classe desse managed bean da seguinte forma:
16
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package managedbeans ;
@ManagedBean
public class CarroBean {
private Carro carro = new Carro () ;
public void adicionaCarro () {
EntityManager manager = this . getEntityManager () ;
CarroRepository repository = new CarroRepository ( manager ) ;
repository . adiciona ( this . carro ) ;
this . carro = new Carro () ;
}
public List < Carro > getCarros () {
EntityManager manager = this . getEntityManager () ;
CarroRepository repository = new CarroRepository ( manager ) ;
System . out . println ( " CHAMANDO O REPOSITORIO " ) ;
return repository . buscaTodos () ;
}
private EntityManager getEntityManager () {
FacesContext fc = FacesContext . getCurrentInstance () ;
ExternalContext ec = fc . getExternalContext () ;
HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
return manager ;
}
// GETTERS E SETTERS
}
Cdigo Java 13.10: CarroBean.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
196
package managedbeans ;
@ManagedBean
public class CarroBean {
private Carro carro = new Carro () ;
private List < Carro > carros ;
public void adicionaCarro () {
EntityManager manager = this . getEntityManager () ;
CarroRepository repository = new CarroRepository ( manager ) ;
repository . adiciona ( this . carro ) ;
this . carro = new Carro () ;
this . carros = null ;
www.k19.com.br
197
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
www.k19.com.br
197
198
198
www.k19.com.br
APNDICE
AUTENTICAO
Exerccios de Fixao
Crie um projeto do tipo Dynamic Web Project chamado K19-Autenticacao seguindo os passos
vistos no exerccio do Captulo 5.
1
Importante
Por motivos de segurana, as senhas dos usurios no devem ser armazenadas literalmente. Ao invs disso, as senhas dos usurios devem passar por um processo de transformao (criptografia) antes de serem armazenadas.
Quando um usurio tenta logar no sistema, ele digita o seu nome de usurio e sua senha. Para
garantir que o usurio tenha acesso ao sistema, precisamos verificar se o nome de usurio digitado est cadastrado no sistema e se sua senha est correta. Como ns no armazenamos a
senha do usurio, o que fazemos aplicar a mesma transformao feita anteriormente e comparar o valor obtido com aquele armazenado no servidor. Se esses valores forem iguais, ento
permitimos que o usurio acesse o sistema. Caso contrrio, o acesso ao sistema negado.
@ManagedBean
public class AutenticadorBean {
private static Map < String , String > mapa = new HashMap < String , String >() ;
}
Cdigo Java A.1: AutenticadorBean.java
1
2
3
4
@ManagedBean
public class AutenticadorBean {
private static Map < String , String > mapa = new HashMap < String , String >() ;
www.k19.com.br
199
AUTENTICAO
5
6
7
8
9
10
11
12
200
static {
AutenticadorBean . mapa . put ( " k19 " , " k19 " ) ;
AutenticadorBean . mapa . put ( " jonas . hirata " , " jonas . hirata " ) ;
AutenticadorBean . mapa . put ( " marcelo . martins " , " marcelo . martins " ) ;
AutenticadorBean . mapa . put ( " rafael . cosentino " , " rafael . cosentino " ) ;
}
}
Cdigo Java A.2: AutenticadorBean.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
@ManagedBean
public class AutenticadorBean {
private static Map < String , String > mapa = new HashMap < String , String >() ;
private String usuario ;
private String senha ;
static {
AutenticadorBean . mapa . put ( " k19 " , " k19 " ) ;
AutenticadorBean . mapa . put ( " jonas . hirata " , " jonas . hirata " ) ;
AutenticadorBean . mapa . put ( " marcelo . martins " , " marcelo . martins " ) ;
AutenticadorBean . mapa . put ( " rafael . cosentino " , " rafael . cosentino " ) ;
}
public String autentica () {
FacesContext fc = FacesContext . getCurrentInstance () ;
if ( AutenticadorBean . mapa . containsKey ( this . usuario )
&& AutenticadorBean . mapa . get ( this . usuario ) . equals ( this . senha ) ) {
ExternalContext ec = fc . getExternalContext () ;
HttpSession session = ( HttpSession ) ec . getSession ( false ) ;
session . setAttribute ( " usuario " , this . usuario ) ;
return " / home " ;
} else {
FacesMessage fm = new FacesMessage ( " usurio e / ou senha invlidos " ) ;
fm . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
fc . addMessage ( null , fm ) ;
return " / login " ;
}
}
public String registraSaida () {
FacesContext fc = FacesContext . getCurrentInstance () ;
ExternalContext ec = fc . getExternalContext () ;
HttpSession session = ( HttpSession ) ec . getSession ( false ) ;
session . removeAttribute ( " usuario " ) ;
return " / login " ;
}
// GETTERS E SETTERS
}
Cdigo Java A.3: AutenticadorBean.java
O mtodo autentica() verifica se os dados enviados pelo formulrio de autenticao esto cadastrados no mapa. Se esses dados estiverem cadastrados, registramos o nome do usurio na sesso
200
www.k19.com.br
201
AUTENTICAO
HTTP e navegamos para a pgina principal da aplicao. Caso contrrio, adicionamos no contexto
do processamento da requisio uma mensagem de erro e navegamos para a pgina do formulrio de autenticao. O mtodo registraSaida() simplesmente retira da sesso HTTP o nome do
usurio anteriormente autenticado.
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
Ol #{ sessionScope . usuario }!
Voc est logado .
<h : form >
<h : commandLink value = " Sair " action = " #{ autenticadorBean . registraSaida } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML A.2: home.xhtml
Somente usurios autenticados podem acessar a pgina principal da aplicao. Para controlar
www.k19.com.br
201
AUTENTICAO
202
o acesso s pginas da aplicao, implemente um filtro para interceptar todas as requisies HTTP
direcionadas Faces Servlet.
Crie uma classe chamada ControleDeAcesso em um pacote chamado filtros no projeto K19-Autenticacao com o seguinte contedo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
202
www.k19.com.br
203
AUTENTICAO
www.k19.com.br
L
HTMscript
a
Jav
S
S
C
Requisio HTTP
Resposta HTTP
Faces Servlet
Restore
View
Apply Request
Values
Process
Validation
Update
Model
Ivoke
Application
Render
Response
MANAGED BEANS
CONTROLE
MODELO
VISO
TELAS
ENTIDADES
TEMPLATES
REPOSITRIOS
TELAS PARCIAIS
www.k19.com.br
203
AUTENTICAO
204
204
www.k19.com.br
APNDICE
PGINAS DE E RRO
Por padro, quando determinados erros ocorrem no processamento de uma requisio, pginas
com informaes tcnicas sobre o problema que ocorreu so geradas e enviadas para os usurios. Na
fase de desenvolvimento, essas pginas so teis para os desenvolvedores. Por outro lado, na fase de
produo, essas pginas podem confundir os usurios da aplicao e revelar a estrutura do sistema,
expondo possveis falhas de segurana.
Caused by: java.lang.IllegalArgumentException: id to load is required for loading
at org.hibernate.event.LoadEvent.<init>(LoadEvent.java:89)
at org.hibernate.event.LoadEvent.<init>(LoadEvent.java:61)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:994)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:990)
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:554)
at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:529)
at model.repositories.TimeRepository.procura(TimeRepository.java:38)
at managedbeans.JogadorBean.adiciona(JogadorBean.java:30)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.sun.el.parser.AstValue.invoke(AstValue.java:234)
at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
... 41 more
Hi Hi Hi!!
Exerccios de Fixao
Crie um projeto do tipo Dynamic Web Project chamado K19-Paginas-de-Erro seguindo os passos vistos no exerccio do Captulo 5.
1
Criaremos uma pgina de erro padro. Adicione na pasta WebContent um arquivo XHTML com
o seguinte contedo.
2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Ocorreu um erro interno no sistema . </ h1 >
< h3 > Tente novamente em alguns instantes . </ h3 >
www.k19.com.br
205
PGINAS DE E RRO
16
17
206
Criaremos uma pgina com um boto que sempre produzir um erro ao ser clicado. Adicione
na pasta WebContent um arquivo XHTML com o seguinte contedo.
3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<! 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 > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : commandButton value = " Gera Erro " action = " #{ erroBean . geraErro } " / >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML B.2: gerador-de-erro.xhtml
Crie um managed bean que provoque propositalmente um erro. Adicione em um pacote chamado managedbeans uma classe com o seguinte cdigo:
4
1
2
3
4
5
6
@ManagedBean
public class ErroBean {
public void geraErro () {
System . out . println (10/0) ;
}
}
Cdigo Java B.1: AutenticadorBean.java
http://localhost:8080/K19-Paginas-de-Erro/gerador-de-erro.xhtml
Configure o Web Container para direcionar todas as exceptions para a pgina de erro padro.
Adicione o seguinte cdigo no arquivo web.xml.
6
1
2
3
4
5
6
...
< error - page >
< exception - type > java . lang . Exception </ exception - type >
< location >/ pagina - de - erro . xhtml </ location >
</ error - page >
...
Cdigo XML B.1: web.xml
http://localhost:8080/K19-Paginas-de-Erro/gerador-de-erro.xhtml
206
www.k19.com.br
APNDICE
Para consolidar o conhecimento obtido durante o treinamento, desenvolveremos uma aplicao completa para auxiliar no gerenciamento de um campeonato de futebol. Essa aplicao dever
permitir que os usurios possam cadastrar novos times e jogadores, bem como list-los, alter-los
e remov-los. Essa aplicao tambm dever possibilitar que jogadores sejam associados a times
de futebol, respeitando-se a restrio de que cada jogador deve pertencer a no mximo um time de
futebol.
Exerccios de Fixao
Entre na pasta K19-Arquivos/MySQL-Connector-JDBC da rea de Trabalho e copie o arquivo
mysql-connector-java-5.1.13-bin.jar para a pasta glassfishv3/glassfish/lib tambm da sua rea
de Trabalho. OBS: O Glassfish deve ser reiniciado para reconhecer o driver JDBC do MySQL.
1
Crie um projeto do tipo Dynamic Web Project chamado K19-Futebol seguindo os passos vistos
no exerccio do Captulo 5.
2
1
2
3
4
5
<? xml version = " 1.0 " encoding = " UTF -8 " ? >
< persistence version = " 2.0 "
xmlns = " http: // java . sun . com / xml / ns / persistence "
xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
xsi:schemaLocation = " http: // java . sun . com / xml / ns / persistence http: // java . sun . com / xml / ns / persistence / persistence_2_0 . xsd " >
6
7
8
9
10
11
12
13
14
15
16
17
18
< persistence - unit name = " K19 - Futebol - PU " transaction - type = " RESOURCE_LOCAL " >
< provider > org . hibernate . ejb . HibernatePersistence </ provider >
< properties >
< property name = " hibernate . dialect " value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
< property name = " hibernate . hbm2ddl . auto " value = " update " / >
< property name = " javax . persistence . jdbc . driver " value = " com . mysql . jdbc . Driver " / >
< property name = " javax . persistence . jdbc . user " value = " root " / >
< property name = " javax . persistence . jdbc . password " value = " root " / >
www.k19.com.br
207
208
< property name = " javax . persistence . jdbc . url " value = " jdbc:mysql: // localhost:3306 / K19 - Futebol - DB " / >
</ properties >
</ persistence - unit >
</ persistence >
Cdigo XML C.1: persistence.xml
5 Abra um terminal; entre no cliente do MySQL Server; apague se existir a base de dados K19-Futebol-DB;
e crie uma base de dados nova chamada K19-Futebol-DB.
k19@k19 -11:~/ rafael$ mysql -u root -p
Enter password :
Welcome to the MySQL monitor . Commands end with ; or \ g .
Your MySQL connection id is 36
Server version : 5.1.58 -1 ubuntu1 ( Ubuntu )
Copyright ( c ) 2000 , 2010 , Oracle and / or its affiliates . All rights reserved .
This software comes with ABSOLUTELY NO WARRANTY . This is free software ,
and you are welcome to modify and redistribute it under the GPL v2 license
Type help ; or \h for help . Type \c to clear the current input statement .
mysql > DROP DATABASE IF EXISTS K19 - Futebol - DB ;
Query OK , 0 rows affected , 1 warning (0.00 sec )
mysql > CREATE DATABASE K19 - Futebol - DB ;
Query OK , 1 row affected (0.02 sec )
No pacote filters, crie uma classe chamada JPAFilter com o seguinte contedo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
208
package filters ;
@WebFilter ( servletNames ={ " Faces Servlet " })
public class JPAFilter implements Filter {
private EntityManagerFactory factory ;
@Override
public void init ( FilterConfig filterConfig ) throws ServletException {
this . factory = Persistence . createEntityManagerFactory ( " K19 - Futebol - PU " ) ;
}
@Override
public void destroy () {
this . factory . close () ;
}
@Override
public void doFilter ( ServletRequest request , ServletResponse response ,
FilterChain chain ) throws IOException , ServletException {
// CHEGADA
EntityManager manager = this . factory . createEntityManager () ;
request . setAttribute ( " EntityManager " , manager ) ;
manager . getTransaction () . begin () ;
// CHEGADA
// FACES SERVLET
chain . doFilter ( request , response ) ;
// FACES SERVLET
// SADA
try {
manager . getTransaction () . commit () ;
} catch ( Exception e ) {
www.k19.com.br
209
36
37
38
39
40
41
42
Modelo
Na camada de modelo da nossa aplicao, implementaremos duas entidades: Jogador e Time.
Alm disso, criaremos os respectivos repositrios para implementar as diversas operaes relacionadas persistncia dessas duas entidades.
Exerccios de Fixao
8
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
www.k19.com.br
209
210
10
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
27
28
29
30
31
32
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
210
www.k19.com.br
211
25
26
27
28
29
30
31
32
33
34
35
36
37
Managed Beans
Na camada de controle, implementaremos managed beans para controlar as operaes relacionadas s entidades Jogador e Time.
Exerccios de Fixao
12
13
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
package managedbeans ;
@ManagedBean
public class TimeBean {
private Time time = new Time () ;
private List < Time > times ;
public void adiciona () {
EntityManager manager = this . getManager () ;
TimeRepository repository = new TimeRepository ( manager ) ;
if ( this . time . getId () == null ) {
repository . adiciona ( this . time ) ;
} else {
repository . atualiza ( this . time ) ;
}
this . time = new Time () ;
this . times = null ;
}
public void preparaAlteracao () {
Map < String , String > params =
FacesContext . getCurrentInstance () . getExternalContext () . getRequestParameterMap () ;
Long id = Long . parseLong ( params . get ( " id " ) ) ;
EntityManager manager = this . getManager () ;
TimeRepository repository = new TimeRepository ( manager ) ;
this . time = repository . procura ( id ) ;
}
public void remove () {
Map < String , String > params =
FacesContext . getCurrentInstance () . getExternalContext () . www.k19.com.br
211
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
212
getRequestParameterMap () ;
Long id = Long . parseLong ( params . get ( " id " ) ) ;
EntityManager manager = this . getManager () ;
TimeRepository repository = new TimeRepository ( manager ) ;
repository . remove ( id ) ;
this . times = null ;
}
public List < Time > getTimes () {
if ( this . times == null ) {
EntityManager manager = this . getManager () ;
TimeRepository repository = new TimeRepository ( manager ) ;
this . times = repository . getLista () ;
}
return this . times ;
}
private EntityManager getManager () {
FacesContext fc = FacesContext . getCurrentInstance () ;
ExternalContext ec = fc . getExternalContext () ;
HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
return ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
}
// GETTERS E SETTERS
}
Cdigo Java C.6: TimeBean.java
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
212
www.k19.com.br
213
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
Telas
Vamos implementar a camada de apresentao da nossa aplicao. Criaremos algumas telas
usando templates e telas parciais.
Exerccios de Fixao
Na pasta WebContent, crie um diretrio chamado resources. Nesse diretrio, crie diretrios
chamados css e imagens.
15
16
1
2
3
4
5
6
7
8
9
10
11
12
www.k19.com.br
213
214
h2 {
font : bold 24 px Arial ;
color : #595959;
}
a {
color : #3 a34c3 ;
text - decoration : none ;
}
a : hover {
text - decoration : underline ;
}
. dados {
border - collapse : collapse ;
}
. dados td ,. dados th {
border : 1 px solid #0000 c6 ;
padding : 3 px 7 px 2 px 7 px ;
}
. dados th {
padding - top : 5 px ;
padding - bottom : 4 px ;
background - color : #156 bbd ;
color : # ffffff ;
}
. dados tr . impar td {
color : #000000;
background - color : # d4d4d9 ;
}
. dados tr . par td {
color : #000000;
background - color : # f6f6fa ;
}
input {
font - size : 16 px ;
border : 1 px solid #0000 c6 ;
background - color : # f6f6fa ;
}
# header {
color : # FFFFFF ;
background - color : #252525;
padding : 10 px 0 px 28 px 10 px ;
}
# header a {
color : # FFFFFF ;
font : bold 24 px Arial ;
}
# conteudo {
margin : 0 px 0 px 50 px 10 px ;
}
17
214
Copie o arquivo k19-logo.png da pasta K19-Arquivos da rea de Trabalho para a pasta resources/imagens.
www.k19.com.br
215
18
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 > K19 Futebol </ title >
</ h : head >
<h : body >
<h : outputStylesheet library = " css " name = " style . css " / >
< div id = " header " >
<h : form style = " float : left ; " >
<h : link value = " Times " outcome = " times " / >
& nbsp ;
<h : link value = " Jogadores " outcome = " jogadores " / >
</ h : form >
<h : graphicImage library = " imagens " name = " k19 - logo . png " style = " float : right ; " / >
< div style = " clear : both " > </ div >
</ div >
< div id = " conteudo " >
< ui : insert name = " conteudo " > Espao para o contedo da tela </ ui : insert >
</ div >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2012 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML C.1: template.xhtml
20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
www.k19.com.br
215
216
Tambm na pasta WebContent, crie as telas parciais definidas pelos arquivos formulario-novo-time.xhtml e lista-de-times.xhtml.
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
25
26
27
28
29
30
31
32
33
34
35
< ui : composition
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : ui = " http :// java . sun . com / jsf / facelets "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : inputHidden value = " #{ timeBean . time . id } " / >
<h : panelGrid columns = " 3 " >
<h : outputLabel value = " Nome : " for = " nome " / >
<h : inputText
id = " nome "
required = " true "
requiredMessage = " O nome do time obrigatrio "
value = " #{ timeBean . time . nome } " >
</ h : inputText >
<h : message for = " nome " / >
<h : outputLabel value = " Tcnico : " for = " tecnico " / >
<h : inputText
id = " tecnico "
required = " true "
requiredMessage = " O nome do tcnico obrigatrio "
value = " #{ timeBean . time . tecnico } " >
</ h : inputText >
<h : message for = " tecnico " / >
<h : commandButton value = " Cadastrar " >
<f : ajax
event = " click "
execute = " @form "
listener = " #{ timeBean . adiciona } "
render = " @all " / >
</ h : commandButton >
</ h : panelGrid >
</ ui : composition >
Cdigo XHTML C.3: formulario-novo-time.xhtml
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
216
< ui : composition
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : ui = " http :// java . sun . com / jsf / facelets "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : panelGroup rendered = " #{ not empty timeBean . times } " >
< h2 > Lista de Times </ h2 >
<h : dataTable
id = " tabela "
value = " #{ timeBean . times } "
var = " time "
styleClass = " dados "
rowClasses = " par , impar " >
<h : column >
<f : facet name = " header " >
<h : outputText value = " Id " / >
</ f : facet >
#{ time . id }
</ h : column >
<h : column >
<f : facet name = " header " >
<h : outputText value = " Nome " / >
</ f : facet >
www.k19.com.br
217
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
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
www.k19.com.br
217
218
Ainda na pasta WebContent, crie as telas parciais definidas pelos arquivos formulario-novo-jogador.xhtml e lista-de-jogadores.xhtml.
23
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
53
54
55
< ui : composition
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : ui = " http :// java . sun . com / jsf / facelets "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : inputHidden value = " #{ jogadorBean . jogador . id } " / >
<h : panelGrid columns = " 3 " >
<h : outputLabel value = " Nome : " for = " jogador - nome " / >
<h : inputText
id = " jogador - nome "
required = " true "
requiredMessage = " O nome do jogador obrigatrio "
value = " #{ jogadorBean . jogador . nome } " >
</ h : inputText >
<h : message for = " jogador - nome " / >
<h : outputLabel value = " Posio : " for = " jogador - posicao " / >
<h : inputText
id = " jogador - posicao "
required = " true "
requiredMessage = " A posio do jogador deve ser especificada "
value = " #{ jogadorBean . jogador . posicao } " >
</ h : inputText >
<h : message for = " jogador - posicao " / >
<h : outputLabel value = " Data de Nascimento : " for = " jogador - nascimento " / >
<h : inputText
id = " jogador - nascimento "
required = " true "
requiredMessage = " Informe a data de nascimento do jogador "
value = " #{ jogadorBean . jogador . dataDeNascimento . time } " >
<f : convertDateTime pattern = " dd / MM / yyyy " / >
</ h : inputText >
<h : message for = " jogador - nascimento " / >
<h : outputLabel value = " Time : " for = " jogador - time " / >
<h : selectOneMenu id = " jogador - time " value = " #{ jogadorBean . timeID } " >
<f : selectItems
value = " #{ timeBean . times } "
var = " time "
itemLabel = " #{ time . nome } "
itemValue = " #{ time . id } " / >
</ h : selectOneMenu >
<h : message for = " jogador - time " / >
<h : commandButton value = " Cadastrar " styleClass = " botao - formulario " >
<f : ajax
event = " click "
execute = " @form "
listener = " #{ jogadorBean . adiciona } "
render = " @form " / >
</ h : commandButton >
</ h : panelGrid >
</ ui : composition >
Cdigo XHTML C.6: formulario-novo-jogador.xhtml
1
2
3
4
5
6
7
218
< ui : composition
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : ui = " http :// java . sun . com / jsf / facelets "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : panelGroup rendered = " #{ not empty jogadorBean . jogadores } " >
www.k19.com.br
219
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
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
www.k19.com.br
219
220
24
http://localhost:8080/K19-Futebol/times.xhtml
Autenticao
Vamos acrescentar um controle de segurana nossa aplicao como vimos no Apndice A.
25
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
220
www.k19.com.br
221
42
43
44
45
46
47
48
26
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
< ui : composition template = " / WEB - INF / templates / template . xhtml "
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 " >
< ui : define name = " conteudo " >
<p > Preencha o formulrio abaixo para entrar no sistema . </ p >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Usurio : " for = " campo - usuario " / >
<h : inputText value = " #{ autenticadorBean . usuario } " id = " campo - usuario " / >
<h : outputLabel value = " Senha : " for = " campo - senha " / >
<h : inputSecret value = " #{ autenticadorBean . senha } " id = " campo - senha " / >
</ h : panelGrid >
<h : commandButton value = " Entrar " action = " #{ autenticadorBean . autentica } " / >
www.k19.com.br
221
222
No arquivo template.xhtml, acrescente um link para o usurio fazer logout. O menu de navegao deve ser exibido apenas se o usurio estiver logado.
28
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
<! 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 > K19 Futebol </ title >
</ h : head >
<h : body >
<h : outputStylesheet library = " css " name = " style . css " / >
< div id = " header " >
<h : form style = " float : left ; " rendered = " #{ not empty sessionScope . usuario } " >
<h : link value = " Times " outcome = " times " / >
& nbsp ;
<h : link value = " Jogadores " outcome = " jogadores " / >
& nbsp ;
<h : commandLink value = " Logout " action = " #{ autenticadorBean . registraSaida } " / >
</ h : form >
<h : graphicImage library = " imagens " name = " k19 - logo . png " style = " float : right ; " / >
< div style = " clear : both " > </ div >
</ div >
< div id = " conteudo " >
< ui : insert name = " conteudo " > Espao para o contedo da tela </ ui : insert >
</ div >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2012 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML C.9: template.xhtml
29
http://localhost:8080/K19-Futebol/login.xhtml
222
www.k19.com.br
APNDICE
R ESPOSTAS
import
import
import
import
1
2
www.k19.com.br
223
R ESPOSTAS
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
224
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
224
import
import
import
import
www.k19.com.br
225
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
R ESPOSTAS
String sql = " SELECT * FROM Livro ; " ;
PreparedStatement comando = conexao . prepareStatement ( sql ) ;
System . out . println ( " Executando comando ... " ) ;
ResultSet resultado = comando . executeQuery () ;
System . out . println ( " Resultados encontrados : \ n " ) ;
while ( resultado . next () ) {
System . out . printf ( " ID : % d - TTULO : % s - PREO : % f - EDITORA : % d \ n " ,
resultado . getInt ( " id " ) ,
resultado . getString ( " titulo " ) ,
resultado . getDouble ( " preco " ) ,
resultado . getInt ( " editora_id " ) ) ;
}
System . out . println ( " \ nFechando conexo ... " ) ;
conexao . close () ;
} catch ( Exception e ) {
e . printStackTrace () ;
}
}
}
Cdigo Java 2.18: ListaLivros.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
www.k19.com.br
225
R ESPOSTAS
38
39
40
226
}
}
}
Cdigo Java 2.23: InsereLivros.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
226
@ManagedBean
public class ContatoSACBean {
private String nome ;
private String email ;
private String codigoDeArea ;
private String numeroDoTelefone ;
private Integer numeroDoPedido ;
private String assunto ;
private String comentario ;
private Boolean sexoFeminino ;
private List < String > assuntos = new ArrayList < String >() ;
public ContatoSACBean () {
assuntos . add ( " Entrega " ) ;
assuntos . add ( " Pagamento " ) ;
www.k19.com.br
227
20
21
22
23
24
25
26
R ESPOSTAS
assuntos . add ( " Trocas ou devolues " ) ;
assuntos . add ( " Dvidas gerais " ) ;
assuntos . add ( " Comentrios " ) ;
}
// GETTERS E SETTERS
}
Cdigo Java 6.8: ContatoSACBean.java
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Servio de Atendimento ao Consumidor </ h1 >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Nome : " for = " campo - nome " / >
<h : inputText value = " #{ contatoSACBean . nome } " id = " campo - nome " / >
<h : outputLabel value = "E - mail : " for = " campo - email " / >
<h : inputText value = " #{ contatoSACBean . email } " id = " campo - email " / >
<h : outputLabel value = " Telefone : " for = " campo - telefone " / >
<h : panelGroup >
( <h : inputText value = " #{ contatoSACBean . codigoDeArea } " id = " campo - telefone "
size = " 2 " / >)
<h : inputText value = " #{ contatoSACBean . numeroDoTelefone } " / > ( DDD ) XXXX - XXXX
</ h : panelGroup >
<h : outputLabel value = " Sexo : " for = " campo - sexo " / >
<h : selectOneRadio value = " #{ contatoSACBean . sexoFeminino } " id = " campo - sexo " >
<f : selectItem itemLabel = " Feminino " itemValue = " true " / >
<f : selectItem itemLabel = " Masculino " itemValue = " false " / >
</ h : selectOneRadio >
<h : outputLabel value = " Nmero do pedido : " for = " campo - pedido " / >
<h : inputText value = " #{ contatoSACBean . numeroDoPedido } " id = " campo - pedido " / >
<h : outputLabel value = " Assunto " for = " campo - assunto " / >
<h : selectOneMenu value = " #{ contatoSACBean . assunto } " >
<f : selectItem noSelectionOption = " true " itemLabel = " Escolha um assunto " / >
<f : selectItems
value = " #{ contatoSACBean . assuntos } "
var = " assunto "
itemLabel = " #{ assunto } "
itemValue = " #{ assunto } " / >
</ h : selectOneMenu >
<h : outputLabel value = " Comentrio : " for = " campo - comentario " / >
<h : inputTextarea value = " #{ contatoSACBean . comentario } " id = " campo - comentario " / >
<h : commandButton value = " Enviar " / >
</ h : panelGrid >
</ h : form >
</ h : body >
</ html >
www.k19.com.br
227
R ESPOSTAS
228
Acesse a aplicao em
http://localhost:8080/K19-Componentes-Visuais/contato-sac.xhtml
Resposta do Complementar 6.2
Primeiramente, crie a classe Produto no diretrio src do projeto K19-Componentes-Visuais.
1
2
3
4
5
6
7
8
9
10
11
@ManagedBean
public class ProdutosBean {
private List < Produto > produtos = new ArrayList < Produto >() ;
public ProdutosBean () {
this . produtos . add ( new
this . produtos . add ( new
this . produtos . add ( new
this . produtos . add ( new
this . produtos . add ( new
}
// GETTER E SETTER
}
Cdigo Java 6.13: ProdutosBean.java
Finalmente, crie o arquivo lista-de-produtos.xhtml na pasta WebContent e implemente a listagem dos produtos.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
228
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : dataTable value = " #{ produtosBean . produtos } " var = " produto " >
<f : facet name = " header " > Lista de produtos </ f : facet >
<h : column >
www.k19.com.br
229
16
17
18
19
20
21
22
23
24
25
26
27
28
R ESPOSTAS
<f : facet name = " header " > Nome </ f : facet >
#{ produto . nome }
</ h : column >
<h : column >
<f : facet name = " header " > Preo </ f : facet >
<h : outputFormat value = " {0 , number , R$ .00} " >
<f : param value = " #{ produto . preco } " / >
</ h : outputFormat >
</ h : column >
</ h : dataTable >
</ h : body >
</ html >
Cdigo XHTML 6.51: lista-de-produtos.xhtml
http://localhost:8080/K19-Componentes-Visuais/lista-de-produtos.xhtml
Resposta do Complementar 6.3
Na classe Produto, adicione um atributo booleano chamado mostraPreco.
1
2
3
4
5
6
7
8
9
10
11
12
13
Modifique a tabela de forma a exibir somente os preos dos produtos para os quais a propriedade
mostraPreco seja verdadeira. Use o atributo rendered para determinar quando um componente
deve ser exibido.
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 : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : dataTable value = " #{ produtosBean . produtos } " var = " produto " >
<f : facet name = " header " > Lista de produtos </ f : facet >
<h : column >
<f : facet name = " header " > Nome </ f : facet >
#{ produto . nome }
</ h : column >
<h : column >
www.k19.com.br
229
R ESPOSTAS
21
22
23
24
25
26
27
28
29
30
230
<f : facet name = " header " > Preo </ f : facet >
<h : outputFormat value = " {0 , number , R$ .00} " rendered = " #{ produto . mostraPreco } " >
<f : param value = " #{ produto . preco } " / >
</ h : outputFormat >
<h : outputText value = " Adicione o produto ao carrinho para ver o preo "
rendered = " #{! produto . mostraPreco } " / >
</ h : column >
</ h : dataTable >
</ h : body >
</ html >
Cdigo XHTML 6.52: lista-de-produtos.xhtml
@ManagedBean
public class ProdutosBean {
private List < Produto > produtos = new ArrayList < Produto >() ;
public ProdutosBean () {
this . produtos . add ( new Produto ( " Camiseta branca " , 29.90) ) ;
this . produtos . add ( new Produto ( " Camiseta preta " , 39.99) ) ;
this . produtos . add ( new Produto ( " Cala jeans " , 95.99) ) ;
this . produtos . add ( new Produto ( " Gravata " , 19.90) ) ;
Produto produto = new Produto ( " Terno " , 289.95) ;
produto . setMostraPreco ( false ) ;
this . produtos . add ( produto ) ;
}
// GETTER E SETTER
}
Cdigo Java 6.15: ProdutosBean.java
http://localhost:8080/K19-Componentes-Visuais/lista-de-produtos.xhtml
Resposta do Complementar 6.4
Essa mensagem pode ser criada no mtodo adicionaCurso() do managed bean cursosBean. Nesse
mtodo, adicione uma mensagem usando o mtodo addMessage() da classe FacesContext.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
230
@ManagedBean
@SessionScoped
public class CursosBean {
private List < Curso > cursos = new ArrayList < Curso >() ;
private Curso curso = new Curso () ;
public void adicionaCurso () {
this . cursos . add ( this . curso ) ;
this . curso = new Curso () ;
this . adicionaMensagemDeConfirmacao ( curso ) ;
}
private void adicionaMensagemDeConfirmacao ( Curso curso ) {
FacesMessage mensagem = new FacesMessage ( " O curso " + curso . getSigla ()
+ " - " + curso . getNome () + " foi adicionado " ) ;
FacesContext . getCurrentInstance () . addMessage (
" form - adiciona : botao - adiciona " , mensagem ) ;
}
// GETTERS E SETTERS
}
www.k19.com.br
231
R ESPOSTAS
Modifique o arquivo cursos.xhtml para exibir a mensagem. Faa isso usando a tag <h:message>,
como mostrado abaixo.
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
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form id = " form - adiciona " >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Sigla : " for = " campo - sigla " / >
<h : inputText value = " #{ cursosBean . curso . sigla } " id = " campo - sigla " / >
<h : outputLabel value = " Nome : " for = " campo - nome " / >
<h : inputText value = " #{ cursosBean . curso . nome } " id = " campo - nome " / >
<h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } "
id = " botao - adiciona " / >
</ h : panelGrid >
</ h : form >
<p > <h : message for = " botao - adiciona " style = " color : green " / > </ p >
<h : dataTable value = " #{ cursosBean . cursos } " var = " curso "
rendered = " #{ not empty cursosBean . cursos } " >
<f : facet name = " header " > Lista de Cursos </ f : facet >
<h : column >
<f : facet name = " header " > Sigla </ f : facet >
#{ curso . sigla }
</ h : column >
<h : column >
<f : facet name = " header " > Nome </ f : facet >
#{ curso . nome }
</ h : column >
</ h : dataTable >
</ h : body >
</ html >
Cdigo XHTML 6.59: cursos.xhtml
http://localhost:8080/K19-Componentes-Visuais/cursos.xhtml
Resposta do Complementar 7.1
No pacote model, crie uma classe chamada Produto para representar os produtos da loja.
1
2
3
package model ;
public class Produto {
www.k19.com.br
231
R ESPOSTAS
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private
private
private
private
private
232
String nome ;
String descricao ;
String caminhoDaFigura ;
double preco ;
int id ;
Na pasta WebContent do projeto, crie um diretrio chamado imagens. Copie os arquivos da pasta
K19-Arquivos/imagens/loja-virtual para o diretrio WebContent/imagens.
No pacote managedbeans, crie uma classe chamada ProdutosBean. Essa classe deve armazenar
uma lista de produtos e deve ter um atributo para guardar o produto cujos detalhes devem ser exibidos.
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
232
package managedbeans ;
@ManagedBean
public class ProdutosBean {
private Produto produtoSelecionado ;
private int idDoProdutoSelecionado ;
private List < Produto > produtos = new ArrayList < Produto >() ;
public ProdutosBean () {
this . produtos . add ( new Produto (
" Camiseta branca " ,
" Esta uma camiseta bsica na cor branca . Ela feita de algodo e " +
" est disponvel nos tamanhos P , M e G . " ,
" / imagens / camiseta - branca . png " , 29.90 , 1) ) ;
this . produtos . add ( new Produto (
" Camiseta preta " ,
" Esta uma camiseta na cor preta , que est disponvel " +
" nos tamanhos P , M e G . Seu material 100% algodo . " ,
" / imagens / camiseta - preta . png " , 39.90 , 2) ) ;
this . produtos . add ( new Produto (
" Cala jeans " ,
" Cala jeans disponvel nos tamanhos 38 a 50. " ,
" / imagens / calca - jeans . png " , 95.99 , 3) ) ;
this . produtos . add ( new Produto (
" Terno " ,
" Terno de seda na cor cinza . " ,
" / imagens / terno . png " , 589.95 , 4) ) ;
this . produtos . add ( new Produto (
" Gravata " ,
" Gravata nas cores vermelha , azul e verde . " ,
" / imagens / gravatas . png " , 19.90 , 5) ) ;
this . produtoSelecionado = this . produtos . get (0) ;
}
www.k19.com.br
233
40
41
42
43
44
45
46
47
48
49
50
51
R ESPOSTAS
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< div id = " header " >
< h1 > Loja virtual </ h1 >
< hr / >
</ div >
< ui : insert name = " conteudo " / >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2012 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML 7.13: template-loja-virtual.xhtml
No diretrio WEB-INF, crie um diretrio com o nome includes.No diretrio includes, crie um
arquivo chamado produto-info.xhtml e implemente o pedao da tela responsvel por exibir os
detalhes de um produto. O produto particular a ser exibido deve ser passado como parmetro para
esse arquivo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
< ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : panelGrid columns = " 2 " cellspacing = " 5 " >
<h : graphicImage value = " #{ produto . caminhoDaFigura } " width = " 100 " / >
<h : panelGroup >
< h2 > #{ produto . nome } </ h2 >
Preo :
<h : outputFormat value = " {0 , number , R$ .00} " style = " color : red " >
<f : param value = " #{ produto . preco } " / >
</ h : outputFormat >
www.k19.com.br
233
R ESPOSTAS
15
16
17
18
19
20
21
234
Note que o parmetro para o arquivo produto-info.xhtml deve se chamar produto. No diretrio WebContent, crie um arquivo chamado loja.xhtml. Esse arquivo usar o template que voc
acabou de criar. O contedo da pgina ser formado pela caixa de seleo de produto e pelo pedao
de tela de informaes do produto.
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
< ui : composition
template = " / WEB - INF / templates / template - loja - virtual . xhtml "
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
< ui : define name = " conteudo " >
<h : form >
<h : selectOneMenu value = " #{ produtosBean . idDoProdutoSelecionado } " >
<f : selectItems
value = " #{ produtosBean . produtos } "
var = " produto "
itemValue = " #{ produto . id } "
itemLabel = " #{ produto . nome } " >
</ f : selectItems >
</ h : selectOneMenu >
<h : commandButton value = " Detalhes " action = " #{ produtosBean . carregaProduto } " / >
</ h : form >
< ui : include src = " / WEB - INF / includes / produto - info . xhtml " >
< ui : param name = " produto " value = " #{ produtosBean . produtoSelecionado } " / >
</ ui : include >
</ ui : define >
</ ui : composition >
Cdigo XHTML 7.15: loja.xhtml
http://localhost:8080/K19-Templates-e-Modularizacao/loja.xhtml
Resposta do Complementar 8.1
Primeiramente, crie um pacote chamado managedbeans na pasta src do projeto K19-Navegacao.
Nesse pacote, crie uma classe chamada UsuarioBean e implemente um managed bean para armazenar a preferncia do usurio.
1
2
3
4
5
6
234
package managedbeans ;
@SessionScoped
@ManagedBean
public class UsuarioBean {
private String versaoPreferida = " Simples " ;
www.k19.com.br
235
7
8
9
10
11
12
13
14
15
16
R ESPOSTAS
O mtodo principal() da classe UsuarioBean ser usado para determinar a pgina de resposta
quando o link para a pgina principal for clicado.
Na pasta WebContent/WEB-INF, crie um diretrio chamado templates. Nesse diretrio, crie um
arquivo chamado template-aplicacao.xhtml para implementar um template para as pginas da
aplicao.
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 "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< div id = " header " style = " text - align : center " >
<h : outputText value = " Loja Virtual " style = " font - size : 36 px ; font - weight : bold " / >
<h : form >
<h : commandLink value = " Pgina principal " action = " #{ usuarioBean . principal } " / >
<h : link value = " Configuraes " outcome = " configuracoes " / >
</ h : form >
</ div >
< ui : insert name = " conteudo " / >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2012 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML 8.18: template-aplicacao.xhtml
Note que o menu para navegar entre as pginas da aplicao foi definido nesse arquivo. Observe que a navegao para a pgina de configuraes foi definida de forma esttica, enquanto que
a navegao para a pgina principal foi definida de forma dinmica.
No diretrio WebContent, crie dois arquivos chamados principal-simples.xhtml e principal-avancada.xhtml para implementar as verses simples e avanada da pgina principal, respectivamente.
1
2
< ui : composition template = " / WEB - INF / templates / template - aplicacao . xhtml "
xmlns = " http :// www . w3 . org /1999/ xhtml "
www.k19.com.br
235
R ESPOSTAS
3
4
5
6
7
8
9
10
11
12
236
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
< ui : define name = " conteudo " >
< h1 > Pgina Principal Simples </ h1 >
< ul >
< li > <h : link > Visualizar produtos cadastrados </ h : link > </ li >
</ ul >
</ ui : define >
</ ui : composition >
Cdigo XHTML 8.19: principal-simples.xhtml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< ui : composition template = " / WEB - INF / templates / template - aplicacao . xhtml "
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
< ui : define name = " conteudo " >
< h1 > Pgina Principal Avanada </ h1 >
< ul >
< li > <h : link > Visualizar produtos cadastrados </ h : link > </ li >
< li > <h : link > Editar produtos cadastrados </ h : link > </ li >
< li > <h : link > Adicionar ou remover produtos </ h : link > </ li >
< li > <h : link > Adicionar ou remover usurios </ h : link > </ li >
</ ul >
</ ui : define >
</ ui : composition >
Cdigo XHTML 8.20: principal-avancada.xhtml
Finalmente, na pasta WebContent, crie um arquivo chamado configuracoes.xhtml para implementar a pgina da aplicao em que o usurio pode alterar suas preferncias.
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
< ui : composition template = " / WEB - INF / templates / template - aplicacao . xhtml "
xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
< ui : define name = " conteudo " >
< h1 > Configuraes </ h1 >
<p > Voc est usando a verso <b > #{ usuarioBean . versaoPreferida } </ b >
da aplicao . Se desejar , escolha outra verso abaixo e clique no
boto " Salvar " . </ p >
<h : form >
<h : panelGrid columns = " 3 " >
<h : outputLabel value = " Verso da aplicao : " for = " versao " / >
<h : selectOneMenu value = " #{ usuarioBean . versaoPreferida } " id = " versao " >
<f : selectItem itemLabel = " Simples " itemValue = " Simples " / >
<f : selectItem itemLabel = " Avanada " itemValue = " Avanada " / >
</ h : selectOneMenu >
<h : commandButton value = " Salvar " / >
</ h : panelGrid >
</ h : form >
</ ui : define >
</ ui : composition >
Cdigo XHTML 8.21: configuracoes.xhtml
www.k19.com.br
237
R ESPOSTAS
http://localhost:8080/K19-Navegacao/principal-simples.xhtml
Resposta do Complementar 8.2
No arquivo template-aplicacao.xhtml, altere o link para a pgina principal para que ele emita o
sinal "principal".
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 "
xmlns : f = " http :// java . sun . com / jsf / core "
xmlns : ui = " http :// java . sun . com / jsf / facelets " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< div id = " header " style = " text - align : center " >
<h : outputText value = " Loja Virtual " style = " font - size : 36 px ; font - weight : bold " / >
<h : form >
<h : link value = " Pgina principal " outcome = " principal " / >
<h : link value = " Configuraes " outcome = " configuracoes " / >
</ h : form >
</ div >
< ui : insert name = " conteudo " / >
< div id = " footer " style = " text - align : center " >
< hr / >
& copy ; 2012 K19 . Todos os direitos reservados .
</ div >
</ h : body >
</ html >
Cdigo XHTML 8.22: template-aplicacao.xhtml
...
< navigation - rule >
< from - view - id >* </ from - view - id >
< navigation - case >
< from - outcome > principal </ from - outcome >
< if > #{ usuarioBean . versaoPreferida == Simples } </ if >
<to - view - id > principal - simples . xhtml </ to - view - id >
</ navigation - case >
< navigation - case >
< from - outcome > principal </ from - outcome >
< if > #{ usuarioBean . versaoPreferida == Avanada } </ if >
<to - view - id > principal - avancada . xhtml </ to - view - id >
</ navigation - case >
</ navigation - rule >
...
www.k19.com.br
237
R ESPOSTAS
238
http://localhost:8080/K19-Navegacao/principal-simples.xhtml
Resposta do Complementar 10.1
No diretrio src do projeto K19-Conversao-e-Validacao, crie um pacote chamado model. Nesse
pacote, crie uma classe chamada Cotacao para modelar a cotao de uma moeda.
1
2
3
4
5
6
7
8
9
package model ;
public class Cotacao {
private Double valor ;
private Double variacao ;
private Date horario ;
// GETTERS E SETTERS
}
Cdigo Java 10.4: Cotacao.java
Crie um pacote chamado managedbeans no diretrio src. Nesse pacote, crie uma classe chamada
CotacaoBean para armazenar os valores submetidos pelo formulrio.
1
2
3
4
5
6
7
8
package managedbeans ;
@ManagedBean
public class CotacaoBean {
private Cotacao cotacao = new Cotacao () ;
// GETTER E SETTER
}
Cdigo Java 10.5: CotacaoBean.java
238
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Registrar cotao do dlar </ h1 >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Valor : " for = " valor " / >
<h : panelGroup >
<h : inputText value = " #{ cotacaoBean . cotacao . valor } " id = " valor " required = " true " >
<f : convertNumber locale = " pt_BR " type = " currency " / >
</ h : inputText >
<h : message for = " valor " style = " color : red " / >
www.k19.com.br
239
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
R ESPOSTAS
</ h : panelGroup >
<h : outputLabel value = " Variao : " for = " variacao " / >
<h : panelGroup >
<h : inputText value = " #{ cotacaoBean . cotacao . variacao } " id = " variacao " required = " true " >
<f : convertNumber maxFractionDigits = " 5 " type = " percent " / >
</ h : inputText >
<h : message for = " variacao " style = " color : red " / >
</ h : panelGroup >
<h : outputLabel value = " Horrio : " for = " horario " / >
<h : panelGroup >
<h : inputText value = " #{ cotacaoBean . cotacao . horario } " id = " horario " required = " true " >
<f : convertDateTime pattern = " HH : mm dd - MM - yyyy " / >
</ h : inputText >
<h : message for = " horario " style = " color : red " / >
</ h : panelGroup >
<h : commandButton value = " Registrar " / >
</ h : panelGrid >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 10.9: registrar-cotacao.xhtml
http://localhost:8080/K19-Conversao-e-Validacao/registrar-cotacao.xhtml
Resposta do Complementar 10.2
No arquivo registrar-cotacao.xhtml, adicione as linhas em destaque do cdigo abaixo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
" http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
< html xmlns = " http :// www . w3 . org /1999/ xhtml "
xmlns : h = " http :// java . sun . com / jsf / html "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Registrar cotao do dlar </ h1 >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Valor : " for = " valor " / >
<h : panelGroup >
<h : inputText value = " #{ cotacaoBean . cotacao . valor } " id = " valor " required = " true " >
<f : convertNumber locale = " pt_BR " type = " currency " / >
</ h : inputText >
<h : message for = " valor " style = " color : red " / >
</ h : panelGroup >
<h : outputLabel value = " Variao : " for = " variacao " / >
<h : panelGroup >
<h : inputText value = " #{ cotacaoBean . cotacao . variacao } " id = " variacao " required = " true " >
<f : convertNumber maxFractionDigits = " 5 " type = " percent " / >
</ h : inputText >
<h : message for = " variacao " style = " color : red " / >
</ h : panelGroup >
www.k19.com.br
239
R ESPOSTAS
30
31
32
33
240
<h : outputLabel value = " Horrio : " for = " horario " / >
<h : panelGroup >
<h : inputText value = " #{ cotacaoBean . cotacao . horario } " id = " horario " required = " true " >
<f : convertDateTime pattern = " HH : mm dd - MM - yyyy " / >
</ h : inputText >
<h : message for = " horario " style = " color : red " / >
</ h : panelGroup >
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
http://localhost:8080/K19-Conversao-e-Validacao/registrar-cotacao.xhtml
Altere o valor do atributo timeZone do componente <f:convertDateTime>. Use, por exemplo,
os valores GMT-2 e GMT-3. Teste o formulrio novamente.
Resposta do Complementar 10.3
No diretrio src do projeto K19-Conversao-e-Validacao, crie um pacote chamado model. Nesse
pacote, crie uma classe chamada Produto.
1
2
3
4
5
6
7
8
9
10
package model ;
public class Produto {
private String nome ;
private String codigo ;
private Integer tamanho ;
private Double volume ;
// GETTERS E SETTERS
}
Cdigo Java 10.7: Produto.java
Crie um pacote chamado managedbeans no diretrio src. Nesse pacote, crie uma classe chamada
ProdutoBean.
1
2
3
4
5
6
7
8
240
package managedbeans ;
@ManagedBean
public class ProdutoBean {
private Produto produto = new Produto () ;
// GETTER E SETTER
}
www.k19.com.br
241
R ESPOSTAS
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
< h1 > Cadastro de Produtos </ h1 >
<h : form >
<h : panelGrid columns = " 2 " >
<h : outputLabel value = " Nome : " for = " nome " / >
<h : panelGroup >
<h : inputText value = " #{ produtoBean . produto . nome } " id = " nome " required = " true " >
<f : validateRegex pattern = " [a - zA - Z \ s ]+ " / >
</ h : inputText >
<h : message for = " nome " style = " color : red " / >
</ h : panelGroup >
<h : outputLabel value = " Cdigo : " for = " codigo " / >
<h : panelGroup >
<h : inputText value = " #{ produtoBean . produto . codigo } " id = " codigo " required = " true " >
<f : validateRegex pattern = " [A - Z ][0 -9]+ " / >
<f : validateLength minimum = " 4 " maximum = " 10 " / >
</ h : inputText >
<h : message for = " codigo " style = " color : red " / >
</ h : panelGroup >
<h : outputLabel value = " Tamanho : " for = " tamanho " / >
<h : panelGroup >
<h : inputText value = " #{ produtoBean . produto . tamanho } " id = " tamanho " >
<f : validateRequired / >
<f : validateLongRange minimum = " 1 " maximum = " 32 " / >
</ h : inputText >
<h : message for = " tamanho " style = " color : red " / >
</ h : panelGroup >
<h : outputLabel value = " Volume : " for = " volume " / >
<h : panelGroup >
<h : inputText value = " #{ produtoBean . produto . volume } " id = " volume " >
<f : validateRequired / >
<f : validateDoubleRange minimum = " 0.1 " / >
</ h : inputText >
<h : message for = " volume " style = " color : red " / >
</ h : panelGroup >
<h : commandButton value = " Enviar " / >
</ h : panelGrid >
</ h : form >
</ h : body >
</ html >
Cdigo XHTML 10.22: cadastro-de-produtos.xhtml
241
R ESPOSTAS
242
http://localhost:8080/K19-Conversao-e-Validacao/cadastro-de-produtos.xhtml
Resposta do Complementar 10.4
Na pasta src do projeto K19-Conversao-e-Validacao, crie um pacote chamado model. Nesse pacote, crie uma classe chamada RIC.
1
2
3
4
5
6
7
8
package model ;
public class RIC {
private String numeroDeIdentificacao ;
private String digitoVerificador ;
// GETTERS E SETTERS
}
Cdigo Java 10.20: RIC.java
Na pasta src, crie um pacote chamado converters. Nesse pacote, crie uma classe chamada
ConversorDeRIC e implemente o conversor.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package converters ;
@FacesConverter ( forClass = RIC . class )
public class ConversorDeRIC implements Converter {
@Override
public Object getAsObject ( FacesContext context , UIComponent component ,
String value ) {
String ricString = value . trim () ;
if (! Pattern . matches ( " [0 -9]{10}[ -]?[0 -9] " , ricString ) ) {
FacesMessage mensagem = new FacesMessage ( " Nmero RIC invlido " ) ;
mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
throw new ConverterException ( mensagem ) ;
}
ricString = ricString . replaceAll ( " -" , " " ) ;
RIC ric = new RIC () ;
ric . setNumeroDeIdentificacao ( ricString . substring (0 , 10) ) ;
ric . setDigitoVerificador ( ricString . substring (10 , 11) ) ;
return ric ;
}
@Override
public String getAsString ( FacesContext context , UIComponent component ,
Object value ) {
RIC ric = ( RIC ) value ;
return ric . getNumeroDeIdentificacao () + " -" + ric . getDigitoVerificador () ;
}
}
Cdigo Java 10.21: ConversorDeRIC.java
Agora, voc deve testar o seu conversor. Na pasta src, crie um pacote chamado managedbeans.
Nesse pacote, crie uma classe chamada RICBean e implemente o managed bean que dar suporte ao
seu formulrio.
1
2
242
package managedbeans ;
www.k19.com.br
243
3
4
5
6
7
8
R ESPOSTAS
@ManagedBean
public class RICBean {
private RIC ric ;
// GETTER E SETTER
}
Cdigo Java 10.22: RICBean.java
<! 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : form >
<h : outputLabel value = " RIC : " for = " campo - ric " / >
<h : inputText id = " campo - ric " value = " #{ rICBean . ric } " / >
<h : commandButton value = " Enviar " / >
</ h : form >
<h : message for = " campo - ric " style = " color : red " / >
</ h : body >
</ html >
Cdigo XHTML 10.26: ric.xhtml
http://localhost:8080/K19-Conversao-e-Validacao/ric.xhtml
Resposta do Complementar 10.5
Primeiro, implemente o managed bean que armazenar a data escolhida pelo usurio. No diretrio
src do projeto K19-Conversao-e-Validacao, crie um pacote chamado managedbeans. Nesse pacote, adicione a seguinte classe.
1
2
3
4
5
6
7
8
9
package managedbeans ;
@ManagedBean
public class ReservaBean {
private Date data ;
// GETTER E SETTER
}
Cdigo Java 10.27: ReservaBean.java
<! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
www.k19.com.br
243
R ESPOSTAS
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
244
" 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 "
xmlns : f = " http :// java . sun . com / jsf / core " >
<h : head >
< title > K19 Treinamentos </ title >
</ h : head >
<h : body >
<h : outputText value = " Escolha uma data entre 01/05/2014 e 30/08/2014. " / >
<h : form >
<h : outputLabel value = " Data : ( dd / MM / yyyy ) " for = " campo - data " / >
<h : inputText id = " campo - data " value = " #{ reservaBean . data } " required = " true " >
<f : convertDateTime pattern = " dd / MM / yyyy " / >
<f : validator validatorId = " validators . ValidadorDeData " / >
<f : attribute name = " padraoDeData " value = " dd / MM / yyyy " / >
<f : attribute name = " inicio " value = " 01/05/2014 " / >
<f : attribute name = " fim " value = " 30/08/2014 " / >
</ h : inputText >
<h : commandButton value = " Enviar " / >
</ h : form >
<h : message for = " campo - data " style = " color : red " / >
</ h : body >
</ html >
Cdigo XHTML 10.30: reserva.xhtml
Crie um pacote chamado validators no diretrio src. Nesse pacote, crie uma classe chamada
ValidadorDeData para implementar o validador.
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
244
package validators ;
@FacesValidator ( " validators . ValidadorDeData " )
public class ValidadorDeData implements Validator {
@Override
public void validate ( FacesContext context , UIComponent component ,
Object value ) throws ValidatorException {
String padraoDeData = ( String ) component . getAttributes () . get ( " padraoDeData " ) ;
String inicio = ( String ) component . getAttributes () . get ( " inicio " ) ;
String fim = ( String ) component . getAttributes () . get ( " fim " ) ;
Date data = ( Date ) value ;
Date dataInicio ;
Date dataFim ;
try {
dataInicio = ( Date ) new SimpleDateFormat ( padraoDeData ) . parse ( inicio ) ;
dataFim = ( Date ) new SimpleDateFormat ( padraoDeData ) . parse ( fim ) ;
} catch ( ParseException e ) {
FacesMessage mensagem = new FacesMessage (
" Erro ao criar as datas de incio e fim do intervalo . " ) ;
mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
throw new ValidatorException ( mensagem ) ;
}
if ( data . before ( dataInicio ) || data . after ( dataFim ) ) {
FacesMessage mensagem = new FacesMessage (
" A data escolhida precisa estar entre " + inicio + " e " + fim ) ;
mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
throw new ValidatorException ( mensagem ) ;
www.k19.com.br
245
33
34
35
R ESPOSTAS
}
}
}
Cdigo Java 10.28: ValidadorDeData.java
http://localhost:8080/K19-Conversao-e-Validacao/reserva.xhtml
Teste o formulrio submetendo-o com diversas datas diferentes, inclusive com datas nos extremos do intervalo permitido.
Agora, modifique o arquivo reserva.xhtml de forma que o conversor de datas considere o fuso
horrio da cidade de So Paulo, como no trecho de cdigo abaixo.
1
2
3
...
<f : convertDateTime pattern = " dd / MM / yyyy " timeZone = " GMT -3 " / >
...
Cdigo XHTML 10.31: reserva.xhtml
www.k19.com.br
245