You are on page 1of 314

TREINAMENTOS

Desenvolvimento Web
com JSF2 e JPA2
Desenvolvimento Web com JSF 2.2 e JPA 2.1

22 de agosto de 2015
As apostilas atualizadas esto disponveis em www.k19.com.br

Esta apostila contm:

270 exerccios de fixao.


32 exerccios complementares.
2 desafios.
0 questes de prova.

Sumrio i

Sobre a K19 1

Seguro Treinamento 2

Termo de Uso 3

Cursos 4

1 Banco de dados 1
1.1 Sistemas Gerenciadores de Banco de Dados . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2 MySQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3 Bases de dados (Databases) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4 Criando uma base de dados no MySQL Server . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5 Tabelas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6 Criando tabelas no MySQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.7 CRUD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.8 Chaves Primria e Estrangeira . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.10 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2 JDBC 27
2.1 Driver . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.2 JDBC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

www.facebook.com/k19treinamentos i
S UMRIO ii

2.3 Instalando o Driver JDBC do MySQL Server . . . . . . . . . . . . . . . . . . . . . . . . . . 30


2.4 Criando uma conexo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
2.5 Inserindo registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
2.7 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.8 SQL Injection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
2.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
2.10 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
2.11 Listando registros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
2.12 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.13 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.14 Connection Factory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.15 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
2.16 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
2.17 Desafios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40

3 JPA 2.1 e Hibernate 41


3.1 Mltiplas sintaxes da linguagem SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.2 Orientao a Objetos VS Modelo Relacional . . . . . . . . . . . . . . . . . . . . . . . . . . 41
3.3 Ferramentas ORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.4 O que JPA e Hibernate? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.5 Bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.6 Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.7 Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.8 Gerando Tabelas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
3.10 Manipulando entidades . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.11 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.12 Repository . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.13 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56

4 Web Container 59
4.1 Necessidades de uma aplicao web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
4.2 Web Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4.3 Servlet e Java EE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
4.5 Aplicao Web Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.7 Processando requisies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.8 Servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
4.10 Frameworks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

5 Viso Geral do JSF 2.2 83


5.1 MVC e Front Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.2 Configurando uma aplicao JSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.3 Managed Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
5.4 Processamento de uma requisio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
5.5 Exemplo Prtico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
5.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93

ii www.k19.com.br
iii S UMRIO

6 Componentes Visuais 99
6.1 Estrutura Bsica de uma Pgina JSF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
6.2 Formulrios . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.3 Caixas de Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
6.4 Campos Ocultos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
6.5 Caixas de Seleo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
6.6 Botes e Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
6.7 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
6.8 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
6.9 Textos e Imagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
6.10 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.11 Componentes de Organizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.12 Tabelas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
6.13 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
6.14 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
6.15 Mensagens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
6.16 Adicionando JavaScript e CSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
6.17 Outros Componentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
6.18 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
6.19 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

7 Templates e Modularizao 131


7.1 Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
7.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
7.3 Modularizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
7.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
7.5 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

8 Navegao 141
8.1 Navegao Implcita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
8.2 Navegao Explcita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
8.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
8.4 Navegaes Esttica e Dinmica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
8.5 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
8.6 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151

9 Escopos 153
9.1 Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
9.2 View . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
9.3 Session . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
9.4 Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
9.5 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157

10 Converso e Validao 163


10.1 Converso . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
10.2 Conversores Padro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
10.3 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
10.4 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
10.5 Mensagens de Erro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
10.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170

www.facebook.com/k19treinamentos iii
S UMRIO iv

10.7 Validao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171


10.8 Validadores Padro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
10.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 172
10.10 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
10.11 Bean Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
10.12 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
10.13 Criando o seu Prprio Conversor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178
10.14 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
10.15 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
10.16 Criando o seu Prprio Validador . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
10.17 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
10.18 Exerccios Complementares . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
10.19 Criando o seu Prprio Bean Validator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
10.20 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189

11 Eventos 193
11.1 FacesEvent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
11.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
11.3 PhaseEvent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198
11.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
11.5 SystemEvent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
11.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
11.7 Immediate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
11.8 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 204

12 Ajax 209
12.1 Fazendo requisies AJAX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
12.2 Processando uma parte especfica da tela . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
12.3 Recarregando parte da tela . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
12.4 Associando um procedimento a uma requisio AJAX . . . . . . . . . . . . . . . . . . . . 211
12.5 Palavras especiais . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
12.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 212

13 Integrao JSF e JPA 215


13.1 Bibliotecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
13.2 Configurao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
13.3 Mapeamento . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
13.4 Inicializao e Finalizao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
13.5 Transaes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
13.6 Recuperando o EntityManager da Requisio . . . . . . . . . . . . . . . . . . . . . . . . . 218
13.7 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219
13.8 Otimizando o nmero de consultas ao SGDB . . . . . . . . . . . . . . . . . . . . . . . . . 224
13.9 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225

A Autenticao 229
A.1 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 229

B Pginas de Erro 235


B.1 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235

iv www.k19.com.br
v S UMRIO

C PrimeFaces 239
C.1 Instalao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
C.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
C.3 AutoComplete . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
C.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
C.5 Poll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
C.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
C.7 Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
C.8 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
C.9 InputMask . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
C.10 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
C.11 DataTable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
C.12 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246
C.13 DataExporter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
C.14 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
C.15 PickList . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
C.16 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
C.17 MegaMenu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
C.18 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
C.19 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
C.20 Chart . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
C.21 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257

D Projeto Futebol K19 261


D.1 Integrao JSF e JPA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
D.2 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
D.3 Modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
D.4 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
D.5 Managed Beans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
D.6 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
D.7 Telas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
D.8 Exerccios de Fixao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
D.9 Autenticao . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275

E Respostas 279

www.facebook.com/k19treinamentos v
S UMRIO vi

vi www.k19.com.br
1 S UMRIO

Sobre a K19
A K19 uma empresa especializada na capacitao de desenvolvedores de software. Sua equipe
composta por profissionais formados em Cincia da Computao pela Universidade de So Paulo
(USP) e que possuem vasta experincia em treinamento de profissionais para rea de TI.

O principal objetivo da K19 oferecer treinamentos de mxima qualidade e relacionados s prin-


cipais tecnologias utilizadas pelas empresas. Atravs desses treinamentos, seus alunos tornam-se
capacitados para atuar no mercado de trabalho.

Visando a mxima qualidade, a K19 mantm as suas apostilas em constante renovao e melho-
ria, oferece instalaes fsicas apropriadas para o ensino e seus instrutores esto sempre atualizados
didtica e tecnicamente.

www.facebook.com/k19treinamentos 1
S UMRIO 2

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 pos-
sui 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 Treina-
mento 10% do valor total do curso.

2 www.k19.com.br
3 S UMRIO

Termo de Uso
Termo de Uso
Todo o contedo desta apostila propriedade da K19 Treinamentos. A apostila pode ser utilizada
livremente para estudo pessoal . Alm disso, este material didtico pode ser utilizado como material
de apoio em cursos de ensino superior desde que a instituio correspondente seja reconhecida pelo
MEC (Ministrio da Educao) e que a K19 seja citada explicitamente como proprietria do material.

proibida qualquer utilizao desse material que no se enquadre nas condies acima sem
o prvio consentimento formal, por escrito, da K19 Treinamentos. O uso indevido est sujeito s
medidas legais cabveis.

www.facebook.com/k19treinamentos 3
S UMRIO 4

TR
EIN
AM
EN

TR
TO

EIN
S

TREINAMENTOS
AM
EN
TO
S
Conhea os nossos cursos

K01- Lgica de Programao

K02 - Desenvolvimento Web com HTML, CSS e JavaScript

K03 - SQL e Modelo Relacional

K11 - Orientao a Objetos em Java

K12 - Desenvolvimento Web com JSF2 e JPA2

K21 - Persistncia com JPA2 e Hibernate

K22 - Desenvolvimento Web Avanado com JFS2, EJB3.1 e CDI

K23 - Integrao de Sistemas com Webservices, JMS e EJB

K41 - Desenvolvimento Mobile com Android

K51 - Design Patterns em Java

K52 - Desenvolvimento Web com Struts

K31 - C# e Orientao a Objetos

K32 - Desenvolvimento Web com ASP.NET MVC

www.k19.com.br/cursos

4 www.k19.com.br
CAPTULO
B ANCO DE DADOS
1
Em geral, as aplicaes necessitam armazenar dados de forma persistente para consult-los pos-
teriormente. 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 fato-
res importantes nos levam a descartar tal opo. A seguir, apresentamos as principais dificuldades a
serem consideradas na persistncia de dados.

Segurana: O acesso s informaes potencialmente confidenciais deve ser controlado de forma


que apenas usurios e sistemas autorizados possam manipul-las.

Integridade: Restries relacionadas aos dados armazenados devem ser respeitadas para que as in-
formaes estejam sempre consistentes.

Consulta: O tempo gasto para realizar as consultas aos dados armazenados deve ser o menor poss-
vel.

Concorrncia: Em geral, diversos sistemas e usurios acessaro concorrentemente as informaes


armazenadas. Apesar disso, a integridade dos dados deve ser preservada.

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).

Figura 1.1: Sistema Gerenciador de Banco de Dados

Sistemas Gerenciadores de Banco de Dados

No mercado, h diversas opes de sistemas gerenciadores de banco de dados. Os mais popula-


res so:

Oracle Database

www.facebook.com/k19treinamentos 1
B ANCO DE DADOS 2

SQL Server
MySQL Server
PostgreSQL

MySQL Server

Neste treinamento, utilizaremos o MySQL Server, que mantido pela Oracle e amplamente utili-
zado 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/

Bases de dados (Databases)

Um sistema gerenciador de banco de dados capaz de gerenciar informaes de diversos siste-


mas ao mesmo tempo. Por exemplo, as informaes dos clientes de um banco, alm dos produtos
de uma loja virtual ou dos livros de uma livraria.

Suponha que os dados fossem mantidos sem nenhuma separao lgica. Implementar regras
de segurana especficas seria extremamente complexo. Tais regras criam restries quanto ao con-
tedo que pode ser acessado por cada usurio. Por exemplo, determinado usurio poderia ter per-
misso de acesso aos dados dos clientes do banco, mas no s informaes dos produtos da loja
virtual, ou dos livros da livraria.

Para obter uma organizao melhor, os dados so armazenados separadamente em um SGDB.


Da surge o conceito de base de dados (database). Uma base de dados um agrupamento lgico das
informaes de um determinado domnio.

Criando uma base de dados no MySQL Server

Para criar uma base de dados no MySQL Server, podemos utilizar o comando CREATE DATA-
BASE.

mysql > CREATE DATABASE livraria ;


Query OK , 1 row affected (0.02 sec )

Terminal 1.1: Criando uma base de dados.

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 )

Terminal 1.2: Listando as bases de dados existentes.

2 www.k19.com.br
3 B ANCO DE DADOS

Repare que, alm da base de dados livraria, h outras trs bases. Essas bases foram criadas au-
tomaticamente 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 )

Terminal 1.3: Destruindo uma base de dados.

Tabelas

Um servidor de banco de dados dividido em bases de dados com o intuito de separar as infor-
maes 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.

Cliente Conta
nome idade cpf numero saldo limite
Jos 27 31875638735 1 1000 500
Maria 32 30045667856 2 2000 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.

Criando tabelas no MySQL Server

As tabelas no MySQL Server so criadas atravs do comando CREATE TABLE. Na criao de uma
tabela, necessrio definir quais so os nomes e os tipos das colunas.

mysql > CREATE TABLE livraria . Livro (


-> titulo VARCHAR (255) ,
-> preco DOUBLE
-> )
-> ENGINE = MyISAM ;
Query OK , 0 rows affected (0.14 sec )

Terminal 1.4: Criando uma tabela.

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
mysql > SHOW TABLES ;

www.facebook.com/k19treinamentos 3
B ANCO DE DADOS 4

+ - - - - - - - - - - - - - - - - - - - -+
| Tables_in_livraria |
+ - - - - - - - - - - - - - - - - - - - -+
| Livro |
+ - - - - - - - - - - - - - - - - - - - -+
1 row in set (0.00 sec )

Terminal 1.5: Listando as tabelas de uma base 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 )

Terminal 1.6: Destruindo uma tabela.

CRUD

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 (Structu-
red Query Language). Essa linguagem oferece quatro comandos bsicos: INSERT, SELECT, UPDATE
e DELETE. Esses comandos so utilizados para inserir, ler, alterar e remover registros, respectiva-
mente.

mysql > INSERT INTO Livro ( titulo , preco ) VALUES ( Java , 98.75);
Query OK , 1 row affected (0.00 sec )

Terminal 1.7: Inserindo um registro.

mysql > SELECT * FROM Livro ;


+ - - - - - - - -+ - - - - - - -+
| titulo | preco |
+ - - - - - - - -+ - - - - - - -+
| Java | 98.75 |
+ - - - - - - - -+ - - - - - - -+
1 row in set (0.00 sec )

Terminal 1.8: Selecionando registros.

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

Terminal 1.9: Alterando registros.

mysql > SELECT * FROM Livro ;


+ - - - - - - - -+ - - - - - - -+
| titulo | preco |
+ - - - - - - - -+ - - - - - - -+
| Java | 115.9 |
+ - - - - - - - -+ - - - - - - -+
1 row in set (0.00 sec )

Terminal 1.10: Selecionando registros.

mysql > DELETE FROM Livro WHERE titulo = Java ;


Query OK , 1 row affected (0.00 sec )

Terminal 1.11: Removendo registros.

4 www.k19.com.br
5 B ANCO DE DADOS

mysql > SELECT * FROM Livro ;


Empty set (0.00 sec )

Terminal 1.12: Selecionando registros.

Chaves Primria e Estrangeira

Suponha que os livros da nossa livraria sejam classificados por editoras. As editoras possuem
nome e telefone. Para armazenar esses dados, uma nova tabela deveria ser criada.

Nesse momento, teramos duas tabelas (Livro e Editora). Constantemente, a aplicao da livraria
dever descobrir qual a editora de um determinado livro ou quais so os livros de uma determinada
editora. Para isso, os registros da tabela Editora devem estar relacionados aos da tabela Livro.

Na tabela Livro, poderamos adicionar uma coluna para armazenar o nome da editora dos livros.
Dessa forma, se algum quiser recuperar as informaes da editora de um determinado livro, deve
consultar a tabela Livro para obter o nome da editora correspondente. Depois, com esse nome, deve
consultar a tabela Editora para obter as informaes da editora.

Porm, h um problema nessa abordagem. A tabela Editora aceita duas editoras com o mesmo
nome. Dessa forma, eventualmente, no conseguiramos descobrir os dados corretos da editora de
um determinado livro. Para resolver esse problema, deveramos criar uma restrio na tabela Editora
que proba a insero de editoras com o mesmo nome.

Para resolver esse problema no MySQL Server, poderamos adicionar a propriedade UNIQUE no
campo nome da tabela Editora. Porm, ainda teramos mais um problema. Na tabela Livro, pode-
ramos adicionar registros vinculados a editoras inexistentes, pois no h nenhuma relao explcita
entre as tabelas. Para solucionar esses problemas, devemos utilizar o conceito de chave primria e
chave estrangeira.

Toda tabela pode ter uma chave primria, que um conjunto de um ou mais campos que de-
vem ser nicos para cada registro. Normalmente, um campo numrico escolhido para ser a chave
primria de uma tabela, pois as consultas podem ser realizadas com melhor desempenho.

Ento, poderamos adicionar um campo numrico na tabela Editora e torn-lo chave primria.
Vamos chamar esse campo de id. Na tabela Livro, podemos adicionar um campo numrico chamado
editora_id que deve ser utilizado para guardar o valor da chave primria da editora correspondente
ao livro. Alm disso, o campo editora_id deve estar explicitamente vinculado com o campo id da
tabela Editora. Para estabelecer esse vnculo, o campo editora_id da tabela Livro deve ser uma chave
estrangeira associada chave primria da tabela Editora.

Uma chave estrangeira um conjunto de uma ou mais colunas de uma tabela que possuem va-
lores iguais aos da chave primria de outra tabela.

Com a definio da chave estrangeira, um livro no pode ser inserido com o valor do campo
editora_id invlido. Caso tentssemos fazer isso, obteramos uma mensagem de erro.

Exerccios de Fixao

www.facebook.com/k19treinamentos 5
B ANCO DE DADOS 6

1 Abra um terminal, crie e acesse uma pasta com o seu nome.

cosen@k19 :~ $ mkdir rafael


cosen@k19 :~ $ cd rafael /
cosen@k19 :~/ rafael$

Terminal 1.13: Criando e acessando uma pasta com o seu nome.

2 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 :

Terminal 1.14: Logando no MySQL Server.

3 Caso exista uma base de dados chamada livraria, remova-a. Utilize o comando SHOW DATA-
BASES para listar as bases de dados existentes e o comando DROP DATABASE para remover a base
livraria se ela existir.

mysql > SHOW DATABASES ;


+ - - - - - - - - - - - - - - - - - - - -+
| Database |
+ - - - - - - - - - - - - - - - - - - - -+
| information_schema |
| livraria |
| mysql |
| test |
+ - - - - - - - - - - - - - - - - - - - -+
4 rows in set (0.00 sec )

mysql > DROP DATABASE livraria ;


Query OK , 1 row affected (0.12 sec )

Terminal 1.15: Listando as bases de dados existentes e removendo a base livraria.

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 )

Terminal 1.16: Criando a base livraria.

5 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.

1 USE livraria ;
2 CREATE TABLE Editora (
3 id BIGINT NOT NULL AUTO_INCREMENT ,
4 nome VARCHAR (255) NOT NULL ,
5 email VARCHAR (255) NOT NULL ,
6 PRIMARY KEY ( id )
7 )
8 ENGINE = InnoDB ;

Cdigo SQL 1.1: Criando a tabela Editora

6 www.k19.com.br
7 B ANCO DE DADOS

6 Dentro do terminal, use o comando source para executar o arquivo que voc acabou de criar.

mysql > source create - table - editora . sql


Database changed
Query OK , 0 rows affected (0.08 sec )

Terminal 1.17: Executando a tabela Editora.

7 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.

1 USE livraria ;
2 CREATE TABLE Livro (
3 id BIGINT NOT NULL AUTO_INCREMENT ,
4 titulo VARCHAR (255) NOT NULL ,
5 preco DOUBLE NOT NULL ,
6 editora_id BIGINT NOT NULL ,
7 PRIMARY KEY ( id ) ,
8 CONSTRAINT fk_editora FOREIGN KEY fk_editora ( editora_id )
9 REFERENCES Editora ( id )
10 ON DELETE RESTRICT
11 ON UPDATE RESTRICT
12 )
13 ENGINE = InnoDB ;

Cdigo SQL 1.2: Criando a tabela Livro

8 Dentro do terminal, use o comando source para executar o cdigo do arquivo create-table-li-
vro.sql.

mysql > source create - table - livro . sql


Database changed
Query OK , 0 rows affected (0.08 sec )

Terminal 1.18: Executando a tabela Livro.

9 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.

1 INSERT INTO Editora ( nome , email ) VALUES ( Oreilly , oreilly@email . com ) ;


2
3 INSERT INTO Editora ( nome , email ) VALUES ( Wrox , wrox@email . com ) ;
4
5 INSERT INTO Editora ( nome , email ) VALUES ( Apress , apress@email . com ) ;

Cdigo SQL 1.3: Adicionando registros na tabela Editora

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 )

www.facebook.com/k19treinamentos 7
B ANCO DE DADOS 8

Terminal 1.19: Inserindo editoras.

11 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.

1 INSERT INTO Livro ( titulo , preco , editora_id ) VALUES ( Aprendendo C # , 89.90 , 1) ;


2
3 INSERT INTO Livro ( titulo , preco , editora_id ) VALUES ( Introduo ao JSF 2 ,
4 122.90 , 3) ;
5
6 INSERT INTO Livro ( titulo , preco , editora_id ) VALUES ( JSF 2 Avanado , 149.90 , 3) ;

Cdigo SQL 1.4: Adicionando alguns registros na tabela Livro

12 Dentro do terminal, execute o arquivo que voc acabou de criar para adicionar alguns registros
na Livro.

mysql > source adicionando - registros - livro . sql


Query OK , 1 row affected (0.02 sec )

Query OK , 1 row affected (0.04 sec )

Query OK , 1 row affected (0.04 sec )

Terminal 1.20: Inserindo livros.

13 Consulte os registros da tabela Editora e da tabela Livro. Utilize o comando SELECT.

mysql > SELECT * FROM Editora ;


+ - - - -+ - - - - - - - - -+ - - - - - - - - - - - - - - - - - - -+
| id | nome | email |
+ - - - -+ - - - - - - - - -+ - - - - - - - - - - - - - - - - - - -+
| 1 | Oreilly | oreilly@email . com |
| 2 | Wrox | wrox@email . com |
| 3 | Apress | apress@email . com |
+ - - - -+ - - - - - - - - -+ - - - - - - - - - - - - - - - - - - -+
3 rows in set (0.00 sec )

Terminal 1.21: Selecionando as editoras.

mysql > SELECT * FROM Livro ;


+ - - - -+ - - - - - - - - - - - - - - - - - - - - - - -+ - - - - - - -+ - - - - - - - - - - - -+
| id | titulo | preco | editora_id |
+ - - - -+ - - - - - - - - - - - - - - - - - - - - - - -+ - - - - - - -+ - - - - - - - - - - - -+
| 1 | Aprendendo C # | 89.9 | 1 |
| 2 | Introduo ao JSF 2 | 122.9 | 3 |
| 3 | JSF 2 Avanado | 149.9 | 3 |
+ - - - -+ - - - - - - - - - - - - - - - - - - - - - - -+ - - - - - - -+ - - - - - - - - - - - -+
3 rows in set (0.00 sec )

Terminal 1.22: Selecionando os livros.

14 Altere alguns dos registros da tabela Livro. Utilize o comando UPDATE.

mysql > UPDATE Livro SET preco =92.9 WHERE id =1;


Query OK , 1 row affected (0.07 sec )
Rows matched : 1 Changed : 1 Warnings : 0

8 www.k19.com.br
9 B ANCO DE DADOS

Terminal 1.23: Alterando livros.

15 Altere alguns dos registros da tabela Editora. Utilize o comando UPDATE.

mysql > UPDATE Editora SET nome = OReilly WHERE id =1;


Query OK , 1 row affected (0.09 sec )
Rows matched : 1 Changed : 1 Warnings : 0

Terminal 1.24: Alterando editoras.

16 Remova alguns registros da tabela Livro. Utilize o comando DELETE.

mysql > DELETE FROM Livro WHERE id =2;


Query OK , 1 row affected (0.07 sec )

Terminal 1.25: Removendo livros.

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 )

Terminal 1.26: Removendo editoras.

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 )

Terminal 1.27: Selecionando os livros de uma editora.

Exerccios Complementares
Utilize o MySQL Workbench para refazer os exerccios anteriores.

1 Abra o MySQL Workbench utilizando localhost como Server Hostname, root como Username e
root como Password.

www.facebook.com/k19treinamentos 9
B ANCO DE DADOS 10

10 www.k19.com.br
11 B ANCO DE DADOS

2 Caso exista uma base de dados chamada livraria, remova-a conforme a figura abaixo.

www.facebook.com/k19treinamentos 11
B ANCO DE DADOS 12

3 Crie uma nova base de dados chamada livraria, conforme mostrado na figura abaixo. Voc vai
utilizar esta base nos exerccios seguintes.

12 www.k19.com.br
13 B ANCO DE DADOS

www.facebook.com/k19treinamentos 13
B ANCO DE DADOS 14

14 www.k19.com.br
15 B ANCO DE DADOS

4 Selecione a base de dados livraria como padro.

5 Crie uma tabela chamada Editora conforme as figuras abaixo.

www.facebook.com/k19treinamentos 15
B ANCO DE DADOS 16

16 www.k19.com.br
17 B ANCO DE DADOS

www.facebook.com/k19treinamentos 17
B ANCO DE DADOS 18

6 Crie uma tabela chamada Livro conforme as figuras abaixo.

18 www.k19.com.br
19 B ANCO DE DADOS

www.facebook.com/k19treinamentos 19
B ANCO DE DADOS 20

20 www.k19.com.br
21 B ANCO DE DADOS

7 Adicione alguns registros na tabela Editora. Veja exemplos na figura abaixo.

8 Adicione alguns registros na tabela Livro. Veja exemplos na figura abaixo.

9 Consulte os registros da tabela Editora e, em seguida, consulte a tabela Livro. Veja exemplos logo

www.facebook.com/k19treinamentos 21
B ANCO DE DADOS 22

abaixo.

10 Altere alguns dos registros da tabela Livro. Veja o exemplo abaixo.

22 www.k19.com.br
23 B ANCO DE DADOS

11 Altere alguns dos registros da tabela Editora. Veja o exemplo abaixo.

12 Remova alguns registros da tabela Livro. Veja o exemplo abaixo.

www.facebook.com/k19treinamentos 23
B ANCO DE DADOS 24

13 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:

14 Faa uma consulta para buscar todos os livros associados as suas respectivas editoras. Veja um
exemplo na figura abaixo.

24 www.k19.com.br
25 B ANCO DE DADOS

www.facebook.com/k19treinamentos 25
B ANCO DE DADOS 26

26 www.k19.com.br
CAPTULO
JDBC
2
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 dis-
ponveis 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.

SELECT * FROM tbl_funcionarios WHERE


nome LIKE %jonas%;

INSERT INTO tbl_funcionarios (nome,


codigo, salario) VALUES (Rafael, 1234,
1000);

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 co-
nhecimentos 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:

Figura 2.2: Usurios comuns devem utilizar interfaces simples

www.facebook.com/k19treinamentos 27
JDBC 28

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.

rollback
find
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 com-
plexas para um ser humano compreender. Dessa forma, o trabalho dos desenvolvedores seria muito
complexo, aumentando o custo para o desenvolvimento e manuteno das aplicaes.
10 010 11 110 01

1011010111
11 11 11 0

0010110011
0 10 01 10 1

0010110001
01 00 01

1101011101
10 111 10 110 11

01 01

1010111101 0101101001
0 01 01 00

11

0111011100 0111011100
01 101 11

0101101001 1010111101
1 010

1101011101 0010110001
0

0010110011 1011010111

Figura 2.4: Mensagens binrias so altamente complexas para os seres humanos

28 www.k19.com.br
29 JDBC

Para resolver esse problema e facilitar o desenvolvimento das aplicaes, as empresas propriet-
rias 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. Consequen-
temente, 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 desenvol-
vedores teriam de conhecer a interface de cada um dos drivers dos respectivos SGDBs que fossem
utilizar.

createConnection() 01110010101110011
Driver MySQL

openConnection() 00010011101110010
Driver Oracle

Figura 2.5: Drivers de conexo sem padronizao

Para facilitar o trabalho do desenvolvedor da aplicao, a plataforma Java possui uma especifica-
o que padroniza os drivers de conexo. A sigla dessa especificao JDBC (Java Database Connec-
tivity). Em geral, as empresas proprietrias dos SGBDs desenvolvem e distribuem drivers de conexo
que seguem a especificao JDBC.

www.facebook.com/k19treinamentos 29
JDBC 30

getConnection() 01110010101110011

Driver MySQL
JDBC
getConnection() 00010011101110010

Driver Oracle
JDBC

Figura 2.6: Drivers de conexo padronizados pela especificao JDBC

Instalando o Driver JDBC do MySQL Server

Podemos obter um driver de conexo JDBC para o MySQL Server na seguinte url:

http://www.mysql.com/downloads/connector/j/.

A instalao desse driver consiste em descompactar o arquivo obtido no site acima e depois in-
cluir o arquivo jar com o driver no class path da aplicao.

Criando uma conexo

Com o driver de conexo JDBC adicionado aplicao, j possvel criar uma conexo. Abaixo,
esto as informaes necessrias para a criao de uma conexo JDBC.

Nome do driver JDBC.

Endereo (IP e porta) do SGDB.

Nome da base de dados.

Um usurio do SGBD.

Senha do usurio.

O nome do driver JDBC, o endereo do SGDB e nome da base de dados so definidos na string
de conexo ou url de conexo. Veja o exemplo abaixo:

1 String stringDeConexao = " jdbc : mysql :// localhost / livraria " ;

Cdigo Java 2.1: String de conexo

30 www.k19.com.br
31 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 String urlDeConexao = " jdbc : mysql :// localhost / livraria " ;


2 String usuario = " root " ;
3 String senha = " " ;
4 try {
5 Connection conexao = DriverManager . getConnection ( urlDeConexao , usuario , senha ) ;
6 } catch ( SQLException e ) {
7 e . printStackTrace () ;
8 }

Cdigo Java 2.2: Criando uma conexo JDBC

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 pa-
rmetro 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 // criando um prepared statement


2 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
3
4 // executando o prepared statement
5 comando . execute () ;
6 comando . close () ;

Cdigo Java 2.4: Criando um prepared statement

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.facebook.com/k19treinamentos 31
JDBC 32

1 Crie um projeto chamado JDBC. Esse projeto deve ser do tipo Java Project.

2 Acrescente uma pasta chamada lib no projeto JDBC. Copie o arquivo mysql-connector-java-
VERSAO-bin.jar da pasta K19-Arquivos/mysql-connector-java-VERSAO para a pasta lib do projeto
JDBC. Observao: o termo VERSAO deve ser substitudo pelo nmero da verso utilizada.

Importante
Voc tambm pode obter o arquivo mysql-connector-java-VERSAO-bin.jar atravs
do site da K19: www.k19.com.br/arquivos.

3 Adicione o arquivo mysql-connector-java-VERSAO-bin.jar ao build path do projeto JDBC. Veja


a imagem abaixo.

4 Crie uma classe chamada InsereEditora em um pacote chamado br.com.k19.jdbc no projeto


JDBC com o seguinte contedo.

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . PreparedStatement ;

32 www.k19.com.br
33 JDBC

6 import java . util . Scanner ;


7
8 public class InsereEditora {
9 public static void main ( String [] args ) {
10 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
11 String usuario = " root " ;
12 String senha = " root " ;
13
14 try {
15 System . out . println ( " Abrindo conexo ... " ) ;
16 Connection conexao =
17 DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
18
19 Scanner entrada = new Scanner ( System . in ) ;
20
21 System . out . println ( " Digite o nome da editora : " ) ;
22 String nome = entrada . nextLine () ;
23
24 System . out . println ( " Digite o email da editora : " ) ;
25 String email = entrada . nextLine () ;
26
27 entrada . close () ;
28
29 String sql = " INSERT INTO Editora ( nome , email ) " +
30 " VALUES ( " + nome + " , " + email + " ) " ;
31
32 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
33
34 System . out . println ( " Executando comando ... " ) ;
35 comando . execute () ;
36
37 System . out . println ( " Fechando conexo ... " ) ;
38 conexao . close () ;
39 } catch ( Exception e ) {
40 e . printStackTrace () ;
41 }
42 }
43 }

Cdigo Java 2.6: InsereEditora.java

Execute a classe InsereEditora e verifique se o registro foi inserido com sucesso na base de dados.

Exerccios Complementares

1 Crie uma classe chamada InsereLivro 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 compor-
tamento 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

www.facebook.com/k19treinamentos 33
JDBC 34

OReilly e oreilly@email.com, o cdigo SQL gerado pela aplicao seria:

1 INSERT INTO Editora ( nome , email ) VALUES ( O Reilly , oreilly@email . com )

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 INSERT INTO Editora ( nome , email ) VALUES ( O \ Reilly , oreilly@email . com )

Os valores recebidos dos usurios devem ser analisados e os caracteres especiais contidos nesses
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 denomi-
nado sanitize.

1 // lendo as entradas do usurio


2 System . out . println ( " Digite o nome da editora : " ) ;
3 String nome = entrada . nextLine () ;
4
5 System . out . println ( " Digite o email da editora : " ) ;
6 String email = entrada . nextLine () ;
7
8 // cdigo sql com marcadores para as entradas do usurio
9 String sql = " INSERT INTO Editora ( nome , email ) VALUES (? , ?) " ;
10
11 // criando um comando a partir do cdigo SQL
12 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
13
14 // adicionando as entradas do usurios no comando
15 // o processo de sanitizao ocorre aqui
16 comando . setString (1 , nome ) ;
17 comando . setString (2 , email ) ;

Cdigo Java 2.10: Sanitizando as entradas dos usurios

Observe que o cdigo SQL foi definido com parmetros atravs do caractere ?. Antes de exe-
cutar 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 va-
lor 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

34 www.k19.com.br
35 JDBC

5 Tente gerar um erro de SQL Injection no cadastro de editoras. Dica: utilize entradas com aspas
simples.

6 Altere o cdigo da classe InsereEditora para eliminar o problema do SQL Injection.

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . PreparedStatement ;
6 import java . util . Scanner ;
7
8 public class InsereEditora {
9 public static void main ( String [] args ) {
10 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
11 String usuario = " root " ;
12 String senha = " root " ;
13
14 try {
15 System . out . println ( " Abrindo conexo ... " ) ;
16 Connection conexao =
17 DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
18
19 Scanner entrada = new Scanner ( System . in ) ;
20
21 System . out . println ( " Digite o nome da editora : " ) ;
22 String nome = entrada . nextLine () ;
23
24 System . out . println ( " Digite o email da editora : " ) ;
25 String email = entrada . nextLine () ;
26
27 entrada . close () ;
28
29 String sql = " INSERT INTO Editora ( nome , email ) VALUES (? , ?) " ;
30
31 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
32 comando . setString (1 , nome ) ;
33 comando . setString (2 , email ) ;
34
35 System . out . println ( " Executando comando ... " ) ;
36 comando . execute () ;
37
38 System . out . println ( " Fechando conexo ... " ) ;
39 conexao . close () ;
40 } catch ( Exception e ) {
41 e . printStackTrace () ;
42 }
43 }
44 }

Cdigo Java 2.11: InsereEditora.java

Exerccios Complementares

2 Tente gerar um erro de SQL Injection no cadastro de livros. Dica: utilize entradas com aspas
simples.

www.facebook.com/k19treinamentos 35
JDBC 36

3 Altere o cdigo da classe InsereLivro para eliminar o problema do SQL Injection.

4 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 String sql = " SELECT * FROM Editora ; " ;


2
3 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
4
5 System . out . println ( " Executando comando ... " ) ;
6 ResultSet resultado = comando . executeQuery () ;

Cdigo Java 2.13: Realizando uma consulta.

A diferena que para executar um comando de consulta necessrio utilizar o mtodo execu-
teQuery() ao invs do execute(). Esse mtodo devolve um objeto da interface java.sql.Result-
Set, que responsvel por armazenar os resultados da consulta.

Os dados contidos no ResultSet podem ser acessados atravs de mtodos, como o getString,
getInt, getDouble, etc, de acordo com o tipo do campo. Esses mtodos recebem como parmetro
uma string referente ao nome da coluna correspondente.

1 int id = resultado . getInt ( " id " ) ,


2 String nome = resultado . getString ( " nome " ) ,
3 String email = resultado . getString ( " email " ) ;

Cdigo Java 2.14: Recuperando os dados de um ResultSet

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 int id1 = resultado . getInt ( " id " ) ,


2 String nome1 = resultado . getString ( " nome " ) ,
3 String email1 = resultado . getString ( " email " ) ;
4
5 resultado . next () ;
6
7 int id2 = resultado . getInt ( " id " ) ,
8 String nome2 = resultado . getString ( " nome " ) ,
9 String email2 = resultado . getString ( " email " ) ;

Cdigo Java 2.15: Avanando o ResultSet

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 while ( resultado . next () ) {


2 int id = resultado . getInt ( " id " ) ,
3 String nome = resultado . getString ( " nome " ) ,
4 String email = resultado . getString ( " email " ) ;

36 www.k19.com.br
37 JDBC

5 }

Cdigo Java 2.16: Iterando os registros do ResultSet

Exerccios de Fixao

7 Insira algumas editoras utilizando a classe InsereEditora que voc criou anteriormente.

8 Adicione uma nova classe no projeto JDBC chamada ListaEditoras.

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . PreparedStatement ;
6 import java . sql . ResultSet ;
7
8 public class ListaEditoras {
9 public static void main ( String [] args ) {
10 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
11 String usuario = " root " ;
12 String senha = " root " ;
13
14 try {
15 System . out . println ( " Abrindo conexo ... " ) ;
16 Connection conexao =
17 DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
18
19 String sql = " SELECT * FROM Editora ; " ;
20
21 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
22
23 System . out . println ( " Executando comando ... " ) ;
24 ResultSet resultado = comando . executeQuery () ;
25
26 System . out . println ( " Resultados encontrados : \ n " ) ;
27 while ( resultado . next () ) {
28 System . out . printf ( " % d : % s - % s \ n " ,
29 resultado . getInt ( " id " ) ,
30 resultado . getString ( " nome " ) ,
31 resultado . getString ( " email " ) ) ;
32 }
33
34 System . out . println ( " \ nFechando conexo ... " ) ;
35 conexao . close () ;
36 } catch ( Exception e ) {
37 e . printStackTrace () ;
38 }
39 }
40 }

Cdigo Java 2.17: ListaEditoras.java

Exerccios Complementares

www.facebook.com/k19treinamentos 37
JDBC 38

5 Crie uma classe para listar os livros cadastrados na base de dados.

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 pro-
blema 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 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . SQLException ;
6
7 public class ConnectionFactory {
8 public static Connection createConnection () {
9 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
10 String usuario = " root " ;
11 String senha = " root " ;
12
13 Connection conexao = null ;
14
15 try {
16 conexao = DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
17 } catch ( SQLException e ) {
18 e . printStackTrace () ;
19 }
20 return conexao ;
21 }
22 }

Cdigo Java 2.19: ConnectionFactory.java

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

9 Adicione uma classe chamada ConnectionFactory no projeto JDBC com o cdigo abaixo.

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . SQLException ;

38 www.k19.com.br
39 JDBC

6
7 public class ConnectionFactory {
8 public static Connection createConnection () {
9 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
10 String usuario = " root " ;
11 String senha = " root " ;
12
13 Connection conexao = null ;
14
15 try {
16 conexao = DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
17 } catch ( SQLException e ) {
18 e . printStackTrace () ;
19 }
20 return conexao ;
21 }
22 }

Cdigo Java 2.20: ConnectionFactory.java

10 Altere as classes InsereEditora e ListaEditoras para que elas utilizem a fbrica de conexo.
Depois, execute-as novamente.

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . PreparedStatement ;
5 import java . util . Scanner ;
6
7 public class InsereEditora {
8 public static void main ( String [] args ) {
9 try {
10 System . out . println ( " Abrindo conexo ... " ) ;
11 Connection conexao = ConnectionFactory . createConnection () ;
12
13 Scanner entrada = new Scanner ( System . in ) ;
14
15 System . out . println ( " Digite o nome da editora : " ) ;
16 String nome = entrada . nextLine () ;
17
18 System . out . println ( " Digite o email da editora : " ) ;
19 String email = entrada . nextLine () ;
20
21 entrada . close () ;
22
23 String sql = " INSERT INTO Editora ( nome , email ) VALUES (? , ?) " ;
24
25 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
26 comando . setString (1 , nome ) ;
27 comando . setString (2 , email ) ;
28
29 System . out . println ( " Executando comando ... " ) ;
30 comando . execute () ;
31
32 System . out . println ( " Fechando conexo ... " ) ;
33 conexao . close () ;
34 } catch ( Exception e ) {
35 e . printStackTrace () ;
36 }
37 }
38 }

Cdigo Java 2.21: InsereEditora.java

1 package br . com . k19 . jdbc ;


2

www.facebook.com/k19treinamentos 39
JDBC 40

3 import java . sql . Connection ;


4 import java . sql . PreparedStatement ;
5 import java . sql . ResultSet ;
6
7 public class ListaEditoras {
8 public static void main ( String [] args ) {
9 try {
10 System . out . println ( " Abrindo conexo ... " ) ;
11 Connection conexao = ConnectionFactory . createConnection () ;
12
13 String sql = " SELECT * FROM Editora ; " ;
14
15 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
16
17 System . out . println ( " Executando comando ... " ) ;
18 ResultSet resultado = comando . executeQuery () ;
19
20 System . out . println ( " Resultados encontrados : \ n " ) ;
21 while ( resultado . next () ) {
22 System . out . printf ( " % d : % s - % s \ n " ,
23 resultado . getInt ( " id " ) ,
24 resultado . getString ( " nome " ) ,
25 resultado . getString ( " email " ) ) ;
26 }
27
28 System . out . println ( " \ nFechando conexo ... " ) ;
29 conexao . close () ;
30 } catch ( Exception e ) {
31 e . printStackTrace () ;
32 }
33 }
34 }

Cdigo Java 2.22: ListaEditoras.java

Exerccios Complementares

6 Altere as classes InsereLivro e ListaLivros para que elas utilizem a fbrica de conexo. Depois,
execute-as novamente.

Desafios

1 Implemente a remoo de editoras pelo id.

2 Implemente a alterao dos dados das editoras pelo id.

40 www.k19.com.br
CAPTULO
JPA 2.1 E H IBERNATE
3
Mltiplas sintaxes da linguagem SQL

No captulo anterior, utilizamos a especificao JDBC para fazer uma aplicao Java interagir
com os SGDBs. Nessa interao, as consultas so definidas com a linguagem SQL. A sintaxe dessa
linguagem diferente em cada SGDB. Dessa forma, a complexidade do trabalho dos desenvolvedo-
res aumenta. Para resolver esse problema, as consultas deveriam ser definidas atravs de um meca-
nismo independente da linguagem SQL.

SELECT columns FROM livros ORDER BY autor ASC LIMIT 100

Driver MySQL
JDBC

SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY autor ASC) AS rownumber,
id, titulo, autor
FROM livros
) WHERE rownumber <= 100
Driver Oracle
JDBC

Figura 3.1: Diferentes sintaxes da linguagem SQL

Orientao a Objetos VS Modelo Relacional

Outro problema na comunicao entre uma aplicao Java e um SGDB o conflito de paradig-
mas. Os SGDBs so organizados seguindo o modelo relacional. Por outro lado, as aplicaes Java

www.facebook.com/k19treinamentos 41
JPA 2.1 E H IBERNATE 42

utilizam o modelo orientado a objetos.

A transio de dados entre o modelo relacional e o modelo orientado a objetos no simples.


Para realizar essa transio, necessrio definir um mapeamento entre os conceitos desses dois pa-
radigmas. Por exemplo, classes podem ser mapeadas para tabelas, objetos para registros, atributos
para campos e referncia entre objetos para chaves estrangeiras.

tbl_editoras

Livro id nome
id = 1 1 Cultura
titulo = Os Lusadas
2 FTDA
autor = Lus Vaz de
Cames 3 Globo
editora = 1
4 Scipione
Editora
id = 1
nome = Livraria Cultura
tbl_livros
Livro
id = 2 id titulo autor editora_id
titulo = Vidas Secas 1 Os Lusadas Lus Vaz de Cames 1
autor = Graciliano
Ramos 2 Vidas Secas Graciliano Ramos 1
editora = 1 3 Dom Casmurro Machado de Assis 3
4 O Cortio Alusio Azevedo 2

ORIENTAO A OBJETOS MODELO RELACIONAL


Figura 3.2: Modelo Orientado a Objetos vs 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 ob-
jetivo.

42 www.k19.com.br
43 JPA 2.1 E H IBERNATE

tbl_livros

id titulo autor editora_id Livro Livro


1 Os Lusadas Lus Vaz de Cames 1 FERRAMENTA
id = 1 id = 2
2 Vidas Secas Graciliano Ramos 1 ORM titulo = Os Lusadas
autor = Lus Vaz de
titulo = Vidas Secas
autor = Graciliano
3 Dom Casmurro Machado de Assis 3 Cames Ramos
4 O Cortio Alusio Azevedo 2 editora = 1 editora = 1

Figura 3.3: Transformao dos dados do Modelo Relacional para o Modelo Orientado a Objetos

tbl_livros
Livro Livro id titulo autor editora_id
id = 1 id = 2 FERRAMENTA
1 Os Lusadas Lus Vaz de Cames 1
titulo = Os Lusadas
autor = Lus Vaz de
titulo = Vidas Secas
autor = Graciliano
ORM
2 Vidas Secas Graciliano Ramos 1

Cames Ramos 3 Dom Casmurro Machado de Assis 3


editora = 1 editora = 1 4 O Cortio Alusio Azevedo 2

Figura 3.4: Transformao dos dados do Modelo Orientado a Objetos para o Modelo Relacional

O que JPA e Hibernate?

Aps o sucesso do Hibernate, a especificao JPA (Java Persistence API) foi criada com o objetivo
de padronizar as ferramentas ORM para aplicaes Java e consequentemente diminuir a complexi-
dade do desenvolvimento. Atualmente, essa especificao est na sua segunda verso.

Ela especifica um conjunto de classes e mtodos que as ferramentas ORM devem implementar.
Veja que a JPA apenas uma especificao. Ela no implementa nenhum cdigo. Para isso, utiliza-
mos alguma das diversas implementaes da JPA. Neste curso, utilizaremos o Hibernate como im-
plementao de JPA. As outras implementaes de JPA mais conhecidas so EclipseLink e OpenJPA.
Optamos por utilizar o Hibernate por ele ser o mais antigo e mais utilizado atualmente.

Caso voc queira utilizar outra ferramenta ORM, poder aplicar os conceitos aqui aprendidos
justamente porque eles seguem a mesma especificao. Assim, podemos programar voltado es-
pecificao e substituir uma implementao pela outra, sem precisar reescrever o cdigo da nossa
aplicao. Claro que teramos que alterar alguns arquivos de configurao, mas o cdigo da aplica-
o permaneceria o mesmo.

Bibliotecas

Antes de comear a utilizar o Hibernate, necessrio baixar do site oficial o bundle que inclui os
jars do hibernate e todas as suas dependncias. Neste curso, utilizaremos a verso 4.3.10. A url do
site oficial do Hibernate http://www.hibernate.org/.

www.facebook.com/k19treinamentos 43
JPA 2.1 E H IBERNATE 44

Configurao

Para configurar o Hibernate em uma aplicao, devemos criar um arquivo chamado persisten-
ce.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 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence
3 version = " 2.1 "
4 xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
5 xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
6 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
7 http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd " >
8
9 < persistence - unit name = " livraria - pu " transaction - type = " RESOURCE_LOCAL " >
10 < provider > org . hibernate . ejb . HibernatePersistence </ provider >
11 < properties >
12 < property
13 name = " hibernate . dialect "
14 value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
15
16 < property
17 name = " hibernate . hbm2ddl . auto "
18 value = " create " / >
19
20 < property
21 name = " javax . persistence . jdbc . driver "
22 value = " com . mysql . jdbc . Driver " / >
23
24 < property
25 name = " javax . persistence . jdbc . user "
26 value = " root " / >
27
28 < property
29 name = " javax . persistence . jdbc . password "
30 value = " root " / >
31
32 < property
33 name = " javax . persistence . jdbc . url "
34 value = " jdbc:mysql: // localhost:3306 / livraria " / >
35 </ properties >
36 </ persistence - unit >
37 </ 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

44 www.k19.com.br
45 JPA 2.1 E H IBERNATE

Um dos principais objetivos das ferramentas ORM estabelecer o mapeamento entre os concei-
tos 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.

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 pos-
suem 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 atri-
buto 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 @Table ( name = " Publisher " )


2 @Entity
3 public class Editora {
4 // ...
5 }

Cdigo Java 3.1: Editora.java

@Column Utilizado para alterar o nome da coluna que ser usado na tabela. Caso voc esteja uti-
lizando 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 @Entity
2 public class Editora {
3 @Column ( name = " publisher_name " , nullable = false )
4 private String nome ;
5
6 }

Cdigo Java 3.2: Editora.java

@Transient Serve para indicar que um atributo no deve ser persistido, ou seja, os atributos anota-
dos com @Transient no so mapeados para colunas.

www.facebook.com/k19treinamentos 45
JPA 2.1 E H IBERNATE 46

@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.

1 @Entity
2 public class Livro {
3 @Temporal ( TemporalType . DATE )
4 private Calendar publicacao ;
5 // ...
6
7 }

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 createEntityManager-


Factory(String entityUnit). O parmetro entityUnit permite escolher, pelo nome, uma uni-
dade de persistncia definida no persistence.xml.

A poltica de criao das tabelas pode ser alterada modificando o valor a propriedade hiberna-
te.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 hiberna-
te.hbm2ddl.auto deve ser update.

1 < property name = " hibernate . hbm2ddl . auto " value = " update " / >

Exerccios de Fixao

1 Crie um projeto chamado JPA. Esse projeto deve ser do tipo Java Project.

2 Crie uma pasta chamada lib no projeto JPA. Copie os JARs do Hibernate e do driver JDBC do
MySQL para a pasta lib. Esses JARs esto nos diretrios:

46 www.k19.com.br
47 JPA 2.1 E H IBERNATE

K19-Arquivos/hibernate-release-4.3.10.Final/lib/required

K19-Arquivos/hibernate-release-4.3.10.Final/lib/jpa

K19-Arquivos/mysql-connector-java-VERSAO

Importante
Voc tambm pode obter os JARs do Hibernate e do driver JDBC do MySQL atravs do
site da K19: www.k19.com.br/arquivos.

3 Adicione os JARs da pasta lib do projeto JPA no build path.

4 Configure uma unidade de persistncia no projeto JPA. Para isso, crie uma pasta chamada META-

INF na pasta src do projeto JPA. Adicione nessa pasta o arquivo persistence.xml com o seguinte
contedo.

Para criar o arquivo persistence.xml no Eclipse, digite CTRL + 3 e pesquise por Create a new
XML file. Selecione a opo correspondente e siga as imagens abaixo.

www.facebook.com/k19treinamentos 47
JPA 2.1 E H IBERNATE 48

48 www.k19.com.br
49 JPA 2.1 E H IBERNATE

www.facebook.com/k19treinamentos 49
JPA 2.1 E H IBERNATE 50

1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence
3 version = " 2.1 "
4 xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
5 xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
6 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
7 http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd " >
8
9 < persistence - unit name = " livraria - pu " transaction - type = " RESOURCE_LOCAL " >
10 < provider > org . hibernate . ejb . HibernatePersistence </ provider >
11 < properties >
12 < property
13 name = " hibernate . dialect "
14 value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
15
16 < property
17 name = " hibernate . hbm2ddl . auto "
18 value = " create " / >
19
20 < property
21 name = " javax . persistence . jdbc . driver "
22 value = " com . mysql . jdbc . Driver " / >
23
24 < property
25 name = " javax . persistence . jdbc . user "
26 value = " root " / >
27
28 < property
29 name = " javax . persistence . jdbc . password "
30 value = " root " / >
31
32 < property
33 name = " javax . persistence . jdbc . url "
34 value = " jdbc:mysql: // localhost:3306 / livraria " / >
35 </ properties >
36 </ persistence - unit >
37 </ persistence >

Cdigo XML 3.4: persistence.xml

50 www.k19.com.br
51 JPA 2.1 E H IBERNATE

5 Crie uma classe chamada Editora em um pacote chamado br.com.k19.jpa e acrescente as ano-
taes necessrias para fazer o mapeamento.

1 package br . com . k19 . jpa ;


2
3 import javax . persistence . Entity ;
4 import javax . persistence . GeneratedValue ;
5 import javax . persistence . Id ;
6
7 @Entity
8 public class Editora {
9
10 @Id
11 @GeneratedValue
12 private Long id ;
13
14 private String nome ;
15
16 private String email ;
17
18 // GETTERS AND SETTERS
19 }

Cdigo Java 3.4: Editora.java

6 Apague a tabela Livro e depois a tabela Editora.

7 Inicialize a unidade de persistncia atravs da classe Persistence. Para isso, crie uma classe
chamada Teste com o seguinte cdigo.

1 package br . com . k19 . jpa ;


2
3 import javax . persistence . EntityManagerFactory ;
4 import javax . persistence . Persistence ;
5
6 public class Teste {
7 public static void main ( String [] args ) {
8 EntityManagerFactory factory =
9 Persistence . createEntityManagerFactory ( " livraria - pu " ) ;
10
11 factory . close () ;
12 }
13 }

Cdigo Java 3.5: Teste.java

Execute a classe Teste e verifique se a tabela Editora foi criada corretamente.

Manipulando entidades

Para manipular as entidades da nossa aplicao, devemos utilizar um EntityManager que ob-
tido atravs de uma EntityManagerFactory.

1 EntityManagerFactory factory =
2 Persistence . createEntityManagerFactory ( " K19 " ) ;
3
4 EntityManager manager = factory . createEntityManager () ;

www.facebook.com/k19treinamentos 51
JPA 2.1 E H IBERNATE 52

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 Editora novaEditora = new Editora () ;


2 novaEditora . setNome ( " K19 - Livros " )
3 novaEditora . setEmail ( " contato@k19 . com . br " ) ;
4
5 manager . persist ( novaEditora ) ;

Cdigo Java 3.7: Marcando um objeto para ser persistido

importante destacar que o mtodo persist() apenas marca os objetos que devem ser arma-
zenados no banco de dados. Os objetos sero armazenados aps a chamada do mtodo commit(),
como veremos adiante.

Buscando
Para obter um objeto que contenha informaes do banco de dados, podemos utilizar o mtodo
find() ou o mtodo getReference() do EntityManager.

1 Editora editora1 = manager . find ( Editora . class , 1 L ) ;


2 Editora editora2 = manager . getReference ( Editora . class , 2 L ) ;

Cdigo Java 3.8: Obtendo objetos com informaes do banco de dados

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 Editora editora1 = manager . find ( Editora . class , 1 L ) ;


2 manager . remove ( editora1 ) ;

Cdigo Java 3.9: Marcando um objeto para ser removido

Atualizando
Para alterar os dados do registro correspondente a um objeto, basta utilizar os prprios mtodos
setters desse objeto.

1 Editora editora = manager . find ( Editora . class , 1 L ) ;


2 editora . setNome ( " K19 - Livros e Publicaes " ) ;

Cdigo Java 3.10: Alterando os dados de um registro

52 www.k19.com.br
53 JPA 2.1 E H IBERNATE

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 prin-
cipal vantagem do JPQL em relao ao SQL que a sintaxe do JPQL no depende do SGDB utilizado.

1 Query query = manager . createQuery ( " SELECT e FROM Editora e " ) ;


2 List < Editora > editoras = query . getResultList () ;

Cdigo Java 3.11: Obtendo uma lista de objetos com informaes do banco de dados

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 manager . getTransaction () . begin () ;

Cdigo Java 3.12: Abrindo uma transao

Com uma transao aberta, podemos sincronizar os dados da memria com os dados do banco
atravs do mtodo commit().

1 Editora editora = manager . find ( Editora . class , 1 L ) ;


2 editora . setNome ( " K19 - Livros e Publicaes " ) ;
3
4 manager . getTransaction () . begin () ;
5 manager . getTransaction () . commit () ;

Cdigo Java 3.13: Sincronizando com o mtodo commit()

Exerccios de Fixao

8 Altere o arquivo persistence.xml, modificando o valor da propriedade hibernate.hbm2ddl.auto


para update. Assim, as tabelas no sero recriadas a cada execuo. Elas sero apenas atualizadas.

1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence
3 version = " 2.1 "
4 xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
5 xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
6 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
7 http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd " >
8
9 < persistence - unit name = " livraria - pu " transaction - type = " RESOURCE_LOCAL " >
10 < provider > org . hibernate . ejb . HibernatePersistence </ provider >
11 < properties >
12 < property
13 name = " hibernate . dialect "
14 value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
15

www.facebook.com/k19treinamentos 53
JPA 2.1 E H IBERNATE 54

16 < property
17 name = " hibernate . hbm2ddl . auto "
18 value = " update " / >
19
20 < property
21 name = " javax . persistence . jdbc . driver "
22 value = " com . mysql . jdbc . Driver " / >
23
24 < property
25 name = " javax . persistence . jdbc . user "
26 value = " root " / >
27
28 < property
29 name = " javax . persistence . jdbc . password "
30 value = " root " / >
31
32 < property
33 name = " javax . persistence . jdbc . url "
34 value = " jdbc:mysql: // localhost:3306 / livraria " / >
35 </ properties >
36 </ persistence - unit >
37 </ persistence >

Cdigo XML 3.5: persistence.xml

9 Crie uma classe chamada InsereEditoraComJPA no pacote br.com.k19.jpa.

1 package br . com . k19 . jpa ;


2
3 import java . util . Scanner ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . EntityManagerFactory ;
6 import javax . persistence . Persistence ;
7
8 public class InsereEditoraComJPA {
9
10 public static void main ( String [] args ) {
11 EntityManagerFactory factory =
12 Persistence . createEntityManagerFactory ( " livraria - pu " ) ;
13
14 EntityManager manager = factory . createEntityManager () ;
15
16 Editora novaEditora = new Editora () ;
17
18 Scanner entrada = new Scanner ( System . in ) ;
19
20 System . out . println ( " Digite o nome da editora : " ) ;
21 novaEditora . setNome ( entrada . nextLine () ) ;
22
23 System . out . println ( " Digite o email da editora : " ) ;
24 novaEditora . setEmail ( entrada . nextLine () ) ;
25
26 entrada . close () ;
27
28 manager . persist ( novaEditora ) ;
29
30 manager . getTransaction () . begin () ;
31 manager . getTransaction () . commit () ;
32
33 manager . close () ;
34 factory . close () ;
35 }
36 }

Cdigo Java 3.14: InsereEditoraComJPA.java

54 www.k19.com.br
55 JPA 2.1 E H IBERNATE

Execute a classe InsereEditoraComJPA para inserir algumas editoras.

10 Crie uma classe chamada ListaEditorasComJPA no pacote br.com.k19.jpa.

1 package br . com . k19 . jpa ;


2
3 import java . util . List ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . EntityManagerFactory ;
6 import javax . persistence . Persistence ;
7 import javax . persistence . Query ;
8
9 public class ListaEditorasComJPA {
10
11 public static void main ( String [] args ) {
12 EntityManagerFactory factory =
13 Persistence . createEntityManagerFactory ( " livraria - pu " ) ;
14
15 EntityManager manager = factory . createEntityManager () ;
16
17 Query query = manager . createQuery ( " SELECT e FROM Editora e " ) ;
18 List < Editora > editoras = query . getResultList () ;
19
20 for ( Editora e : editoras ) {
21 System . out . println ( " EDITORA : " + e . getNome () + " - " + e . getEmail () ) ;
22 }
23
24 manager . close () ;
25 factory . close () ;
26 }
27 }

Cdigo Java 3.15: ListaEditorasComJPA.java

Execute a classe ListaEditorasComJPA para listar as editoras.

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 au-
mentando 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 ferramen-
tas ORM como o Hibernate.

1 class EditoraRepository {
2 private EntityManager manager ;
3
4 public EditoraRepository ( EntityManager manager ) {

www.facebook.com/k19treinamentos 55
JPA 2.1 E H IBERNATE 56

5 this . manager = manager ;


6 }
7
8 public void adiciona ( Editora e ) {
9 this . manager . persist ( e ) ;
10 }
11 public Editora busca ( Long id ) {
12 return this . manager . find ( Editora . class , id ) ;
13 }
14 public List < Editora > buscaTodas () {
15 Query query = this . manager . createQuery ( " SELECT e FROM Editora e " ) ;
16 return query . getResultList () ;
17 }
18 }

Cdigo Java 3.16: EditoraRepository.java

1 EntityManagerFactory factory = Persistence . createEntityManagerFactory ( " K19 " ) ;


2
3 EntityManager manager = factory . createEntityManager () ;
4
5 EditoraRepository editoraRepository = new EditoraRepository ( manager ) ;
6
7 List < Editora > editoras = editoraRepository . buscaTodas () ;

Cdigo Java 3.17: Utilizando um repositrio

Exerccios de Fixao

11 Adicione uma classe chamada EditoraRepository no pacote br.com.k19.jpa.

1 package br . com . k19 . jpa ;


2
3 import java . util . List ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . Query ;
6
7 public class EditoraRepository {
8 private EntityManager manager ;
9
10 public EditoraRepository ( EntityManager manager ) {
11 this . manager = manager ;
12 }
13
14 public void adiciona ( Editora e ) {
15 this . manager . persist ( e ) ;
16 }
17 public Editora busca ( Long id ) {
18 return this . manager . find ( Editora . class , id ) ;
19 }
20 public List < Editora > buscaTodas () {
21 Query query = this . manager . createQuery ( " SELECT e FROM Editora e " ) ;
22 return query . getResultList () ;
23 }
24 }

Cdigo Java 3.18: EditoraRepository.java

12 Altere a classe InsereEditoraComJPA para que ela utilize o repositrio de editoras.

56 www.k19.com.br
57 JPA 2.1 E H IBERNATE

1 package br . com . k19 . jpa ;


2
3 import java . util . Scanner ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . EntityManagerFactory ;
6 import javax . persistence . Persistence ;
7
8 public class InsereEditoraComJPA {
9
10 public static void main ( String [] args ) {
11 EntityManagerFactory factory =
12 Persistence . createEntityManagerFactory ( " livraria - pu " ) ;
13
14 EntityManager manager = factory . createEntityManager () ;
15
16 EditoraRepository editoraRepository = new EditoraRepository ( manager ) ;
17
18 Editora novaEditora = new Editora () ;
19
20 Scanner entrada = new Scanner ( System . in ) ;
21
22 System . out . println ( " Digite o nome da editora : " ) ;
23 novaEditora . setNome ( entrada . nextLine () ) ;
24
25 System . out . println ( " Digite o email da editora : " ) ;
26 novaEditora . setEmail ( entrada . nextLine () ) ;
27
28 entrada . close () ;
29
30 editoraRepository . adiciona ( novaEditora ) ;
31
32 manager . getTransaction () . begin () ;
33 manager . getTransaction () . commit () ;
34
35 manager . close () ;
36 factory . close () ;
37 }
38 }

Cdigo Java 3.19: InsereEditoraComJPA.java

13 Altere a classe ListaEditorasComJPA para que ela utilize o repositrio de editoras.

1 package br . com . k19 . jpa ;


2
3 import java . util . List ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . EntityManagerFactory ;
6 import javax . persistence . Persistence ;
7
8 public class ListaEditorasComJPA {
9
10 public static void main ( String [] args ) {
11 EntityManagerFactory factory =
12 Persistence . createEntityManagerFactory ( " livraria - pu " ) ;
13
14 EntityManager manager = factory . createEntityManager () ;
15
16 EditoraRepository editoraRepository = new EditoraRepository ( manager ) ;
17
18 List < Editora > editoras = editoraRepository . buscaTodas () ;
19
20 for ( Editora e : editoras ) {
21 System . out . println ( " EDITORA : " + e . getNome () + " - " + e . getEmail () ) ;
22 }
23

www.facebook.com/k19treinamentos 57
JPA 2.1 E H IBERNATE 58

24 manager . close () ;
25 factory . close () ;
26 }
27 }

Cdigo Java 3.20: ListaEditorasComJPA.java

58 www.k19.com.br
CAPTULO
W EB C ONTAINER
4
Necessidades de uma aplicao web

HTTP

Os usurios de uma aplicao web utilizam navegadores (browsers) para interagir com essa apli-
cao. 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.facebook.com/k19treinamentos 59
W EB C ONTAINER 60

Aplicao
Web

TP
Re

HT
sp

Requisio HTTP
Resposta HTTP
os

o
ta


isi
H

qu
TT

Re
P

TP

Re
HT

sp
o
o

st

aH
isi
qu

TT
Re

P
www.k19.com.br www.k19.com.br www.k19.com.br

Cursos Artigos Apostilas

Figura 4.1: Necessidades de uma aplicao web

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

Web Container
TP
Re

HT
sp

Requisio HTTP
Resposta HTTP
os

o
i
ta

s
H

ui
TT

q
Re
P

TP

Re
HT

sp
os
o

ta
isi

H
qu

TT
Re

www.k19.com.br www.k19.com.br www.k19.com.br

Cursos Artigos Apostilas

Figura 4.2: Web Container

Web Container

60 www.k19.com.br
61 W EB C ONTAINER

Uma aplicao web Java deve ser implantada em um Web Container para obter os recursos fun-
damentais 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 Wildfly, 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.1. Para consult-la, acesse https://jcp.org/en/jsr/detail?id=340.

A especificao Servlet faz parte do Java EE. O Java EE uma especificao que agrupa diversas
outras especificaes. Para consult-la, acesse https://jcp.org/en/jsr/detail?id=342.

Apesar das especificaes, os Web Containers possuem algumas diferenas nas configuraes
que devem ser realizadas pelos desenvolvedores. Dessa forma, no h 100% de portabilidade. Con-
tudo, 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 4.1 e o Wildfly 8.2.
Esses servidores seguem a especificao Java EE 7 e portanto contm um Web Container. Mostrare-
mos, a seguir, a sua instalao e configurao.

Exerccios de Fixao

1 Copie o arquivo wildfly-8.2.0.Final.zip da pasta K19-Arquivos para a sua rea de Trabalho.


Depois, descompacte esse arquivo.

Importante
Voc tambm pode obter o arquivo wildfly-8.2.0.Final.zip atravs do site da K19:
www.k19.com.br/arquivos.

2 Copie o arquivo glassfish-4.1.zip da pasta K19-Arquivos para a sua rea de Trabalho. Depois,
descompacte esse arquivo.

www.facebook.com/k19treinamentos 61
W EB C ONTAINER 62

Importante
Voc tambm pode obter o arquivo glassfish-4.1.zip atravs do site da K19: www.k19.
com.br/arquivos.

3 Utilizando o Eclipse Marketplace, adicione no Eclipse Mars o suporte ao Wildfly. Digite CTRL +
3 para abrir o Quick Access. Em seguida, pesquise por Eclipse Marketplace.

62 www.k19.com.br
63 W EB C ONTAINER

www.facebook.com/k19treinamentos 63
W EB C ONTAINER 64

64 www.k19.com.br
65 W EB C ONTAINER

www.facebook.com/k19treinamentos 65
W EB C ONTAINER 66

4 Utilizando o Eclipse Marketplace, adicione no Eclipse Mars o suporte ao Glassfish. Digite CTRL
+ 3 para abrir o Quick Access. Em seguida, pesquise por Eclipse Marketplace.

66 www.k19.com.br
67 W EB C ONTAINER

www.facebook.com/k19treinamentos 67
W EB C ONTAINER 68

68 www.k19.com.br
69 W EB C ONTAINER

5 Configure o Wildfly no Eclipse Mars. Digite CTRL + 3 para abrir o Quick Access. Em seguida,
pesquise por Define a new server.

www.facebook.com/k19treinamentos 69
W EB C ONTAINER 70

70 www.k19.com.br
71 W EB C ONTAINER

www.facebook.com/k19treinamentos 71
W EB C ONTAINER 72

6 Na viso Servers, com um clique duplo sobre o Wildfly abra as configuraes desse servidor. No
menu Publishing, marque a opo Automatically publish when resources change. Por fim, digite
CTRL + S para salvar as alteraes.

7 Pare o Wildfly e configure o Glassfish no Eclipse Mars. Digite CTRL + 3 para abrir o Quick
Access. Em seguida, pesquise por Define a new server.

72 www.k19.com.br
73 W EB C ONTAINER

www.facebook.com/k19treinamentos 73
W EB C ONTAINER 74

74 www.k19.com.br
75 W EB C ONTAINER

8 Na viso Servers, com um clique duplo sobre o Glassfish abra as configuraes desse servidor.
No menu Publishing, marque a opo Automatically publish when resources change. Por fim,
digite CTRL + S para salvar as alteraes.

Aplicao Web Java

www.facebook.com/k19treinamentos 75
W EB C ONTAINER 76

Para que uma aplicao web Java possa ser implantada em um Web Container, a estrutura de
pastas precisa seguir algumas regras.

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.

Exerccios de Fixao

9 Crie um projeto web chamado Servlet. Digite CTRL + 3 e pesquise por Dynamic Web Project.
Selecione a opo correspondente e siga as imagens abaixo.

76 www.k19.com.br
77 W EB C ONTAINER

10 Implante o projeto Servlet no Glassfish. Na viso Servers, clique com o boto direito do mouse
sobre o Glassfish, selecione a opo Add and Remove... e siga a imagem abaixo.

www.facebook.com/k19treinamentos 77
W EB C ONTAINER 78

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.

78 www.k19.com.br
79 W EB C ONTAINER

1 @WebServlet ( " / ola - mundo " )


2 public class OlaMundoServlet extends HttpServlet {
3
4 @Override
5 protected void service ( HttpServletRequest req , HttpServletResponse resp )
6 throws ServletException , IOException {
7 // Lgica para processar as regras de negcio e gerar contedo
8 }
9 }

Cdigo Java 4.1: OlaMundoServlet.java

O mtodo service() executado toda vez que uma requisio HTTP realizada para a url defi-
nida 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 par-
metro a referncia do objeto da classe HttpServletResponse que armazenar o contedo gerado
pela Servlet.

Inserindo contedo na resposta


Para inserir contedo texto na resposta HTTP que ser enviada para o navegador do usurio,
devemos utilizar os mtodos getWriter() e println(). Em geral, o contedo inserido na resposta
HTTP texto HTML. Veja o cdigo abaixo.

1 @WebServlet ( " / ola - mundo " )


2 public class OlaMundoServlet extends HttpServlet {
3
4 @Override
5 protected void service ( HttpServletRequest req , HttpServletResponse resp )
6 throws ServletException , IOException {
7 PrintWriter writer = resp . getWriter () ;
8 writer . println ( " < html > < body > < h1 > Ol Mundo </ h1 > </ body > </ html > " ) ;
9 }
10 }

Cdigo Java 4.2: OlaMundoServlet.java

Exerccios de Fixao

11 Crie um pacote chamado br.com.k19.servlets no projeto Servlet.

12 Crie uma classe chamada OlaMundoServlet no pacote br.com.k19.servlets.

1 package br . com . k19 . servlets ;


2
3 import java . io . IOException ;
4 import java . io . PrintWriter ;
5 import javax . servlet . ServletException ;
6 import javax . servlet . annotation . WebServlet ;
7 import javax . servlet . http . HttpServlet ;
8 import javax . servlet . http . HttpServletRequest ;
9 import javax . servlet . http . HttpServletResponse ;
10
11 @WebServlet ( " / ola - mundo " )
12 public class OlaMundoServlet extends HttpServlet {

www.facebook.com/k19treinamentos 79
W EB C ONTAINER 80

13
14 private static final long serialVersionUID = 1 L ;
15
16 @Override
17 protected void service ( HttpServletRequest req , HttpServletResponse resp )
18 throws ServletException , IOException {
19 PrintWriter writer = resp . getWriter () ;
20 writer . println ( " < html > < body > < h1 > Ol Mundo </ h1 > </ body > </ html > " ) ;
21 }
22 }

Cdigo Java 4.3: OlaMundoServlet.java

13 Verifique o funcionamento da OlaMundoServlet acessando a url abaixo em um navegador.

http://localhost:8080/Servlet/ola-mundo

14 Na viso Servers, clique com o boto direito do mouse sobre o Glassfish e selecione a opo
Stop.

15 Implante o projeto Servlet no Wildfly. Na viso Servers, clique com o boto direito do mouse
sobre o Wildfly, selecione a opo Add and Remove... e siga a imagem abaixo.

16 Na viso Servers, clique com o boto direito do mouse sobre o Wildfly e selecione a opo Start.

80 www.k19.com.br
81 W EB C ONTAINER

17 Verifique o funcionamento da OlaMundoServlet acessando a url abaixo em um navegador.

http://localhost:8080/Servlet/ola-mundo

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 fo-
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

Web Container
TP
Re

HT
sp

Requisio HTTP
Resposta HTTP
os

o
ta

si
H

ui
TT

q
Re
P

TP

Re
HT

sp
os
o

taH
isi
qu

TT
Re

www.k19.com.br www.k19.com.br www.k19.com.br

Cursos Artigos Apostilas

Figura 4.3: Framework para aplicaes web

Nos prximos captulos, mostraremos o funcionamento e explicaremos os conceitos relaciona-


dos ao framework JSF.

www.facebook.com/k19treinamentos 81
W EB C ONTAINER 82

82 www.k19.com.br
CAPTULO
V ISO G ERAL DO JSF 2.2
5
Atualmente, o principal framework para desenvolvimento de aplicaes web em Java o JSF
(Java Server Faces). A especificao desse framework pode ser obtida em https://jcp.org/en/jsr/
detail?id=344. 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.

MVC e Front Controller

O MVC (model-view-controller) um padro de arquitetura que tem por objetivo isolar a lgica
de negcio da lgica de apresentao de uma aplicao.

Esse padro (ou alguma variao) amplamente adotado nas principais plataformas de desen-
volvimento atuais. Em particular, ele bastante utilizado na plataforma Java.

O padro MVC divide uma aplicao em trs tipos de componentes: modelo, viso e controlador.

Modelo: encapsula os dados e as funcionalidades da aplicao.

Viso: responsvel pela exibio de informaes, cujos dados so obtidos do modelo.

Controlador: recebe as requisies do usurio e aciona o modelo e/ou a viso.

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, Re-
gine Meunier, Hans Rohnert, Peter Sommerlad, Michael Stal e Michael Stal.

No padro Front Controller, todas as requisies do usurio so recebidas pelo mesmo compo-
nente. Dessa forma, tarefas que devem ser realizadas em todas as requisies podem ser implemen-
tadas 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.

Configurando uma aplicao JSF

Uma aplicao JSF deve respeitar a estrutura geral de uma aplicao web Java que foi descrita no
captulo anterior. Essa estrutura defina pela especificao Servlet que est disponvel em https:
//jcp.org/en/jsr/detail?id=340.

www.facebook.com/k19treinamentos 83
V ISO G ERAL DO JSF 2.2 84

web.xml
A Faces Servlet deve ser configurada no arquivo WEB-INF/web.xml, indicando a classe que a im-
plementa 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 < servlet >


2 < servlet - name > Faces Servlet </ servlet - name >
3 < servlet - class > javax . faces . webapp . FacesServlet </ servlet - class >
4 </ servlet >
5 < servlet - mapping >
6 < servlet - name > Faces Servlet </ servlet - name >
7 <url - pattern > *. xhtml </ url - pattern >
8 </ servlet - mapping >

Cdigo XML 5.1: web.xml

faces-config.xml
Devemos adicionar um arquivo chamado faces-config.xml no diretrio WEB-INF. Nesse ar-
quivo, podemos alterar diversas configuraes do JSF. Mas, a princpio, podemos deix-lo apenas
com a tag faces-config.

1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < faces - config
3 xmlns = " http: // xmlns . jcp . org / xml / ns / javaee "
4 xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
5 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / javaee
6 http: // xmlns . jcp . org / xml / ns / javaee / web - facesconfig_2_2 . xsd "
7 version = " 2.2 " >
8
9 </ 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 manu-
almente 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.

3. Executar tarefas de acordo com as aes dos usurios.

84 www.k19.com.br
85 V ISO G ERAL DO JSF 2.2

Criando um Managed Bean


Um managed bean pode ser definido de duas maneiras. A primeira maneira criar uma classe
Java e registr-la no arquivo faces-config.xml. Veja o exemplo abaixo.

1 package br . com . k19 ;


2
3 public class TesteBean {
4 ...
5 }

Cdigo Java 5.1: TesteBean.java

1 ...
2 < managed - bean >
3 < managed - bean - name > testeBean </ managed - bean - name >
4 < managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
5 < managed - bean - scope > request </ managed - bean - scope >
6 </ managed - bean >
7 ...

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 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 @ManagedBean
2 public class TesteBean {
3 ...
4 }

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 @ManagedBean
2 public class TesteBean {
3 private int numero ;
4 }

Cdigo Java 5.3: TesteBean.java

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 @ManagedBean
2 public class TesteBean {
3 private int numero ;
4

www.facebook.com/k19treinamentos 85
V ISO G ERAL DO JSF 2.2 86

5 public int getNumero () {


6 return numero ;
7 }
8 }

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 pgina web, precisa-
mos definir um mtodo de escrita.

1 @ManagedBean
2 public class TesteBean {
3 private int numero ;
4
5 public int setNumero ( int numero ) {
6 this . numero = numero ;
7 }
8
9 public int getNumero () {
10 return numero ;
11 }
12 }

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 utili-
zando expression language (#{}). Veja o exemplo a seguir.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 Valor : #{ testeBean . numero }
13 </ h : body >
14 </ 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.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >

86 www.k19.com.br
87 V ISO G ERAL DO JSF 2.2

9 </ h : head >


10
11 <h : body >
12
13 Valor : #{ testeBean . numero }
14
15 <h : form >
16 <h : inputText value = " #{ testeBean . numero } " / >
17 <h : commandButton value = " Altera " / >
18 </ h : form >
19 </ h : body >
20 </ html >

Cdigo XHTML 5.2: Alterando o valor do atributo numero

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 substitusse-


mos 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 Valor : #{ testeBean . valor }


2 <h : inputText value = " #{ testeBean . valor } " / >

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 @ManagedBean
2 public class TesteBean {
3 private int numero ;
4
5 public void incrementaNumero () {
6 this . numero = numero + 1;
7 }
8
9 // GETTERS E SETTERS
10 }

Cdigo Java 5.6: TesteBean.java

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.

www.facebook.com/k19treinamentos 87
V ISO G ERAL DO JSF 2.2 88

1 <h : form >


2 <h : commandButton value = " Incrementa " action = " #{ testeBean . incrementaNumero } " / >
3 </ h : form >

Cdigo XHTML 5.4: Boto associado a um mtodo de um managed bean

Mais Sobre
Todo managed bean possui um nome nico que utilizado para acess-lo den-
tro 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 argu-
mento na anotao.

1 @ManagedBean ( name = " teste " )


2 class TesteBean {
3 ...
4 }

Cdigo Java 5.7: Alterando o nome de um managed bean

Processamento de uma requisio

Em uma aplicao JSF, toda requisio realizada atravs de um navegador recebida pela Faces
Servlet. Ao receber uma requisio, a Faces Servlet executa os seguintes passos:

Restore View: Na primeira requisio de um usurio, uma nova rvore de componentes que repre-
senta 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).
Se ocorrer algum erro de converso ou validao, mensagens de erro so adicionadas no con-
texto da requisio atual e o fluxo redirecionado para a fase Render Response. Caso contrrio,
processo continua na fase Update Model Values.
Ainda nesta fase, os eventos de mudana de valor so identificados e tratados ao final da
mesma.

Update Model Values: Os valores contidos em cada componente da rvore, j convertidos e valida-
dos na fase anterior, so armazenados em propriedades de objetos definidos pela aplicao
(managed beans)

88 www.k19.com.br
89 V ISO G ERAL DO JSF 2.2

Invoke Application: Uma vez que os dados dos componentes j foram convertidos, validados e ar-
mazenados nos objetos do modelo, as tarefas correspondentes ao evento que disparou a re-
quisio (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 requi-
sio 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.facebook.com/k19treinamentos 89
V ISO G ERAL DO JSF 2.2 90

www.k19.com.br

L
HTMscript
a
Jav
CSS

Requisio HTTP Resposta HTTP

Faces Servlet

Restore Apply Request Process Update Ivoke Render


View Values Validation Model Application Response

MANAGED BEANS

CONTROLE
MODELO VISO

TELAS

ENTIDADES

TEMPLATES

REPOSITRIOS TELAS PARCIAIS

Figura 5.1: Estrutura geral de uma aplicao JSF

90 www.k19.com.br
91 V ISO G ERAL DO JSF 2.2

Os managed beans esto disposio da Faces Servlet durante todo o processamento da requi-
sio. 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 funciona-


mento bsico do JSF. Essa aplicao dever receber um texto do usurio e exibi-lo em letras mais-
culas.

Managed Bean

Vamos comear criando um managed bean para armazenar o texto enviado pelo usurio e a
lgica para transform-lo.

1 import javax . faces . bean . ManagedBean ;


2
3 @ManagedBean
4 public class TextoBean {
5 private String texto ;
6
7 public String transformaEmCaixaAlta () {
8 this . texto = this . texto . toUpperCase () ;
9 return " resposta " ;
10 }
11
12 public String getTexto () {
13 return this . texto ;
14 }
15
16 public void setTexto ( String texto ) {
17 this . texto = texto ;
18 }
19 }

Cdigo Java 5.8: TextoBean.java

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 transformaEm-
CaixaAlta(). Esse mtodo devolve uma string para indicar qual deve ser a prxima tela a ser enviada
para o usurio.

www.facebook.com/k19treinamentos 91
V ISO G ERAL DO JSF 2.2 92

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 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets "
6 xmlns : h = " http :// java . sun . com / jsf / html "
7 xmlns : f = " http :// java . sun . com / jsf / core " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12
13 <h : body >
14 <h : form >
15 <h : outputLabel value = " Texto : " / >
16 <h : inputTextarea value = " #{ textoBean . texto } " / >
17 <h : commandButton value = " Transformar " action = " #{ textoBean . transformaEmCaixaAlta } " / >
18 </ h : form >
19 </ h : body >
20 </ 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 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets "
6 xmlns : h = " http :// java . sun . com / jsf / html "
7 xmlns : f = " http :// java . sun . com / jsf / core " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12
13 <h : body >
14 <h : outputText value = " #{ textoBean . texto } " / >
15 </ h : body >
16 </ html >

Cdigo XHTML 5.6: resposta.xhtml

Analogamente, a caixa de sada de texto est associada propriedade texto do managed bean
TextoBean.

92 www.k19.com.br
93 V ISO G ERAL DO JSF 2.2

Exerccios de Fixao

1 Crie um projeto chamado K19-Visao-Geral. Digite CTRL + 3 e pesquise por Dynamic Web
Project. Selecione a opo correspondente e siga as imagens abaixo.

www.facebook.com/k19treinamentos 93
V ISO G ERAL DO JSF 2.2 94

94 www.k19.com.br
95 V ISO G ERAL DO JSF 2.2

www.facebook.com/k19treinamentos 95
V ISO G ERAL DO JSF 2.2 96

2 Altere o arquivo de configurao web.xml do projeto K19-Visao-Geral.

1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 <web - app xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
3 xmlns = " http: // xmlns . jcp . org / xml / ns / javaee "
4 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / javaee
5 http: // xmlns . jcp . org / xml / ns / javaee / web - app_3_1 . xsd "
6 version = " 3.1 " >
7 < display - name >K19 - Visao - Geral </ display - name >
8 < servlet >
9 < servlet - name > Faces Servlet </ servlet - name >
10 < servlet - class > javax . faces . webapp . FacesServlet </ servlet - class >
11 < load - on - startup >1 </ load - on - startup >
12 </ servlet >
13 < servlet - mapping >
14 < servlet - name > Faces Servlet </ servlet - name >
15 <url - pattern > *. xhtml </ url - pattern >
16 </ servlet - mapping >
17
18 < context - param >
19 < param - name > javax . faces . PROJECT_STAGE </ param - name >
20 < param - value > Development </ param - value >
21 </ context - param >
22 </ web - app >

Cdigo XML 5.4: web.xml

3 Em um pacote chamado br.com.k19.controle no projeto K19-Visao-Geral, crie um managed


bean para armazenar um nmero inteiro n enviado pelo usurio, gerar um nmero aleatrio entre
zero e n e armazen-lo em uma propriedade.

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4
5 @ManagedBean
6 public class NumeroAleatorioBean {
7 private int maximo ;
8 private int numeroAleatorio ;
9
10 public String geraNumeroAleatorio () {
11 this . numeroAleatorio = ( int ) ( Math . random () * this . maximo ) ;
12 return " resposta " ;
13 }
14
15 // GETTERS E SETTERS
16 }

Cdigo Java 5.9: NumeroAleatorioBean.java

4 Crie um arquivo chamado formulario.xhtml. Digite CTRL + 3 e pesquise por Create a new
HTML file. Selecione a opo correspondente e siga as imagens abaixo.

96 www.k19.com.br
97 V ISO G ERAL DO JSF 2.2

5 Altere o cdigo do arquivo formulario.xhtml

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >

www.facebook.com/k19treinamentos 97
V ISO G ERAL DO JSF 2.2 98

9 </ h : head >


10
11 <h : body >
12 <h : form >
13 <h : outputLabel value = " Nmero mximo : " / >
14 <h : inputText value = " #{ numeroAleatorioBean . maximo } " / >
15 <h : commandButton value = " Gera nmero aleatrio "
16 action = " #{ numeroAleatorioBean . geraNumeroAleatorio } " / >
17 </ h : form >
18 </ h : body >
19 </ html >

Cdigo XHTML 5.7: formulario.xhtml

6 Agora, crie um arquivo chamado resposta.xhtml com o contedo abaixo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 <h : outputText value = " #{ numeroAleatorioBean . numeroAleatorio } " / >
13 </ h : body >
14 </ html >

Cdigo XHTML 5.8: resposta.xhtml

7 Remova o projeto Servlet do Glassfish e do Wildfly. Implante o projeto K19-Visao-Geral no


Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o endereo abaixo
para testar a aplicao.

http://localhost:8080/K19-Visao-Geral/formulario.xhtml.

8 Implante o projeto K19-Visao-Geral no Wildfly. Certifique-se que o Glassfish esteja parado.


Inicie o Wildfly e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Visao-Geral/formulario.xhtml.

98 www.k19.com.br
CAPTULO
C OMPONENTES V ISUAIS
6
No JSF 2, as telas so definidas em arquivos XHTML. Os componentes visuais que constituem as
telas so adicionados por meio de tags. A especificao do JSF define uma grande quantidade de tags
e as classifica em bibliotecas. As principais bibliotecas de tags do JSF so:

Core (http://java.sun.com/jsf/core)

HTML (http://java.sun.com/jsf/html)

Facelets (http://java.sun.com/jsf/facelets)

A seguir, apresentaremos o funcionamento geral das principais tags dessas trs bibliotecas. A
documentao completa pode ser encontrada em http://www.jcp.org/en/jsr/detail?id=314.

Estrutura Bsica de uma Pgina JSF

A estrutura bsica de uma pgina JSF muito semelhante estrutura de uma pgina HTML.
Observe o cdigo abaixo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets "
6 xmlns : h = " http :// java . sun . com / jsf / html "
7 xmlns : f = " http :// java . sun . com / jsf / core " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12
13 <h : body >
14 <h : outputText value = " Estrutura bsica de uma tela JSF " / >
15 </ h : body >
16 </ 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 atra-
vs do pseudo-atributo xmlns aplicado tag <html>. Observe no exemplo acima que as trs princi-
pais bibliotecas do JSF foram importadas.

www.facebook.com/k19treinamentos 99
C OMPONENTES V ISUAIS 100

Mais Sobre
Devemos utilizar a declarao <!DOCTYPE> para informar aos navegadores qual a ver-
so do HTML utilizado na pgina. Com essa informao, os navegadores podem pro-
cessar o documento corretamente.

Mais Sobre
Quando uma biblioteca de tags importada atravs do pseudo-atributo xmlns, pos-
svel 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 com-
pleto 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 com-
ponentes.

Formulrios

Os formulrios no JSF so definidos atravs da tag <h:form> (e no pela tag <form>). Um formu-
lrio 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 exibe o que foi digitado.

Uma caixa de texto pode ser associada a uma propriedade de um managed bean atravs do atri-
buto value. Esse vnculo denominado binding. Considere o seguinte managed bean.

1 @ManagedBean
2 public class UsuarioBean {

100 www.k19.com.br
101 C OMPONENTES V ISUAIS

3 private String nome ;


4
5 public String getNome () {
6 return nome ;
7 }
8
9 public void setNome ( String nome ) {
10 this . nome = nome ;
11 }
12 }

Cdigo Java 6.1: UsuarioBean.java

Devemos utilizar expression language (#{}) para estabelecer uma associao entre a propriedade
nome a uma caixa de texto. Observe o cdigo abaixo.

1 <h : inputText value = " #{ usuarioBean . nome } " / >

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 <h : outputLabel value = " Nome : " for = " nome " / >
2 <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 navega-
dor.

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 " / >

Resultado:

www.facebook.com/k19treinamentos 101
C OMPONENTES V ISUAIS 102

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 >

102 www.k19.com.br
103 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.facebook.com/k19treinamentos 103
C OMPONENTES V ISUAIS 104

O JSF define sete tipos de caixas de seleo.

<h:selectBooleanCheckbox>
Permite que o usurio faa selees do tipo sim ou no.
<h:selectManyCheckbox>
Permite que o usurio faa mltiplas selees do tipo sim ou no.
<h:selectOneRadio>, <h:selectOneMenu>, <h:selectOneListbox>
Permitem a seleo de uma nica opo de um conjunto de opes. A principal diferena entre
essas tags modo como elas so apresentadas visualmente.
<h:selectManyListbox>, <h:selectManyMenu>
Possibilita a seleo de diversas opes de um conjunto de opes. A diferena principal entre
essas duas tags modo como elas so apresentadas visualmente.

Podemos vincular uma caixa de seleo a uma propriedade de um managed bean atravs do atri-
buto value. No exemplo abaixo, uma caixa de seleo associada propriedade aceito do managed
bean ContratoBean.

1 <h : selectBooleanCheckbox value = " #{ contratoBean . aceito } " / >

Cdigo XHTML 6.12: Caixa de seleo vinculada propriedade aceito do managed bean ContratoBean

Caixas de seleo do tipo <h:selectBooleanCheckbox> devem ser vinculadas a propriedades


booleanas.

Opes Estticas e Dinmicas


As opes de uma caixa de seleo (com exceo da <h:selectBooleanCheckbox>) podem ser
definidas esttica ou dinamicamente. Estaticamente, cada opo pode ser adicionada atravs da tag
<f:selectItem>. Considere o seguinte exemplo.

1 <h : selectOneMenu value = " #{ cursosBean . siglaDoCursoEscolhido } " >


2 <f : selectItem itemValue = " K11 " itemLabel = " Orientao a Objetos em Java " >
3 <f : selectItem itemValue = " K12 " itemLabel = " Desenvolvimento Web com JSF2 e JPA2 " >
4 </ h : selectOneMenu >

Cdigo XHTML 6.13: Caixa de seleo com opes definidas estaticamente

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 dina-
micamente todos os cursos cadastrados. Isso pode ser realizado atravs da tag <f:selectItems>.

1 <h : selectOneMenu value = " #{ cursosBean . siglaDoCursoEscolhido } " >


2 <f : selectItems
3 value = " #{ cursosBean . cursos } "

104 www.k19.com.br
105 C OMPONENTES V ISUAIS

4 var = " curso "


5 itemValue = " #{ curso . sigla } "
6 itemLabel = " #{ curso . nome } " >
7 </ 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.

Seleo nica ou Mltipla


Algumas caixas de seleo permitem que apenas uma opo seja selecionada, enquanto outras
permitem que mltiplas opes sejam selecionadas. Considere um formulrio que permita ao usu-
rio escolher apenas um dos cursos de uma lista. Como vimos, esse formulrio pode ter a seguinte
estrutura:

1 <h : selectOneListbox value = " #{ cursosBean . siglaDoCursoEscolhido } " >


2 <f : selectItems
3 value = " #{ cursosBean . cursos } "
4 var = " curso "
5 itemValue = " #{ curso . sigla } "
6 itemLabel = " #{ curso . nome } " / >
7 </ h : selectOneListbox >

Cdigo XHTML 6.15: Seleo de um nico curso

1 @ManagedBean
2 public class CursosBean {
3 private String siglaDoCursoEscolhido ;
4 private List < Curso > cursos ;
5
6 // GETTERS E SETTERS
7 }

Cdigo Java 6.2: CursosBean.java

1 public class Curso {


2 private String sigla ;
3 private String nome ;
4
5 // GETTERS E SETTERS
6 }

Cdigo Java 6.3: Curso.java

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,
devemos adicionar uma propriedade no managed bean CursosBean, como mostra o cdigo abaixo.

1 @ManagedBean
2 public class CursosBean {

www.facebook.com/k19treinamentos 105
C OMPONENTES V ISUAIS 106

3 private List < String > siglasDosCursosEscolhidos ;


4 private List < Curso > cursos ;
5
6 // GETTERS E SETTERS
7 }

Cdigo Java 6.4: CursosBean.java

Para permitir a seleo mltipla, devemos utilizar uma caixa de seleo do tipo <h:selectMany-
Listbox> ou <h:selectManyMenu>. Essa caixa deve ento ser vinculada nova propriedade do ma-
naged bean CursoBean. Por exemplo, se optarmos pela <h:selectManyListbox>, poderamos ter o
seguinte cdigo.

1 <h : selectManyListbox value = " #{ cursosBean . siglasDosCursosEscolhidos } " >


2 <f : selectItems
3 value = " #{ cursosBean . cursos } "
4 var = " curso "
5 itemValue = " #{ curso . sigla } "
6 itemLabel = " #{ curso . nome } " / >
7 </ h : selectManyListbox >

Cdigo XHTML 6.16: Seleo de diversos cursos

Caixa de Seleo com Pseudo-opo


Por padro, a caixa de seleo do tipo <h:selectOneMenu> sempre tem uma opo selecionada.
Contudo, em alguns casos, faz sentido para o usurio no selecionar nenhuma das opes dispon-
veis. Para resolver esse problema, podemos adicionar uma pseudo-opo na caixa de seleo. Con-
sidere o cdigo abaixo.

1 <h : selectOneMenu value = " #{ cursosBean . siglaDoCursoEscolhido } " >


2 <f : selectItem itemLabel = " Nenhum " noSelectionOption = " true " / >
3 <f : selectItems
4 value = " #{ cursosBean . cursos } "
5 var = " curso "
6 itemValue = " #{ curso . sigla } "
7 itemLabel = " #{ curso . nome } " / >
8 </ h : selectOneMenu >

Cdigo XHTML 6.17: Pseudo-opo

Para adicionar uma pseudo-opo, basta utilizar a tag <f:selectItem> com o atributo noSe-
lectionOption 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.

1. XHTML:

1 <h : outputLabel value = " Ex - aluno " for = " exaluno " / >
2 <h : selectBooleanCheckbox value = " #{ cursosBean . exAluno } " id = " exaluno " / >

106 www.k19.com.br
107 C OMPONENTES V ISUAIS

HTML gerado:

1 < label for = " j_idt6 : exaluno " >Ex - aluno </ label >
2 < input id = " j_idt6 : exaluno " type = " checkbox " name = " j_idt6 : exaluno " / >

Resultado:

Ex-aluno

2. XHTML:

1 <h : selectManyCheckbox value = " #{ cursosBean . siglasDosCursosEscolhidos } "


2 layout = " pageDirection " >
3 <f : selectItems
4 value = " #{ cursosBean . cursos } "
5 var = " curso "
6 itemValue = " #{ curso . sigla } "
7 itemLabel = " #{ curso . nome } " / >
8 </ h : selectManyCheckbox >

HTML gerado:

1 < table >


2 < tr >
3 < td >
4 < input name = " j_idt6 : j_idt27 " id = " j_idt6 : j_idt27 :0 " value = " K11 " type = " checkbox " / -
>
5 < label for = " j_idt6 : j_idt27 :0 " class = " " > Orientao a Objetos em Java </ label >
6 </ td >
7 </ tr >
8 < tr >
9 < td >
10 < input name = " j_idt6 : j_idt27 " id = " j_idt6 : j_idt27 :1 " value = " K12 " type = " checkbox " / -
>
11 < label for = " j_idt6 : j_idt27 :1 " class = " " >
12 Desenvolvimento Web com JSF2 e JPA2
13 </ label >
14 </ td >
15 </ tr >
16 < tr >
17 < td >
18 < input name = " j_idt6 : j_idt27 " id = " j_idt6 : j_idt27 :2 " value = " K51 " type = " checkbox " / -
>
19 < label for = " j_idt6 : j_idt27 :2 " class = " " > Design Patterns em Java </ label >
20 </ td >
21 </ tr >
22 </ table >

Resultado:

Orientao a Objetos em Java


Desenvolvimento Web com JSF2 e JPA2
Design Patterns em Java

3. XHTML:

1 <h : selectOneRadio value = " #{ cursosBean . siglasDosCursosEscolhidos } " layout = " -


lineDirection " >
2 <f : selectItems
3 value = " #{ cursosBean . cursos } "
4 var = " curso "
5 itemValue = " #{ curso . sigla } "

www.facebook.com/k19treinamentos 107
C OMPONENTES V ISUAIS 108

6 itemLabel = " #{ curso . nome } " / >


7 </ h : selectOneRadio >

HTML gerado:

1 < table >


2 < tr >
3 < td >
4 < input type = " radio " name = " j_idt6 : j_idt30 " id = " j_idt6 : j_idt30 :0 " value = " K11 " / >
5 < label for = " j_idt6 : j_idt30 :0 " > Orientao a Objetos em Java </ label >
6 </ td >
7 < td >
8 < input type = " radio " name = " j_idt6 : j_idt30 " id = " j_idt6 : j_idt30 :1 " value = " K12 " / >
9 < label for = " j_idt6 : j_idt30 :1 " > Desenvolvimento Web com JSF2 e JPA2 </ label >
10 </ td >
11 < td >
12 < input type = " radio " name = " j_idt6 : j_idt30 " id = " j_idt6 : j_idt30 :2 " value = " K51 " / >
13 < label for = " j_idt6 : j_idt30 :2 " > Design Patterns em Java </ label >
14 </ td >
15 </ tr >
16 </ table >

Resultado:

Orientao a Objetos em Java Desenvolvimento Web com JSF2 e JPA2 Design Patterns em Java

4. XHTML:

1 <h : selectOneMenu value = " #{ cursosBean . siglasDosCursosEscolhidos } " >


2 <f : selectItem itemLabel = " Escolha um curso " noSelectionOption = " true " / >
3 <f : selectItems
4 value = " #{ cursosBean . cursos } "
5 var = " curso "
6 itemValue = " #{ curso . sigla } "
7 itemLabel = " #{ curso . nome } " / >
8 </ h : selectOneMenu >

HTML gerado:

1 < select name = " j_idt6 : j_idt33 " size = " 1 " >
2 < option value = " " > Escolha um curso </ option >
3 < option value = " K11 " > Orientao a Objetos em Java </ option >
4 < option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >
5 < option value = " K51 " > Design Patterns em Java </ option >
6 </ 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 <h : selectOneListbox value = " #{ cursosBean . siglasDosCursosEscolhidos } " >


2 <f : selectItems
3 value = " #{ cursosBean . cursos } "
4 var = " curso "
5 itemValue = " #{ curso . sigla } "

108 www.k19.com.br
109 C OMPONENTES V ISUAIS

6 itemLabel = " #{ curso . nome } " / >


7 </ h : selectOneListbox >

HTML gerado:

1 < select name = " j_idt6 : j_idt37 " size = " 3 " >
2 < option value = " K11 " > Orientao a Objetos em Java </ option >
3 < option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >
4 < option value = " K51 " > Design Patterns em Java </ option >
5 </ select >

Resultado:

Orientao a Objetos em Java


Desenvolvimento Web com JSF2 e JPA2
Design Patterns em Java

6. XHTML:

1 <h : selectManyListbox value = " #{ cursosBean . siglasDosCursosEscolhidos } " >


2 <f : selectItems
3 value = " #{ cursosBean . cursos } "
4 var = " curso "
5 itemValue = " #{ curso . sigla } "
6 itemLabel = " #{ curso . nome } " / >
7 </ h : selectManyListbox >

HTML gerado:

1 < select name = " j_idt6 : j_idt40 " multiple = " multiple " size = " 3 " >
2 < option value = " K11 " > Orientao a Objetos em Java </ option >
3 < option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >
4 < option value = " K51 " > Design Patterns em Java </ option >
5 </ select >

Resultado:

Orientao a Objetos em Java


Desenvolvimento Web com JSF2 e JPA2
Design Patterns em Java

7. XHTML:

1 <h : selectManyMenu value = " #{ cursosBean . siglasDosCursosEscolhidos } " style = " height : 70 px -
;">
2 <f : selectItem itemLabel = " Escolha um curso " noSelectionOption = " true " / >
3 <f : selectItems
4 value = " #{ cursosBean . cursos } "
5 var = " curso "
6 itemValue = " #{ curso . sigla } "
7 itemLabel = " #{ curso . nome } " / >
8 </ h : selectManyMenu >

HTML gerado:

1 < select name = " j_idt6 : j_idt43 " multiple = " multiple " size = " 1 " style = " height : 70 px ; " >
2 < option value = " " selected = " selected " > Escolha um curso </ option >
3 < option value = " K11 " > Orientao a Objetos em Java </ option >
4 < option value = " K12 " > Desenvolvimento Web com JSF2 e JPA2 </ option >

www.facebook.com/k19treinamentos 109
C OMPONENTES V ISUAIS 110

5 < option value = " K51 " > Design Patterns em Java </ option >
6 </ 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 explicita-
mente 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 mto-
dos de ao de um managed bean atravs dos atributos action e actionListener. Esses atributos
sero detalhados em outro captulo.

1 <h : commandButton value = " Adiciona curso " action = " #{ cursosBean . adicionaCurso } " / >
2 <h : commandLink value = " Remove curso " action = " #{ cursosBean . removeCurso } " / >

Cdigo XHTML 6.25: Exemplos de utilizao do <h:commandButton> e do <h:commandLink>

A diferena bsica entre o <h:commandButton> e o <h:commandLink> o modo como eles so


apresentados visualmente.

Os componentes <h:button> e <h:link>, por sua vez, so usados para realizar requisies atra-
vs do mtodo GET. O JSF utiliza o atributo outcome de um <h:button> ou <h:link> para definir a
pgina de destino. Esses componentes no so utilizados para submeter formulrios HTML.

1 <h : button value = " Lista de cursos " outcome = " lista - cursos " / >
2 <h : link value = " Home " outcome = " home " / >

Cdigo XHTML 6.26: Exemplos de utilizao do <h:button> e do <h:link>

Novamente, a diferena fundamental entre o <h:button> e o <h:link> o modo como eles so


exibidos visualmente.

O componente <h:outputLink> permite apenas a criao de links HTML que realizam requisi-
es do tipo GET. Diferentemente dos componentes <h:button> e <h:link>, a URL da requisio
definida explicitamente no atributo value.

110 www.k19.com.br
111 C OMPONENTES V ISUAIS

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 <a href = " # " onclick = " mojarra . jsfcljs ( document . getElementById ( j_idt62 ) ,{ j_idt62 : -
j_idt66 : j_idt62 : j_idt66 } , ) ; return false " >
2 Remove curso
3 </ a >

Resultado:

Remove curso

3. XHTML:

1 <h : button value = " Lista de cursos " outcome = " lista - cursos " / >

HTML gerado:

1 < input
2 type = " button "
3 onclick = " window . location . href = / K19 - Componentes - Visuais / lista - cursos . xhtml ; return -
false ; "
4 value = " Lista de cursos " / >

Resultado:

Lista de cursos

4. XHTML:

1 <h : link value = " Home " outcome = " home " / >

HTML gerado:

www.facebook.com/k19treinamentos 111
C OMPONENTES V ISUAIS 112

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 um projeto chamado K19-Componentes-Visuais seguindo os passos vistos nos exerccios


do Captulo 5.

2 Crie uma classe chamada UsuarioBean em um pacote chamado br.com.k19.controle. 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.

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4
5 @ManagedBean
6 public class UsuarioBean {
7 private String nome ;
8 private int idade ;
9
10 // GETTERS E SETTERS
11 }

Cdigo Java 6.5: UsuarioBean.java

3 Crie um arquivo XHTML chamado usuario.xhtml. Nesse arquivo, crie um formulrio para o
usurio digitar e enviar o seu nome e a sua idade.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >

112 www.k19.com.br
113 C OMPONENTES V ISUAIS

8 < title > K19 Treinamentos </ title >


9 </ h : head >
10 <h : body >
11 <h : form >
12 <h : outputLabel value = " Nome : " for = " campo - nome " / >
13 <h : inputText value = " #{ usuarioBean . nome } " id = " campo - nome " / >
14
15 <h : outputLabel value = " Idade : " for = " campo - idade " / >
16 <h : inputText value = " #{ usuarioBean . idade } " id = " campo - idade " / >
17
18 <h : commandButton value = " Enviar " / >
19 </ h : form >
20 </ h : body >
21 </ html >

Cdigo XHTML 6.33: usuario.xhtml

4 Remova o projeto K19-Visao-Geral do Glassfish e do Wildfly. Implante o projeto K19-Componentes-


Visuais no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o endereo
abaixo para testar a aplicao.

http://localhost:8080/K19-Componentes-Visuais/usuario.xhtml.

5 Implante o projeto K19-Componentes-Visuais no Wildfly. Certifique-se que o Glassfish esteja


parado. Inicie o Wildfly e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Componentes-Visuais/usuario.xhtml.

6 No arquivo usuario.xhtml, acrescente um trecho de cdigo para exibir os dados do usurio.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 <h : form >
12 <h : outputLabel value = " Nome : " for = " campo - nome " / >
13 <h : inputText value = " #{ usuarioBean . nome } " id = " campo - nome " / >
14
15 <h : outputLabel value = " Idade : " for = " campo - idade " / >
16 <h : inputText value = " #{ usuarioBean . idade } " id = " campo - idade " / >
17
18 <h : commandButton value = " Enviar " / >
19 </ h : form >
20
21 O nome do usurio <b > #{ usuarioBean . nome } </ b >
22 e sua idade <b > #{ usuarioBean . idade } </ b >.
23 </ h : body >
24 </ html >

Cdigo XHTML 6.34: usuario.xhtml

www.facebook.com/k19treinamentos 113
C OMPONENTES V ISUAIS 114

7 Observe o resultado das alteraes realizadas acessando novamente a aplicao no endereo


abaixo.

http://localhost:8080/K19-Componentes-Visuais/usuario.xhtml

8 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 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4
5 @ManagedBean
6 public class ConversorMonetarioBean {
7 private String de ;
8 private String para ;
9 private Double valor ;
10
11 // GETTERS E SETTERS
12 }

Cdigo Java 6.6: ConversorMonetarioBean.java

9 Na classe ConversorMonetarioBean adicione um mtodo para realizar a converso e um atri-


buto para armazenar o resultado.

1 package br . com . k19 . controle ;


2
3 import java . util . LinkedHashMap ;
4 import java . util . Map ;
5 import javax . faces . bean . ManagedBean ;
6
7 @ManagedBean
8 public class ConversorMonetarioBean {
9 private String de ;
10 private String para ;
11 private Double valor ;
12
13 private Double resultado ;
14
15 private Map < String , Double > taxas = new LinkedHashMap < String , Double >() ;
16
17 public ConversorMonetarioBean () {
18 this . taxas . put ( " Real " , 1.0) ;
19 this . taxas . put ( " Euro " , 2.33) ;
20 this . taxas . put ( " Peso argentino " , 0.42) ;
21 this . taxas . put ( " Dolar americano " , 1.84) ;
22 }
23
24 public void converte () {
25 this . resultado = this . valor * this . taxas . get ( this . de ) / this . taxas . get ( this . para ) ;
26 }
27
28 // GETTERS E SETTERS
29 }

Cdigo Java 6.7: ConversorMonetarioBean.java

114 www.k19.com.br
115 C OMPONENTES V ISUAIS

10 Crie um arquivo XHTML chamado conversor-monetario.xhtml. Nesse arquivo, implemente


um formulrio para o usurio digitar os dados de entrada e ver o resultado da converso.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : form >
13 <h : commandButton value = " Converter " action = " #{ conversorMonetarioBean . converte } " / >
14
15 <h : inputText value = " #{ conversorMonetarioBean . valor } " / >
16
17 <h : outputLabel value = " de " for = " de " / >
18
19 <h : selectOneMenu value = " #{ conversorMonetarioBean . de } " id = " de " >
20 <f : selectItems
21 value = " #{ conversorMonetarioBean . taxas . keySet () } "
22 var = " moeda "
23 itemValue = " #{ moeda } "
24 itemLabel = " #{ moeda } " / >
25 </ h : selectOneMenu >
26
27 <h : outputLabel value = " para " for = " para " / >
28
29 <h : selectOneMenu value = " #{ conversorMonetarioBean . para } " id = " para " >
30 <f : selectItems
31 value = " #{ conversorMonetarioBean . taxas . keySet () } "
32 var = " moeda "
33 itemValue = " #{ moeda } "
34 itemLabel = " #{ moeda } " / >
35 </ h : selectOneMenu >
36 </ h : form >
37
38 Resultado : #{ conversorMonetarioBean . resultado }
39
40 </ h : body >
41 </ html >

Cdigo XHTML 6.35: conversor-monetario.xhtml

11 Acesse a aplicao no endereo abaixo.

http://localhost:8080/K19-Componentes-Visuais/conversor-monetario.xhtml

Exerccios Complementares

1 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.

www.facebook.com/k19treinamentos 115
C OMPONENTES V ISUAIS 116

Textos e Imagens

Para inserir textos em uma pgina, podemos usar os componentes <h:outputText> e <h:output-
Format>. 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 <h : outputFormat value = " Preo do produto {0}: R$ {1} " >
2 <f : param value = " #{ lojaBean . produto . nome } " / >
3 <f : param value = " #{ lojaBean . produto . preco } " / >
4 </ h : outputFormat >

Cdigo XHTML 6.37: Exemplo de utilizao do <h:outputFormat>

O componente <h:graphicImage> usado para inserir imagens. Podemos indicar o caminho da


imagem atravs dos atributos value ou url. Esses dois atributos so exatamente iguais.

1 <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 bibli-
otecas 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
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 p-


gina 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 <h : outputFormat value = " Preo do produto {0}: R$ {1} "


2 rendered = " #{ lojaBean . produto . mostraPreco } " >
3 <f : param value = " #{ lojaBean . produto . nome } " / >
4 <f : param value = " #{ lojaBean . produto . preco } " / >
5 </ h : outputFormat >

116 www.k19.com.br
117 C OMPONENTES V ISUAIS

Cdigo XHTML 6.40: O preo do produto exibido somente se o valor da propriedade mostraPreco for true

Exemplos

1. XHTML:

1 <h : outputText value = " Curso : #{ curso . sigla } - #{ curso . descricao } " / >

HTML gerado:

1 Curso : K12 - Desenvolvimento Web com JSF2 e JPA2

2. XHTML:

1 <h : outputFormat value = " {0} amava {1} que amava {2} que amava {3}
2 que amava {4} que amava {5} que no amava ningum . {0} foi
3 para os Estados Unidos , {1} para o convento , {2} morreu de
4 desastre , {3} ficou para tia , {4} suicidou - se e {5} casou
5 com J . Pinto Fernandes que no tinha entrado na histria . " >
6
7 <f : param value = " Joo " / >
8 <f : param value = " Teresa " / >
9 <f : param value = " Raimundo " / >
10 <f : param value = " Maria " / >
11 <f : param value = " Joaquim " / >
12 <f : param value = " Lili " / >
13 </ h : outputFormat >

HTML gerado:

1 Joo amava Teresa que amava Raimundo que amava Maria que amava Joaquim que amava
2 Lili que no amava ningum . Joo foi para os Estados Unidos , Teresa para o
3 convento , Raimundo morreu de desastre , Maria ficou para tia , Joaquim suicidou - se
4 e Lili casou com J . Pinto Fernandes que no tinha entrado na histria .

3. XHTML:

1 <h : graphicImage value = " / imagens / k19 - treinamentos . png " / >

HTML gerado:

1 < img src = " / K19 - Componentes - Visuais / imagens / k19 - treinamentos . png " / >

Resultado:

Exerccios de Fixao

www.facebook.com/k19treinamentos 117
C OMPONENTES V ISUAIS 118

12 No arquivo conversor-monetario.xhtml do projeto K19-Componentes-Visuais, use a tag <h:out-


putFormat> para exibir o resultado do conversor monetrio.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : form >
13 <h : commandButton value = " Converter " action = " #{ conversorMonetarioBean . converte } " / >
14
15 <h : inputText value = " #{ conversorMonetarioBean . valor } " / >
16
17 <h : outputLabel value = " de " for = " de " / >
18
19 <h : selectOneMenu value = " #{ conversorMonetarioBean . de } " id = " de " >
20 <f : selectItems
21 value = " #{ conversorMonetarioBean . taxas . keySet () } "
22 var = " moeda "
23 itemValue = " #{ moeda } "
24 itemLabel = " #{ moeda } " / >
25 </ h : selectOneMenu >
26
27 <h : outputLabel value = " para " for = " para " / >
28
29 <h : selectOneMenu value = " #{ conversorMonetarioBean . para } " id = " para " >
30 <f : selectItems
31 value = " #{ conversorMonetarioBean . taxas . keySet () } "
32 var = " moeda "
33 itemValue = " #{ moeda } "
34 itemLabel = " #{ moeda } " / >
35 </ h : selectOneMenu >
36 </ h : form >
37
38 <h : outputFormat value = " {0} em {1} equivale a {2} em {3} "
39 rendered = " #{ conversorMonetarioBean . resultado != null } " >
40 <f : param value = " #{ conversorMonetarioBean . valor } " / >
41 <f : param value = " #{ conversorMonetarioBean . de } " / >
42 <f : param value = " #{ conversorMonetarioBean . resultado } " / >
43 <f : param value = " #{ conversorMonetarioBean . para } " / >
44 </ h : outputFormat >
45
46 </ h : body >
47 </ html >

Cdigo XHTML 6.44: conversor-monetario.xhtml

13 Acesse novamente a aplicao em


http://localhost:8080/K19-Componentes-Visuais/conversor-monetario.xhtml

Componentes de Organizao

O JSF define dois componentes que nos ajudam a organizar visualmente os elementos de uma
pgina JSF.

<h:panelGrid>

118 www.k19.com.br
119 C OMPONENTES V ISUAIS

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 <h : panelGrid columns = " 2 " >


2 <h : outputLabel value = " Nome do curso : " for = " nome " / >
3 <h : inputText value = " #{ cursosBean . curso . nome } " id = " nome " / >
4
5 <h : outputLabel value = " Descrio : " for = " descricao " / >
6 <h : inputTextarea value = " #{ cursosBean . curso . descricao } " id = " descricao " / >
7
8 <h : outputLabel value = " Carga horria : " for = " carga - horaria " / >
9 <h : inputText value = " #{ cursosBean . curso . cargaHoraria } " id = " carga - horaria " / >
10
11 <h : commandButton action = " #{ cursosBean . cadastraCurso } " value = " Cadastrar " / >
12 </ h : panelGrid >

Cdigo XHTML 6.45: Organizao de um formulrio com o <h:panelGrid>

Os componentes so inseridos na grade de acordo com a ordem em que esto apresentados no


cdigo. O primeiro elemento inserido na primeira coluna da primeira linha. O segundo elemento
inserido na segunda coluna da primeira linha. Uma vez que uma linha foi completamente preen-
chida, o prximo componente inserido na primeira coluna da prxima linha, e o processo se repete
at o ltimo componente.

Suponha que seja necessrio inserir mais de um componente em uma mesma clula de um
<h:panelGrid>. No exemplo acima, podemos adicionar um cone de um relgio ao lado do rtulo
Carga horria:. No entanto, queremos que a imagem e o rtulo sejam colocados na mesma clula.
Para isso, podemos agrup-los usando um <h:panelGroup>.

1 <h : panelGroup >


2 <h : outputLabel value = " Carga horria : " for = " carga - horaria " / >
3 <h : graphicImage library = " imagens " name = " relogio . png " / >
4 </ h : panelGroup >

Cdigo XHTML 6.46: Agrupando componentes com o <h:panelGroup>

Exemplos

1. XHTML:

1 <h : panelGrid columns = " 2 " >


2 <h : outputLabel value = " Nome do curso : " for = " nome " / >
3 <h : inputText value = " #{ cursosBean . curso . nome } " id = " nome " / >
4
5 <h : outputLabel value = " Descrio : " for = " descricao " / >
6 <h : inputTextarea value = " #{ cursosBean . curso . descricao } " id = " descricao " / >
7
8 <h : panelGroup >
9 <h : outputLabel value = " Carga horria : " for = " carga - horaria " / >
10 <h : graphicImage library = " imagens " name = " relogio . png " / >
11 </ h : panelGroup >
12 <h : inputText value = " #{ cursosBean . curso . cargaHoraria } " id = " carga - horaria " / >
13

www.facebook.com/k19treinamentos 119
C OMPONENTES V ISUAIS 120

14 <h : commandButton action = " #{ cursosBean . cadastraCurso } " value = " Cadastrar " / >
15 </ h : panelGrid >

HTML gerado:

1 < table >


2 < tbody >
3 < tr >
4 < td > < label for = " nome " > Nome do curso : </ label > </ td >
5 < td > < input id = " nome " type = " text " name = " nome " / > </ td >
6 </ tr >
7 < tr >
8 < td > < label for = " descricao " > Descrio : </ label > </ td >
9 < td > < textarea id = " descricao " name = " descricao " > </ textarea > </ td >
10 </ tr >
11 < tr >
12 < td >
13 < label for = " carga - horaria " > Carga horria : </ label >
14 < img src = " / K19 - Componentes - Visuais / javax . faces . resource / relogio . png . xhtml ? ln = -
imagens " / >
15 </ td >
16 < td > < input id = " carga - horaria " type = " text " name = " carga - horaria " / > </ td >
17 </ tr >
18 < tr >
19 < td > < input type = " submit " name = " j_idt98 " value = " Cadastrar " / > </ td >
20 </ tr >
21 </ tbody >
22 </ table >

Resultado:

Nome do curso:

Descrio:

Carga horria:

Cadastrar

Tabelas

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 compo-
nente 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 cabea-


lhos e rodaps tabela e a cada coluna usando o componente <f:facet>.

Veja um exemplo a seguir.

1 <h : dataTable value = " #{ cursosBean . cursos } " var = " curso " >
2
3 <f : facet name = " header " > Lista de cursos </ f : facet >
4

120 www.k19.com.br
121 C OMPONENTES V ISUAIS

5 <h : column >


6 <f : facet name = " header " > Sigla </ f : facet >
7 #{ curso . sigla }
8 </ h : column >
9
10 <h : column >
11 <f : facet name = " header " > Nome </ f : facet >
12 #{ curso . nome }
13 </ h : column >
14
15 <h : column >
16 <f : facet name = " header " > Descrio </ f : facet >
17 #{ curso . descricao }
18 </ h : column >
19
20 <h : column >
21 <f : facet name = " header " > Adicionar turma </ f : facet >
22 <h : commandLink
23 value = " Adicionar turma "
24 action = " #{ cursosBean . adicionarTurma ( curso ) } " / >
25 </ h : column >
26 </ 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 < table >


2 < thead >
3 < tr >
4 < th colspan = " 4 " scope = " colgroup " > Lista de cursos </ th >
5 </ tr >
6 < tr >
7 < th scope = " col " > Sigla </ th >
8 < th scope = " col " > Nome </ th >
9 < th scope = " col " > Descrio </ th >
10 < th scope = " col " > Adicionar turma </ th >
11 </ tr >
12 </ thead >
13 < tbody >
14 < tr >
15 < td > K11 </ td >
16 < td > Orientao a Objetos em Java </ td >
17 < td >
18 Com este curso voc vai obter uma base slida de
19 conhecimentos de Java e de Orientao a Objetos
20 </ td >
21 < td >
22 < input
23 type = " submit " name = " j_idt100 : j_idt101 :0: j_idt114 "
24 value = " Adicionar turma " / >
25 </ td >
26 </ tr >
27 < tr >
28 < td > K12 </ td >
29 < td > Desenvolvimento Web com JSF2 e JPA2 </ td >
30 < td >
31 Depois deste curso , voc estar apto a desenvolver
32 aplicaes Web com os padres da plataforma Java

www.facebook.com/k19treinamentos 121
C OMPONENTES V ISUAIS 122

33 </ td >
34 < td >
35 < input
36 type = " submit " name = " j_idt100 : j_idt101 :1: j_idt114 "
37 value = " Adicionar turma " / >
38 </ td >
39 </ tr >
40 < tr >
41 < td > K21 </ td >
42 < td > Persistncia com JPA2 e Hibernate </ td >
43 < td >
44 Neste curso de Java Avanado , abordamos de maneira profunda
45 os recursos de persistncia do JPA2 e do Hibernate
46 </ td >
47 < td >
48 < input
49 type = " submit " name = " j_idt100 : j_idt101 :2: j_idt114 "
50 value = " Adicionar turma " / >
51 </ td >
52 </ tr >
53 </ tbody >
54 </ table >

Cdigo HTML 6.24: Cdigo HTML gerado pelo JSF

A figura abaixo mostra como essa tabela apresentada no navegador.

Lista de cursos

Adicionar
Sigla Nome Descrio
Turma
Com este curso voc vai obter uma base
Orientao a Objetos em slida de conhecimentos de Java e de
K11 Adiciona turma
Java Orientao a Objetos.

Depois deste curso, voc estar apto a


Desenvolvimento Web
K12 desenvolver aplicaes Web com os padres Adiciona turma
com JSF2 e JPA2
da plataforma Java

Neste curso de Java Avanado, abordamos de


Persistncia com JPA2 e
K21 maneira profunda os recursos de persistncia Adiciona turma
Hibernate
do JPA2 e do Hibernate

Figura 6.1: Representao do HTML no navegador

Exerccios de Fixao

14 No projeto K19-Componentes-Visuais, crie uma pgina que contenha um formulrio para adi-
cionar cursos e que exiba os cursos j adicionados. Primeiramente, crie uma classe chamada Curso
em um pacote chamado br.com.k19.modelo 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.

1 package br . com . k19 . modelo ;


2
3 public class Curso {

122 www.k19.com.br
123 C OMPONENTES V ISUAIS

4 private String nome ;


5 private String sigla ;
6
7 // GETTERS E SETTERS
8 }

Cdigo Java 6.9: Curso.java

15 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.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Curso ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . bean . SessionScoped ;
8
9 @ManagedBean
10 @SessionScoped
11 public class CursosBean {
12 private List < Curso > cursos = new ArrayList < Curso >() ;
13
14 // GETTER E SETTER
15 }

Cdigo Java 6.10: CursosBean.java

16 Na classe CursosBean, adicione um atributo do tipo Curso para armazenar os dados de um


curso. Alm disso, crie um mtodo para adicionar o curso na lista de cursos.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Curso ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . bean . SessionScoped ;
8
9 @ManagedBean
10 @SessionScoped
11 public class CursosBean {
12 private List < Curso > cursos = new ArrayList < Curso >() ;
13 private Curso curso = new Curso () ;
14
15 public void adicionaCurso () {
16 this . cursos . add ( this . curso ) ;
17 this . curso = new Curso () ;
18 }
19
20 // GETTERS E SETTERS
21 }

Cdigo Java 6.11: CursosBean.java

17 Crie um arquivo XHTML chamado cursos.xhtml e implemente um formulrio para adicionar


cursos lista de cursos do managed bean CursosBean. Use a tag <h:panelGrid> para organizar o

www.facebook.com/k19treinamentos 123
C OMPONENTES V ISUAIS 124

formulrio.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 <h : form >
12 <h : panelGrid columns = " 2 " >
13 <h : outputLabel value = " Nome : " for = " campo - nome " / >
14 <h : inputText value = " #{ cursosBean . curso . nome } " id = " campo - nome " / >
15
16 <h : outputLabel value = " Sigla : " for = " campo - sigla " / >
17 <h : inputText value = " #{ cursosBean . curso . sigla } " id = " campo - sigla " / >
18
19 <h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } " / >
20 </ h : panelGrid >
21 </ h : form >
22 </ h : body >
23 </ html >

Cdigo XHTML 6.49: cursos.xhtml

18 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.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : form >
13 <h : panelGrid columns = " 2 " >
14 <h : outputLabel value = " Sigla : " for = " campo - sigla " / >
15 <h : inputText value = " #{ cursosBean . curso . sigla } " id = " campo - sigla " / >
16
17 <h : outputLabel value = " Nome : " for = " campo - nome " / >
18 <h : inputText value = " #{ cursosBean . curso . nome } " id = " campo - nome " / >
19
20 <h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } " / >
21 </ h : panelGrid >
22 </ h : form >
23
24 <h : dataTable value = " #{ cursosBean . cursos } " var = " curso "
25 rendered = " #{ not empty cursosBean . cursos } " >
26
27 <f : facet name = " header " > Lista de Cursos </ f : facet >
28
29 <h : column >
30 <f : facet name = " header " > Sigla </ f : facet >
31 #{ curso . sigla }
32 </ h : column >
33
34 <h : column >

124 www.k19.com.br
125 C OMPONENTES V ISUAIS

35 <f : facet name = " header " > Nome </ f : facet >
36 #{ curso . nome }
37 </ h : column >
38 </ h : dataTable >
39 </ h : body >
40 </ html >

Cdigo XHTML 6.50: cursos.xhtml

Acesse a aplicao no endereo:


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 projeto K19-Componentes-Visuais, crie uma classe
chamada Produto em um pacote chamado chamado br.com.k19.modelo. 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 em um pacote chamado
br.com.k19.controle para guardar uma lista de produtos. Implemente a listagem de produtos em
um arquivo XHTML chamado lista-de-produtos.xhtml.

3 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.

Mensagens

Durante o processamento de uma requisio, podemos adicionar mensagens que podem ser exi-
bidas na pgina de resposta. Uma mensagem pode ser adicionada, por exemplo, da seguinte forma:

1 FacesMessage mensagem = new FacesMessage ( " Turma adicionada " ) ;


2 FacesContext . getCurrentInstance () . addMessage ( null , mensagem ) ;

Cdigo Java 6.16: Adicionando uma mensagem

O primeiro parmetro do mtodo addMessage() define qual componente ser associado men-
sagem 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 <h : messages globalOnly = " true " / >

Cdigo XHTML 6.53: Exibindo as mensagens globais

www.facebook.com/k19treinamentos 125
C OMPONENTES V ISUAIS 126

As mensagens so comumente utilizadas para indicar erros de converso e validao. Veremos


mais detalhes sobre isso no Captulo 10.

Adicionando JavaScript e CSS

Podemos adicionar recursos como scripts e arquivos de estilos (CSS) usando diretamente as tags
<script> e <link> do HTML. Contudo, o JSF define outra maneira de inserir esses recursos nas
pginas da aplicao. Tais recursos podem ser inseridos com as tags <h:outputScript> e <h:out-
putStylesheet>. A utilizao dessas tags facilita a criao de componentes visuais personalizados
ou o gerenciamento de recursos que dependem de regionalidade.

1 <h : outputScript name = " k19 . js " library = " javascript " target = " head " / >
2 <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:re-
move>. 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 <h : outputText value = " Nome : #{ testeBean . nome } " / >


2 < ui : remove >
3 <h : outputText value = " Sobrenome : #{ testeBean . sobrenome } " / >
4 </ ui : remove >

Cdigo XHTML 6.55: Excluindo parte do cdigo de uma pgina JSF

O trecho de cdigo HTML correspondente, gerado pelo JSF, o seguinte:

1 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 <h : outputText value = " Nome : #{ testeBean . nome } " / >


2 <! - -
3 <h : outputText value =" Sobrenome : #{ testeBean . sobrenome }" / >
4 -->

Cdigo XHTML 6.56: Uso de delimitadores do XML para comentar cdigo

o JSF produzir o seguinte cdigo HTML:

126 www.k19.com.br
127 C OMPONENTES V ISUAIS

1 Nome : Jonas
2 <! - -
3 <h : outputText value =" Sobrenome : Hirata " / >
4 -->

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.

<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 <h : outputText value = " Alguns cursos da K19 : " / >


2 < ul >
3 < ui : repeat value = " #{ testeBean . cursos } " var = " curso " >
4 < li >
5 <h : outputText value = " #{ curso . sigla }: #{ curso . nome } " / >
6 </ li >
7 </ ui : repeat >
8 </ ul >

Cdigo XHTML 6.57: Iterando sobre uma lista de cursos

A partir desse cdigo, o JSF gera o seguinte cdigo HTML:

1 Alguns cursos da K19 :


2 < ul >
3 < li > K11 : Orientao a Objetos em Java </ li >
4 < li > K12 : Desenvolvimento Web com JSF2 e JPA2 </ li >
5 < li > K21 : Persistncia com JPA2 e Hibernate </ li >
6 < li > K51 : Design Patterns em Java </ li >
7 </ ul >

Cdigo HTML 6.27: Cdigo HTML gerado pelo JSF

Exerccios de Fixao

19 No projeto K19-Componentes-Visuais, crie um arquivo CSS para formatar a pgina que lista
os cursos. Na raiz da aplicao crie um diretrio chamado resources contendo um outro diretrio
chamado css. Dentro do diretrio css crie um arquivo CSS chamado k19.css com o contedo abaixo.

No Eclipse. . .

A raiz da alicao o diretrio WebContent.

1 body {
2 font - family : arial , helvetica , sans - serif ;

www.facebook.com/k19treinamentos 127
C OMPONENTES V ISUAIS 128

3 font - size : 14 px ;
4 }
5
6 h1 {
7 color : #006699;
8 font - size : 18 px ;
9 }
10
11 ul {
12 list - style - type : square ;
13 }
14
15 input {
16 background - color : # E6E6FA ;
17 border : solid 1 px #000000;
18 }

Cdigo CSS 6.1: k19.css

20 Use a tag <h:outputStylesheet> para incluir o arquivo de estilos na pgina definida por cur-
sos.xhtml. Use a tag <ui:repeat> para exibir os cursos.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12 <h : body >
13
14 <h : outputStylesheet name = " k19 . css " library = " css " / >
15
16 <h : form >
17 <h : panelGrid columns = " 2 " >
18 <h : outputLabel value = " Sigla : " for = " campo - sigla " / >
19 <h : inputText value = " #{ cursosBean . curso . sigla } " id = " campo - sigla " / >
20
21 <h : outputLabel value = " Nome : " for = " campo - nome " / >
22 <h : inputText value = " #{ cursosBean . curso . nome } " id = " campo - nome " / >
23
24 <h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } " / >
25 </ h : panelGrid >
26 </ h : form >
27
28 < h1 > Alguns cursos da K19 : </ h1 >
29 < ul >
30 < ui : repeat value = " #{ cursosBean . cursos } " var = " curso " >
31 < li >
32 <h : outputText value = " #{ curso . sigla }: #{ curso . nome } " / >
33 </ li >
34 </ ui : repeat >
35 </ ul >
36 </ h : body >
37 </ html >

Cdigo XHTML 6.58: cursos.xhtml

21 Acesse novamente a aplicao em


http://localhost:8080/K19-Componentes-Visuais/cursos.xhtml e observe o resultado das al-

128 www.k19.com.br
129 C OMPONENTES V ISUAIS

teraes realizas.

Exerccios Complementares

4 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.

www.facebook.com/k19treinamentos 129
C OMPONENTES V ISUAIS 130

130 www.k19.com.br
CAPTULO
T EMPLATES E M ODULARIZAO
7

Certamente, voc j ouviu algum falar da importncia da reutilizao de cdigo no desenvol-


vimento 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 princi-
pal 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: ca-
bealho, 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.facebook.com/k19treinamentos 131
T EMPLATES E M ODULARIZAO 132

Pgina 2

Lorem ipsum dolor sit Lorem ipsum dolor sit


amet, consectetur amet, consectetur
adipiscing elit. adipiscing elit.
Aenean rutrum Aenean rutrum
accumsan lorem, non accumsan lorem, non
euismod ligula euismod ligula
aliquet in. Proin vitae aliquet in. Proin vitae
ultricies sapien. ultricies sapien.
Donec volutpat lacus Donec volutpat lacus
eleifend sapien eleifend sapien
vestibulum eu vestibulum eu
dapibus mi pharetra dapibus mi pharetra

Pgina 2

Pgina 1 Pgina 3

Lorem ipsum dolor sit Lorem ipsum dolor sit Lorem ipsum dolor sit Lorem ipsum dolor sit
amet, consectetur amet, consectetur amet, consectetur amet, consectetur
adipiscing elit. adipiscing elit. adipiscing elit. adipiscing elit.
Aenean rutrum Aenean rutrum Aenean rutrum Aenean rutrum
accumsan lorem, non accumsan lorem, non accumsan lorem, non accumsan lorem, non
euismod ligula euismod ligula euismod ligula euismod ligula
aliquet in. Proin vitae aliquet in. Proin vitae aliquet in. Proin vitae aliquet in. Proin vitae
ultricies sapien. ultricies sapien. ultricies sapien. ultricies sapien.
Donec volutpat lacus Donec volutpat lacus Donec volutpat lacus Donec volutpat lacus
eleifend sapien eleifend sapien eleifend sapien eleifend sapien
vestibulum eu vestibulum eu vestibulum eu vestibulum eu
dapibus mi pharetra dapibus mi pharetra dapibus mi pharetra dapibus mi pharetra

Pgina 1 Template Pgina 3

Pgina 4

Lorem ipsum dolor sit Lorem ipsum dolor sit


amet, consectetur amet, consectetur
adipiscing elit. adipiscing elit.
Aenean rutrum Aenean rutrum
accumsan lorem, non accumsan lorem, non
euismod ligula euismod ligula
aliquet in. Proin vitae aliquet in. Proin vitae
ultricies sapien. ultricies sapien.
Donec volutpat lacus Donec volutpat lacus
eleifend sapien eleifend sapien
vestibulum eu vestibulum eu
dapibus mi pharetra 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 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 < div id = " header " >
14 < img src = " k19 - logo . png " / >
15 < hr / >
16 </ div >
17
18 < ui : insert name = " corpo - da - pagina " > Espao para o contedo da tela </ ui : insert >

132 www.k19.com.br
133 T EMPLATES E M ODULARIZAO

19
20 < div id = " footer " style = " text - align : center " >
21 < hr / >
22 & copy ; 2010 K19 . Todos os direitos reservados .
23 </ div >
24 </ h : body >
25 </ html >

Cdigo XHTML 7.1: template.xhtml

O componente <ui:insert> utilizado para posicionar os trechos dinmicos. O atributo name


desse componente utilizado para nomear os trechos dinmicos.

Normalmente, a declarao <!DOCTYPE> no varia de tela para tela dentro de uma aplicao.
Dessa forma, podemos adicion-la de forma esttica no template, conforme o exemplo acima.

Vimos no Captulo 6 que fundamental a utilizao dos componentes <h:head> e <h:body>.


No exemplo acima, esses componentes foram definidos estaticamente no template. Assim, todas as
telas que utilizam esse template no correm mais o risco de ficarem sem esses componentes.

Utilizando templates

Para criar uma tela que usa um determinado template, devemos criar um arquivo XHTML e adi-
cionar a tag <ui:composition> a esse arquivo. O arquivo do template desejado deve ser indicado
atravs do atributo template da tag <ui:composition>.

1 < ui : composition template = " / template . xhtml "


2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
4 </ ui : composition >

Cdigo XHTML 7.2: tela.xhtml

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 se-


guinte forma:

1 < ui : composition template = " / template . xhtml "


2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 < ui : define name = " corpo - da - pagina " >
7 < h1 > Lista de treinamentos </ h1 >
8 < h2 > K11 - Orientao a Objetos em Java </ h2 >
9 < h2 > K12 - Desenvolvimento Web com JSF2 e JPA2 </ h2 >
10 </ ui : define >
11 </ ui : composition >

Cdigo XHTML 7.3: tela.xhtml

www.facebook.com/k19treinamentos 133
T EMPLATES E M ODULARIZAO 134

Se o contedo de um trecho dinmico no for definido, o JSF utilizar o contedo existente no


corpo da tag <ui:insert> definido no template. No exemplo acima, caso o contedo do trecho di-
nmico corpo-da-pagina no fosse definido no arquivo tela.xhtml, o JSF utilizaria o texto Espao
para o contedo da tela, que foi definido no arquivo template.xhtml como contedo padro para
esse trecho.

Pare para pensar...


Em geral, os templates no definem uma tela concreta da aplicao. Eles funcionam
como uma base para a criao de telas concretas. Dessa forma, no seria interessante
que os navegadores acessassem diretamente a tela correspondente a um template, pois, prova-
velmente, essa tela estaria incompleta. Para evitar esse comportamento indesejado, podemos
colocar todos os templates dentro do diretrio /WEB-INF.

Exerccios de Fixao

1 Crie um projeto chamado K19-Templates-e-Modularizacao seguindo os passos vistos no exer-


ccio do Captulo 5.

2 Adicione um diretrio chamado templates na pasta WEB-INF. Crie um template chamado tem-
plate.xhtml na pasta WEB-INF/templates.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 < div id = " header " > < img src = " imagens / k19 - logo . png " / >
13 < hr / >
14 </ div >
15
16 < ui : insert name = " conteudo " >
17 Espao para o contedo da tela
18 </ ui : insert >
19
20 < div id = " footer " style = " text - align : center " >
21 < hr / >
22 & copy ; 2012 K19 . Todos os direitos reservados . </ div >
23 </ h : body >
24 </ html >

Cdigo XHTML 7.4: template.xhtml

3 Crie uma pasta chamada imagens no projeto K19-Templates-e-Modularizacao.

134 www.k19.com.br
135 T EMPLATES E M ODULARIZAO

4 Copie o arquivo k19-logo.png da pasta K19-Arquivos/imagens para o diretrio imagens.

Importante
Voc tambm pode obter o arquivo k19-logo.png atravs do site da K19: www.k19.
com.br/arquivos.

5 Monte uma pgina que use o template criado anteriormente. O nome do arquivo deve ser
formulario.xhtml.

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 < ui : define name = " conteudo " >
7 <h : form >
8 <h : outputLabel value = " Nome : " for = " campo - nome " / >
9 <h : inputText id = " campo - nome " / >
10 <h : commandButton value = " Enviar " / >
11 </ h : form >
12 </ ui : define >
13 </ ui : composition >

Cdigo XHTML 7.5: formulario.xhtml

6 Remova o projeto K19-Componentes-Visuais do Glassfish e do Wildfly. Implante o projeto


K19-Templates-e-Modularizacao no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o
Glassfish e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Templates-e-Modularizacao/formulario.xhtml

7 Implante o projeto K19-Templates-e-Modularizacao no Wildfly. Certifique-se que o Glassfish


esteja parado. Inicie o Wildfly e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Templates-e-Modularizacao/formulario.xhtml

Modularizao

Os trechos estticos ou dinmicos definidos em um template possuem posio fixa. Em deter-


minadas 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.

www.facebook.com/k19treinamentos 135
T EMPLATES E M ODULARIZAO 136

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 Lorem ipsum

Lorem ipsum dolor sit Suspendisse tristique Suspendisse tristique Lorem ipsum dolor sit Suspendisse tristique Lorem ipsum dolor sit
amet, consectetur dolor sit amet felis dolor sit amet felis amet, consectetur dolor sit amet felis amet, consectetur
adipiscing elit. vehicula rutrum. vehicula rutrum. adipiscing elit. vehicula rutrum. adipiscing elit.
Aenean rutrum Phasellus fringilla Phasellus fringilla Aenean rutrum Aenean rutrum
accumsan lorem, non mauris eu turpis mauris eu turpis accumsan lorem, non accumsan lorem, non
euismod ligula sodales congue. sodales congue. euismod ligula euismod ligula
aliquet in. Proin vitae aliquet in. Proin vitae aliquet in. Proin vitae
Lorem ipsum dolor sit
ultricies sapien. ultricies sapien. ultricies sapien.
amet, consectetur
Donec volutpat lacus Donec volutpat lacus Donec volutpat lacus
adipiscing elit.
eleifend sapien Lorem ipsum dolor sit Lorem ipsum dolor sit eleifend sapien eleifend sapien
vestibulum eu amet, consectetur amet, consectetur vestibulum eu vestibulum eu
dapibus mi pharetra adipiscing elit. adipiscing elit. dapibus mi pharetra dapibus mi pharetra
Aenean rutrum Aenean rutrum
Suspendisse tristique
accumsan lorem, non accumsan lorem, non
dolor sit amet felis
euismod ligula euismod ligula
vehicula rutrum.
aliquet in. Proin vitae aliquet in. Proin vitae

Pgina 1 Pgina 2 Pgina 3


Figura 7.2: Mdulo reaproveitado em diversas pginas

Nessa situao, a melhor abordagem definir o formulrio de contato, separadamente, em um


arquivo XHTML. O cdigo XHTML que define o formulrio de contato deve ser inserido no corpo da
tag <ui:composition>. Observe o cdigo abaixo.

1 < ui : composition
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 <h : form >
7 <h : panelGrid >
8 <h : outputLabel value = " Mensagem : " for = " mensagem " / >
9 <h : inputTextarea id = " mensagem " value = " #{ mensagensBean . mensagem } " / >
10 <h : commandButton value = " Enviar " action = " #{ mensagensBean . envia } " / >
11 </ h : panelGrid >
12 </ h : form >
13 </ 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-
clude> para adicion-lo onde for necessrio.

1 ...
2 < ui : include src = " / formulario - de - contato . xhtml " / >
3 ...

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

136 www.k19.com.br
137 T EMPLATES E M ODULARIZAO

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 < ui : composition
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 <h : dataTable value = " #{ livros } " var = " livro " >
7 ...
8 </ h : dataTable >
9 </ ui : composition >

Cdigo XHTML 7.8: lista-livros.xhtml

Observe, no cdigo acima, que o componente <h:dataTable> foi vinculado a uma varivel cha-
mada 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, de-
vemos utilizar o componente <ui:param>.

1 ...
2 < ui : include src = " / lista - livros . xhtml " >
3 < ui : param name = " livros " value = " #{ livrosBean . listaDosLivrosMaisVendidos } " / >
4 </ ui : include >
5 ...

Cdigo XHTML 7.9: Inserindo a lista dos livros mais vendidos

Em outra pgina da aplicao da livraria, podemos adicionar o arquivo lista-livros.xhtml


passando como parmetro a lista dos livros mais caros.

1 ...
2 < ui : include src = " / lista - livros . xhtml " >
3 < ui : param name = " livros " value = " #{ livrosBean . listaDosLivrosMaisCaros } " / >
4 </ ui : include >
5 ...

Cdigo XHTML 7.10: Inserindo a lista dos livros mais caros

Exerccios de Fixao

8 Vamos implementar uma listagem de instrutores no projeto K19-Templates-e-Modulariza-


cao. O primeiro passo criar uma classe para modelar os instrutores. Crie um pacote chamado
br.com.k19.modelo no projeto K19-Templates-e-Modularizacao e adicione nele uma classe cha-
mada Instrutor com seguinte cdigo.

1 package br . com . k19 . modelo ;


2
3 public class Instrutor {
4 private String nome ;

www.facebook.com/k19treinamentos 137
T EMPLATES E M ODULARIZAO 138

5 private String dataDeNascimento ;


6
7 // GETTERS E SETTERS
8 }

Cdigo Java 7.1: Instrutor.java

9 Faa um managed bean que fornea uma lista de instrutores para uma tela de listagem de instru-
tores. Crie um pacote chamado br.com.k19.controle no projeto K19-Templates-e-Modularizacao e
adicione nele uma classe chamada InstrutorBean com seguinte cdigo:

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Instrutor ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7
8 @ManagedBean
9 public class InstrutorBean {
10
11 private List < Instrutor > instrutores = new ArrayList < Instrutor >() ;
12
13 public InstrutorBean () {
14 Instrutor rafael = new Instrutor () ;
15 rafael . setNome ( " Rafael Cosentino " ) ;
16 rafael . setDataDeNascimento ( " 30/10/1984 " ) ;
17
18 Instrutor marcelo = new Instrutor () ;
19 marcelo . setNome ( " Marcelo Martins " ) ;
20 marcelo . setDataDeNascimento ( " 02/04/1985 " ) ;
21
22 this . instrutores . add ( rafael ) ;
23 this . instrutores . add ( marcelo ) ;
24 }
25
26 public List < Instrutor > getInstrutores () {
27 return instrutores ;
28 }
29
30 public void setInstrutores ( List < Instrutor > instrutores ) {
31 this . instrutores = instrutores ;
32 }
33 }

Cdigo Java 7.2: InstrutorBean.java

10 Crie um diretrio chamado partials na pasta WEB-INF. Adicione nesse diretrio um arquivo
chamado instrutor-info.xhtml com o seguinte contedo.

1 < ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
2 xmlns : h = " http :// java . sun . com / jsf / html "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
4
5 < li >
6 <h : outputText value = " Nome : #{ instrutor . nome } " / >
7 < br / >
8 <h : outputText value = " Data Nascimento : #{ instrutor . dataDeNascimento } " / >
9 </ li >
10
11 </ ui : composition >

Cdigo XHTML 7.11: instrutor-info.xhtml

138 www.k19.com.br
139 T EMPLATES E M ODULARIZAO

11 Crie uma pgina no projeto K19-Templates-e-Modularizacao com o nome listagem-de-instru-


tores.xhtml e com o seguinte cdigo.

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : f = " http :// java . sun . com / jsf / core "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
6
7 < ui : define name = " conteudo " >
8 < ul >
9 < ui : repeat var = " instrutor " value = " #{ instrutorBean . instrutores } " >
10 < ui : include src = " / WEB - INF / partials / instrutor - info . xhtml " >
11 < ui : param name = " instrutor " value = " #{ instrutor } " / >
12 </ ui : include >
13 </ ui : repeat >
14 </ ul >
15 </ ui : define >
16 </ ui : composition >

Cdigo XHTML 7.12: listagem-de-instrutores.xhtml

Veja o resultado acessando a url:

http://localhost:8080/K19-Templates-e-Modularizacao/listagem-de-instrutores.xhtml

Exerccios Complementares

1 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.

www.facebook.com/k19treinamentos 139
T EMPLATES E M ODULARIZAO 140

140 www.k19.com.br
CAPTULO
N AVEGAO
8
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, Lorem ipsum dolor sit amet,
consectetur adipiscing elit. consectetur adipiscing elit.
Aenean rutrum accumsan Aenean rutrum accumsan
lorem, non euismod ligula lorem, non euismod ligula
aliquet in. aliquet in.

LEIA MAIS COMPRAR


www.k19.com.br/loja

Donec vel feugiat ligula. Mauris


bibendum suscipit purus, eu aliquam
dui venenatis sit amet. Praesent
tortor nisl, egestas ut laoreet non,
hendrerit at sapien.

Figura 8.1: Navegao entre pginas

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 redirecio-
nado 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.

Quando utilizamos os componentes <h:commandButton> e <h:commandLink> para criar botes

www.facebook.com/k19treinamentos 141
N AVEGAO 142

e links, devemos definir os outcomes atravs do atributo action. Por outro lado, quando utilizamos
os componentes <h:button> e <h:link>, devemos definir os outcomes atravs do atributo outcome.

Veja como seria o cdigo da pagina1.xhtml e pagina2.xhtml.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 < h1 > K19 Pgina 1 </ h1 >
12 <h : form >
13 <h : commandButton value = " Pgina 2 " action = " pagina2 " / >
14 </ h : form >
15 </ h : body >
16 </ html >

Cdigo XHTML 8.1: pagina1.xhtml

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 < h1 > K19 Pgina 2 </ h1 >
12 <h : link outcome = " pagina1 " >
13 <h : outputText value = " Pgina 1 " / >
14 </ h : link >
15 </ h : body >
16 </ html >

Cdigo XHTML 8.2: pagina2.xhtml

Alm do nome, os outcomes tambm podem determinar o caminho do arquivo de resposta. Se


o outcome comear com caractere /, esse caminho ser definido a partir do diretrio raiz da apli-
cao web . Caso contrrio, ser definido a partir do diretrio atual.

Considere, por exemplo, um arquivo chamado pagina1.xhtml no diretrio /diretorio1 e um


arquivo chamado pagina2.xhtml no diretrio /diretorio1/diretorio2. No arquivo pagina1.xhtml,
podemos adicionar um boto para navegar para o arquivo pagina2.xhtml da seguintes formas:

1 ...
2 <h : commandButton value = " Pgina 2 " action = " / diretorio1 / diretorio2 / pagina2 " / >
3 ...

Cdigo XHTML 8.3: pagina1.xhtml

1 ...
2 <h : commandButton value = " Pgina 2 " action = " diretorio2 / pagina2 " / >
3 ...

Cdigo XHTML 8.4: pagina1.xhtml

142 www.k19.com.br
143 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 independen-


temente 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 con-
figurao 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 < navigation - rule >


2 < from - view - id >/ pagina1 . xhtml </ from - view - id >
3
4 < navigation - case >
5 < from - outcome > proxima </ from - outcome >
6 <to - view - id >/ pagina2 . xhtml </ to - view - id >
7 </ navigation - case >
8 </ navigation - rule >

Cdigo XML 8.1: Registrando uma navegao explcita

Aps o registro da navegao acima, podemos adicionar um boto ou link no arquivo pagi-
na1.xhtml com o outcome proxima para navegar para o arquivo pagina2.xhtml.

1 ...
2 <h : commandButton value = " Prxima tela " action = " proxima " / >
3 ...

Cdigo XHTML 8.5: pagina1.xhtml

Importante
O JSF utiliza a seguinte lgica para determinar a pgina de resposta. Primeiro, ele veri-
fica 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 compa-
tvel 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.facebook.com/k19treinamentos 143
N AVEGAO 144

1 < navigation - rule >


2 < from - view - id >/ K19 /* </ from - view - id >
3
4 < navigation - case >
5 < from - outcome > home </ from - outcome >
6 <to - view - id >/ home . xhtml </ to - view - id >
7 </ navigation - case >
8 </ navigation - rule >

Cdigo XML 8.2: Registrando uma navegao explcita

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 < navigation - rule >
2 < from - view - id >/ login . xhtml </ from - view - id >
3
4 < navigation - case >
5 < from - outcome > sucesso </ from - outcome >
6 < if >
7 #{ usuarioBean . preferencias [ versao - da - interface ] == simples }
8 </ if >
9 <to - view - id >/ home - simples . xhtml </ to - view - id >
10 </ navigation - case >
11
12 < navigation - case >
13 < from - outcome > sucesso </ from - outcome >
14 < if >
15 #{ usuarioBean . preferencias [ versao - da - interface ] == avancada }
16 </ if >
17 <to - view - id >/ home - avancada . xhtml </ to - view - id >
18 </ navigation - case >
19 </ navigation - rule >

Cdigo XML 8.3: Registrando uma navegao explcita condicional

Exerccios de Fixao

1 Crie um projeto chamado K19-Navegacao seguindo os passos vistos no exerccio do Captulo 5.

2 No projeto K19-Navegacao, deve existir trs pginas: componentes-visuais.xhtml, templates-


e-modularizacao.xhtml e navegacao.xhtml. A partir de qualquer uma delas, deve ser possvel nave-
gar para qualquer outra. Podemos criar uma espcie de menu para navegar entre essas pginas:

1 ...

144 www.k19.com.br
145 N AVEGAO

2 <h : link value = " Componentes Visuais " outcome = " componentes - visuais " / > -
3 <h : link value = " Templates e Modularizao " outcome = " templates -e - modularizacao " / > -
4 <h : link value = " Navegao " outcome = " navegacao " / >
5 ...

Cdigo XHTML 8.6: Menu para navegar entre as pginas.

Para facilitar, podemos definir um template para criar essas trs pginas. Crie um arquivo cha-
mado template.xhtml em um diretrio chamado templates dentro de WEB-INF.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12
13 < div id = " header " style = " text - align : center " >
14 < h1 > K19 - Desenvolvimento Web com JSF2 e JPA2 </ h1 >
15 </ div >
16
17 <h : link value = " Componentes Visuais " outcome = " componentes - visuais " / > -
18 <h : link value = " Templates e Modularizao " outcome = " templates -e - modularizacao " / > -
19 <h : link value = " Navegao " outcome = " navegacao " / >
20
21 < ui : insert name = " corpo - da - pagina " > Espao para o contedo da tela </ ui : insert >
22
23 < div id = " footer " style = " text - align : center " >
24 < hr / >
25 & copy ; 2012 K19 . Todos os direitos reservados .
26 </ div >
27
28 </ h : body >
29 </ html >

Cdigo XHTML 8.7: template.xhtml

3 Agora, use o template para criar as pginas componentes-visuais.xhtml, templates-e-modula-


rizacao.xhtml e navegacao.xhtml

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 < ui : define name = " corpo - da - pagina " >
7 < h1 > Componentes Visuais </ h1 >
8
9 No JSF 2 , as telas so definidas em arquivos xhtml . Os componentes visuais que
10 constituem as telas so adicionados por meio de tags . A especificao do JSF
11 define uma grande quantidade de tags e as classifica em bibliotecas .
12 As principais bibliotecas de tags do JSF so :
13 < ul >
14 < li > Core ( http :// java . sun . com / jsf / core ) </ li >
15 < li > HTML ( http :// java . sun . com / jsf / html ) </ li >
16 < li > Facelets ( http :// java . sun . com / jsf / facelets ) </ li >
17 </ ul >
18 </ ui : define >
19 </ ui : composition >

www.facebook.com/k19treinamentos 145
N AVEGAO 146

Cdigo XHTML 8.8: componentes-visuais.xhtml

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 < ui : define name = " corpo - da - pagina " >
7 < h1 > Templates e Modularizao </ h1 >
8
9 A criao de um template simples . Basta criar um arquivo XHTML e definir o
10 posicionamento dos trechos estticos e dinmicos . O contedo dos trechos
11 estticos tambm deve ser definido da forma usual dentro do template . Por outro
12 lado , o contedo dos trechos dinmicos s ser definido nas telas . Para indicar
13 o posicionamento dos trechos dinmicos , devemos utilizar a tag ui : insert .
14 </ ui : define >
15 </ ui : composition >

Cdigo XHTML 8.9: templates-e-modularizacao.xhtml

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 < ui : define name = " corpo - da - pagina " >
7 < h1 > Navegao </ h1 >
8
9 Navegar entre as telas de uma aplicao web preciso . O mecanismo de
10 navegao do JSF bem sofisticado e permite vrios tipos de transies entre
11 telas . A ideia muito simples : no clique de um boto ou link , muda - se a tela
12 apresentada ao usurio .
13 </ ui : define >
14 </ ui : composition >

Cdigo XHTML 8.10: navegacao.xhtml

4 Remova o projeto K19-Templates-e-Modularizacao do Glassfish e do Wildfly. Implante o projeto


K19-Navegacao no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o
endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Navegacao/componentes-visuais.xhtml

5 Implante o projeto K19-Navegacao no Wildfly. Certifique-se que o Glassfish esteja parado. Inicie
o Wildfly e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Navegacao/componentes-visuais.xhtml

6 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 < navigation - rule >
3 < from - view - id > componentes - visuais . xhtml </ from - view - id >

146 www.k19.com.br
147 N AVEGAO

4
5 < navigation - case >
6 < from - outcome > proximo </ from - outcome >
7 <to - view - id > templates -e - modularizacao . xhtml </ to - view - id >
8 </ navigation - case >
9 </ navigation - rule >
10
11 < navigation - rule >
12 < from - view - id > templates -e - modularizacao . xhtml </ from - view - id >
13
14 < navigation - case >
15 < from - outcome > proximo </ from - outcome >
16 <to - view - id > navegacao . xhtml </ to - view - id >
17 </ navigation - case >
18
19 < navigation - case >
20 < from - outcome > anterior </ from - outcome >
21 <to - view - id > componentes - visuais . xhtml </ to - view - id >
22 </ navigation - case >
23 </ navigation - rule >
24
25 < navigation - rule >
26 < from - view - id > navegacao . xhtml </ from - view - id >
27
28 < navigation - case >
29 < from - outcome > anterior </ from - outcome >
30 <to - view - id > templates -e - modularizacao . xhtml </ to - view - id >
31 </ navigation - case >
32 </ navigation - rule >
33 ...

Cdigo XML 8.4: faces-config.xml

7 No arquivo /WEB-INF/templates/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).

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12
13 < div id = " header " style = " text - align : center " >
14 < h1 > K19 - Desenvolvimento Web com JSF2 e JPA2 </ h1 >
15 </ div >
16
17 <h : form >
18 <h : commandButton value = " Anterior " action = " anterior " / >
19 <h : commandButton value = " Prximo " action = " proximo " / >
20 </ h : form >
21
22 <h : link value = " Componentes Visuais " outcome = " componentes - visuais " / > -
23 <h : link value = " Templates e Modularizao " outcome = " templates -e - modularizacao " / > -
24 <h : link value = " Navegao " outcome = " navegacao " / >
25
26 < ui : insert name = " corpo - da - pagina " > Espao para o contedo da tela </ ui : insert >
27
28 < div id = " footer " style = " text - align : center " >
29 < hr / >

www.facebook.com/k19treinamentos 147
N AVEGAO 148

30 & copy ; 2010 K19 . Todos os direitos reservados .


31 </ div >
32
33 </ h : body >
34 </ html >

Cdigo XHTML 8.11: template.xhtml

8 Navegue atravs dos links e botes da url:

http://localhost:8080/K19-Navegacao/componentes-visuais.xhtml

Navegaes Esttica e Dinmica

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 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 < h1 > K19 Cara ou Coroa </ h1 >
12 <h : form >
13 <h : commandButton value = " Lanar Moeda " action = " #{ caraOuCoroaBean . lanca } " / >
14 </ h : form >
15 </ h : body >
16 </ html >

Cdigo XHTML 8.13: cara-ou-coroa.xhtml

1 @ManagedBean
2 public class CaraOuCoroaBean {
3 public String lanca () {
4 if ( Math . random () < 0.5) {
5 return " cara " ;
6 } else {
7 return " coroa " ;
8 }
9 }
10 }

Cdigo Java 8.1: CaraOuCoroaBean.java

148 www.k19.com.br
149 N AVEGAO

Toda vez que o boto Lanar Moeda for clicado, o mtodo lanca() do managed bean cara-
OuCoroaBean 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 out-
come. 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 < navigation - rule >


2 < from - view - id >/ index . xhtml </ from - view - id >
3
4 < navigation - case >
5 < from - outcome > lista </ from - outcome >
6 < from - action > #{ cursosBean . lista } </ from - action >
7 <to - view - id >/ lista - cursos . xhtml </ to - view - id >
8 </ navigation - case >
9
10 < navigation - case >
11 < from - outcome > lista </ from - outcome >
12 < from - action > #{ alunosBean . lista } </ from - action >
13 <to - view - id >/ lista - alunos . xhtml </ to - view - id >
14 </ navigation - case >
15 </ navigation - rule >

Cdigo XML 8.5: faces-config.xml

1 ...
2 <h : commandLink value = " Lista cursos " action = " #{ cursosBean . lista } " / >
3 <h : commandLink value = " Lista alunos " action = " #{ alunosBean . lista } " / >
4 ...

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

9 Implemente um managed bean que, de forma aleatria, escolha entre dois outcomes. Crie um
pacote chamado br.com.k19.controle no projeto K19-Navegacao e adicione uma classe chamada
CaraOuCoroaBean.

www.facebook.com/k19treinamentos 149
N AVEGAO 150

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4
5 @ManagedBean
6 public class CaraOuCoroaBean {
7 public String proxima () {
8 if ( Math . random () < 0.5) {
9 return " cara " ;
10 } else {
11 return " coroa " ;
12 }
13 }
14 }

Cdigo Java 8.2: CaraOuCoroaBean.java

10 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 uma pgina chamada cara-ou-
coroa.xhtml no projeto K19-Navegacao.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 < h1 > K19 Cara ou Coroa </ h1 >
12 <h : form >
13 <h : commandButton value = " Lanar Moeda " action = " #{ caraOuCoroaBean . proxima } " / >
14 </ h : form >
15 </ h : body >
16 </ html >

Cdigo XHTML 8.15: cara-ou-coroa.xhtml

11 Crie as pginas de sada.

O arquivo cara.xhtml:

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 < h1 > Deu Cara ! </ h1 >
12 <h : form >
13 <h : commandButton value = " voltar " action = " cara - ou - coroa " / >
14 </ h : form >
15 </ h : body >
16 </ html >

Cdigo XHTML 8.16: cara.xhtml

150 www.k19.com.br
151 N AVEGAO

O arquivo coroa.xhtml:

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 < h1 > Deu Coroa ! </ h1 >
12 <h : form >
13 <h : commandButton value = " voltar " action = " cara - ou - coroa " / >
14 </ h : form >
15 </ h : body >
16 </ html >

Cdigo XHTML 8.17: coroa.xhtml

12 Verifique o funcionamento acessando o endereo:

http://localhost:8080/K19-Navegacao/cara-ou-coroa.xhtml

Exerccios Complementares

1 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.

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 Repita o exerccio anterior usando navegao explcita.

www.facebook.com/k19treinamentos 151
N AVEGAO 152

152 www.k19.com.br
CAPTULO
E SCOPOS
9
Os managed beans so instanciados pelo JSF, ou seja, os desenvolvedores definem as classes e
o JSF cuida do new. Porm, podemos determinar quando os managed beans devem ser criados e
descartados. O tempo de vida de uma instncia afeta principalmente a durabilidade dos dados que
ela armazena. Por isso, precisamos escolher qual escopo queremos utilizar em cada managed bean.
Eis alguns dos escopos do JSF 2:

Request.
View.
Session.
Application.

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 package br . com . k19 ;


2
3 @ManagedBean
4 @RequestScoped
5 class TesteBean {
6 ...
7 }

Cdigo Java 9.1: TesteBean.java

Por outro lado, se o managed bean for registrado da maneira tradicional, no arquivo faces-con-
fig.xml, a escolha de um escopo obrigatria e realizada atravs da tag managed-bean-scope.

1 ...
2 < managed - bean >
3 < managed - bean - name > testeBean </ managed - bean - name >
4 < managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
5 < managed - bean - scope > request </ managed - bean - scope >
6 </ managed - bean >
7 ...

Cdigo XML 9.1: faces-config.xml

www.facebook.com/k19treinamentos 153
E SCOPOS 154

Navegador Aplicao

Cria
Requisio HTTP MB

Mata
JSF
Resposta HTTP MB

Figura 9.1: Escopo de request

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 package br . com . k19 ;


2
3 @ManagedBean
4 @ViewScoped
5 class TesteBean {
6 ...
7 }

Cdigo Java 9.2: TesteBean.java

1 ...
2 < managed - bean >
3 < managed - bean - name > testeBean </ managed - bean - name >
4 < managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
5 < managed - bean - scope > view </ managed - bean - scope >
6 </ managed - bean >
7 ...

Cdigo XML 9.2: faces-config.xml

154 www.k19.com.br
155 E SCOPOS

Navegador Aplicao

index.xhtml
Requisio HTTP MB

Cr
Resposta HTTP

ia
index.xhtml
Requisio HTTP
JSF
Resposta HTTP

produtos.xhtml
a
Requisio HTTP at
M

Resposta HTTP MB

Figura 9.2: Escopo de view

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 cha-
mado 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 neces-
srias 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 package br . com . k19 ;


2
3 @ManagedBean
4 @SessionScoped
5 class TesteBean {

www.facebook.com/k19treinamentos 155
E SCOPOS 156

6 ...
7 }

Cdigo Java 9.3: TesteBean.java

1 ...
2 < managed - bean >
3 < managed - bean - name > testeBean </ managed - bean - name >
4 < managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
5 < managed - bean - scope > session </ managed - bean - scope >
6 </ managed - bean >
7 ...

Cdigo XML 9.3: faces-config.xml

Temos que tomar um cuidado maior ao utilizar o escopo session, pois podemos acabar sobre-
carregando 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

Resposta HTTP
Cri
a

produtos.xhtml
Requisio HTTP

Resposta HTTP

usuario.xhtml
Requisio HTTP

Resposta HTTP

JSF

30 minutos
depois
a
at
M

MB

Figura 9.3: Escopo de session

156 www.k19.com.br
157 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 @Application-


Scoped ou a tag managed-bean-scope.

1 package br . com . k19 ;


2
3 @ManagedBean
4 @ApplicationScoped
5 class TesteBean {
6 ...
7 }

Cdigo Java 9.4: TesteBean.java

1 ...
2 < managed - bean >
3 < managed - bean - name > testeBean </ managed - bean - name >
4 < managed - bean - class > br . com . k19 . TesteBean </ managed - bean - class >
5 < managed - bean - scope > application </ managed - bean - scope >
6 </ managed - bean >
7 ...

Cdigo XML 9.4: faces-config.xml

Mais Sobre
Por padro, a instncia de um managed bean em escopo application criada no mo-
mento 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 exem-
plo abaixo.

1 package br . com . k19 ;


2
3 @ManagedBean ( eager = true )
4 @ApplicationScoped
5 class TesteBean {
6 ...
7 }

Cdigo Java 9.5: TesteBean.java

Exerccios de Fixao

www.facebook.com/k19treinamentos 157
E SCOPOS 158

1 Crie um projeto chamado K19-Escopos seguindo os passos vistos no exerccio do Captulo 5.

2 Vamos criar uma pgina para adicionar carros e visualiz-los. Adicione um pacote chamado
br.com.k19.modelo no projeto K19-Escopos.

3 No pacote br.com.k19.modelo, 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.

1 package br . com . k19 . modelo ;


2
3 public class Carro {
4 private String marca ;
5 private String modelo ;
6
7 // GETTERS E SETTERS
8 }

Cdigo Java 9.6: Carro.java

4 Crie um outro pacote com o nome br.com.k19.controle.

5 No pacote br.com.k19.controle, crie uma classe chamada CarroBean para armazenar uma lista
de carros.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Carro ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7
8 @ManagedBean
9 public class CarroBean {
10 private List < Carro > carros = new ArrayList < Carro >() ;
11
12 // GETTERS E SETTERS
13 }

Cdigo Java 9.7: CarroBean.java

6 Na classe CarroBean, acrescente um atributo do tipo Carro para armazenar o carro a ser adici-
onado. Implemente tambm um mtodo chamado adicionaCarro() para inserir um novo carro na
lista.

1 package br . com . k19 . controle ;


2
3 import java . util . List ;
4 import java . util . ArrayList ;
5 import javax . faces . bean . ManagedBean ;
6
7 @ManagedBean
8 public class CarroBean {
9 private List < Carro > carros = new ArrayList < Carro >() ;
10 private Carro carro = new Carro () ;

158 www.k19.com.br
159 E SCOPOS

11
12 public void adicionaCarro () {
13 this . carros . add ( this . carro ) ;
14 this . carro = new Carro () ;
15 }
16
17 // GETTERS E SETTERS
18 }

Cdigo Java 9.8: CarroBean.java

No esquea dos mtodos de acesso do atributo carro.

7 Defina o escopo do managed bean carroBean como sendo request. Para isso, use a anotao
@RequestScoped. Lembre-se esse o escopo padro.

1 ...
2 @RequestScoped
3 public class CarroBean {
4 ...
5 }

Cdigo Java 9.9: CarroBean.java

No esquea de importar a anotao @RequestScoped.

8 Crie um pgina no projeto K19-Escopos chamada carros.xhtml. Implemente um formulrio


para adicionar um novo carro.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : form >
13 <h : panelGrid columns = " 2 " >
14 <h : outputLabel value = " Marca : " for = " campo - marca " / >
15 <h : inputText value = " #{ carroBean . carro . marca } " id = " campo - marca " / >
16
17 <h : outputLabel value = " Modelo : " for = " campo - modelo " / >
18 <h : inputText value = " #{ carroBean . carro . modelo } " id = " campo - modelo " / >
19
20 <h : commandButton value = " Adicionar " action = " #{ carroBean . adicionaCarro } " / >
21 </ h : panelGrid >
22 </ h : form >
23 </ h : body >
24 </ html >

Cdigo XHTML 9.1: carros.xhtml

9 No arquivo carros.xhtml, adicione um trecho de cdigo para exibir os carros adicionados.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "

www.facebook.com/k19treinamentos 159
E SCOPOS 160

2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : form >
13 <h : panelGrid columns = " 2 " >
14 <h : outputLabel value = " Marca : " for = " campo - marca " / >
15 <h : inputText value = " #{ carroBean . carro . marca } " id = " campo - marca " / >
16
17 <h : outputLabel value = " Modelo : " for = " campo - modelo " / >
18 <h : inputText value = " #{ carroBean . carro . modelo } " id = " campo - modelo " / >
19
20 <h : commandButton value = " Adicionar " action = " #{ carroBean . adicionaCarro } " / >
21 </ h : panelGrid >
22 </ h : form >
23
24 <h : panelGroup rendered = " #{ not empty carroBean . carros } " >
25 < h1 > Lista de carros : </ h1 >
26 < ul >
27 < ui : repeat value = " #{ carroBean . carros } " var = " carro " >
28 < li > <h : outputText value = " #{ carro . marca } #{ carro . modelo } " / > </ li >
29 </ ui : repeat >
30 </ ul >
31 </ h : panelGroup >
32 </ h : body >
33 </ html >

Cdigo XHTML 9.2: carros.xhtml

10 Remova o projeto K19-Navegacao do Glassfish e do Wildfly. Implante o projeto K19-Escopos


no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o endereo abaixo
para testar a aplicao.

http://localhost:8080/K19-Escopos/carros.xhtml

Adicione alguns carros e observe a lista de carros. O que acontece?

11 Implante o projeto K19-Escopos no Wildfly. Certifique-se que o Glassfish esteja parado. Inicie o
Wildfly e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Escopos/carros.xhtml

Novamente, adicione alguns carros e observe a lista de carros. O que acontece?

12 Mude o escopo do managed bean carroBean de request para view. Para isso, use a anotao
@ViewScoped.

1 @ViewScoped
2 public class CarroBean {
3 ...
4 }

Cdigo Java 9.10: CarroBean.java

160 www.k19.com.br
161 E SCOPOS

No esquea de importar a anotao @ViewScoped.

13 Novamente, acesse a aplicao no endereo:

http://localhost:8080/K19-Escopos/carros.xhtml

Adicione alguns carros e observe a lista de carros. O que acontece?

14 Crie uma pgina chamada menu.xhtml. Essa pgina deve possuir um link para a pgina car-
ros.xhtml.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10 <h : body >
11 <h : link value = " Adicionar carros " outcome = " carros " / >
12 </ h : body >
13 </ html >

Cdigo XHTML 9.3: menu.xhtml

15 No arquivo carros.xhtml, adicione um link para a pgina menu.xhtml.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12 <h : body >
13 <h : link value = " Menu " outcome = " menu " / >
14
15 <h : form >
16 <h : panelGrid columns = " 2 " >
17 <h : outputLabel value = " Marca : " for = " campo - marca " / >
18 <h : inputText value = " #{ carroBean . carro . marca } " id = " campo - marca " / >
19
20 <h : outputLabel value = " Modelo : " for = " campo - modelo " / >
21 <h : inputText value = " #{ carroBean . carro . modelo } " id = " campo - modelo " / >
22
23 <h : commandButton value = " Adicionar " action = " #{ carroBean . adicionaCarro } " / >
24 </ h : panelGrid >
25 </ h : form >
26
27 <h : panelGroup rendered = " #{ not empty carroBean . carros } " >
28 < h1 > Lista de carros : </ h1 >
29 < ul >
30 < ui : repeat value = " #{ carroBean . carros } " var = " carro " >
31 < li > <h : outputText value = " #{ carro . marca } #{ carro . modelo } " / > </ li >
32 </ ui : repeat >
33 </ ul >

www.facebook.com/k19treinamentos 161
E SCOPOS 162

34 </ h : panelGroup >


35 </ h : body >
36 </ html >

Cdigo XHTML 9.4: carros.xhtml

16 Acesse a aplicao no endereo:

http://localhost:8080/K19-Escopos/carros.xhtml

Certifique-se de que o escopo do managed bean carroBean seja view. Mais uma vez, adicione
alguns carros e observe a lista de carros. Use os links criados para navegar entre as pginas car-
ros.xhtml e menu.xhtml. O que acontece?

17 Mude o escopo do managed bean carroBean de view para session. Para isso, use a anotao
@SessionScoped.

1 @SessionScoped
2 public class CarroBean {
3 ...
4 }

Cdigo Java 9.11: CarroBean.java

No esquea de importar a anotao @SessionScoped.

18 Acesse a aplicao no endereo:

http://localhost:8080/K19-Escopos/carros.xhtml

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?

19 Agora, acesse a aplicao a partir de navegadores diferentes. Adicione alguns carros a partir dos

diferentes navegadores. O que voc observa?

20 Mude o escopo do managed bean carroBean de session para application. Para isso, use a ano-
tao @ApplicationScoped.

1 @ApplicationScoped
2 public class CarroBean {
3 ...
4 }

Cdigo Java 9.12: CarroBean.java

No esquea de importar a anotao @ApplicationScoped.

21 Novamente, usando navegadores diferentes, adicione alguns carros. O que voc pode observar?

162 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 con-
verso 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 con-
versores 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.facebook.com/k19treinamentos 163
C ONVERSO E VALIDAO 164

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 @ManagedBean
2 public class TesteBean {
3
4 private double numero ;
5
6 // GETTERS E SETTERS
7 }

Cdigo Java 10.1: TesteBean.java

1 <! - - O valor digitado nesse campo ser convertido para double -->
2 <h : inputText value = " #{ testeBean . numero } " / >

Cdigo XHTML 10.1: Caixa de texto vinculada propriedade numero

Personalizando Conversores Padro


Alguns conversores padro podem ou precisam usar informaes adicionais para realizar a con-
verso de dados. As tags <f:convertNumber> e <f:convertDateTime> so usadas para transmitir
informaes aos conversores de nmeros (java.lang.Number) e datas (java.util.Date), respecti-
vamente.

<f:convertNumber>

A tag <f:convertNumber> permite que converses mais sofisticadas sejam feitas em valores nu-
mricos.

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 <h : outputText value = " #{ testeBean . numero } " >


2 <f : convertNumber maxFractionDigits = " 2 " / >
3 </ h : outputText >

Analogamente, podemos definir o nmero mnimo de casas decimais com o atributo minFrac-
tionDigits.

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 <h : outputText value = " #{ testeBean . numero } " >


2 <f : convertNumber pattern = " #0.000 " / >
3 </ h : outputText >

164 www.k19.com.br
165 C ONVERSO E VALIDAO

Para apresentar dados na forma de porcentagem, podemos usar o atributo type e defini-lo com
o valor percent.

1 <h : outputText value = " #{ testeBean . numero } " >


2 <f : convertNumber type = " percent " / >
3 </ h : outputText >

Para personalizar a exibio de valores monetrios, a tag <f:convertNumber> prov o atributo


currencySymbol e locale. No cdigo abaixo, exemplificamos o uso desses dois atributos.

1 <h : outputText value = " #{ testeBean . numero } " >


2 <f : convertNumber currencySymbol = " R$ " type = " currency " / >
3 </ h : outputText >
4
5 <h : outputText value = " #{ testeBean . numero } " >
6 <f : convertNumber locale = " pt_BR " type = " currency " / >
7 </ h : outputText >

<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. Essa tag possui o atributo pattern, que per-
mite a definio do formato da data que desejamos utilizar.

1 <h : outputText value = " #{ testeBean . data } " >


2 <f : convertDateTime pattern = " dd / MM / yyyy " / >
3 </ h : outputText >

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 <h : outputText value = " #{ testeBean . data } " >


2 <f : convertDateTime locale = " pt_BR " / >
3 </ h : outputText >

Exerccios de Fixao

1 Crie um projeto chamado K19-Conversao-e-Validacao seguindo os passos vistos no exerccio


do Captulo 5.

2 Crie uma classe chamada Funcionario para modelar funcionrios em um pacote chamado
br.com.k19.modelo.

1 package br . com . k19 . modelo ;


2
3 import java . util . Date ;
4

www.facebook.com/k19treinamentos 165
C ONVERSO E VALIDAO 166

5 public class Funcionario {


6 private Double salario ;
7 private Integer codigo ;
8 private Date aniversario ;
9
10 // GETTERS E SETTERS
11 }

Cdigo Java 10.2: Funcionario.java

3 Crie uma class chamada FuncionarioBean contendo um atributo do tipo Funcionario em um


pacote chamado br.com.k19.controle.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Funcionario ;
4 import javax . faces . bean . ManagedBean ;
5
6 @ManagedBean
7 public class FuncionarioBean {
8 private Funcionario funcionario = new Funcionario () ;
9
10 // GETTER E SETTER
11 }

Cdigo Java 10.3: FuncionarioBean.java

4 Crie uma pgina chamada cadastro.xhtml para cadastrar funcionrios.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Cadastro de Funcionrio </ h1 >
13 <h : form >
14 <h : panelGrid columns = " 3 " >
15 <h : outputLabel value = " Salrio : R$ " for = " campo - salario " / >
16 <h : inputText id = " campo - salario " value = " #{ funcionarioBean . funcionario . salario } " >
17 <f : convertNumber locale = " pt_BR " / >
18 </ h: inputText >
19 <h : message for = " campo - salario " / >
20
21 <h : outputLabel value = " Cdigo : " for = " campo - codigo " / >
22 <h : inputText id = " campo - codigo " value = " #{ funcionarioBean . funcionario . codigo } " / >
23 <h : message for = " campo - codigo " / >
24
25 <h : outputLabel value = " Data : ( dd / MM / yyyy ) " for = " campo - aniversario " / >
26 <h : inputText id = " campo - aniversario "
27 value = " #{ funcionarioBean . funcionario . aniversario } " >
28 <f : convertDateTime pattern = " dd / MM / yyyy " / >
29 </ h: inputText >
30 <h : message for = " campo - aniversario " / >
31
32 <h : commandButton value = " Cadastrar " / >
33 </ h : panelGrid >
34 <h : messages / >
35 </ h : form >

166 www.k19.com.br
167 C ONVERSO E VALIDAO

36 </ h : body >


37 </ html >

Cdigo XHTML 10.8: cadastro.xhtml

5 Remova o projeto K19-Escopos do Glassfish e do Wildfly. Implante o projeto K19-Conversao-


e-Validacao no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o
endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Conversao-e-Validacao/cadastro.xhtml

Preencha o formulrio com valores inadequados diversas vezes e observe as mensagens de erros.

6 Implante o projeto K19-Conversao-e-Validacao no Wildfly. Certifique-se que o Glassfish esteja


parado. Inicie o Wildfly e acesse o endereo abaixo para testar a aplicao.

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

1 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 porcenta-
gem, 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.

2 Exiba na tela os valores que foram submetidos pelo formulrio e convertidos.

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 re-
lacionadas aos erros no preenchimento das informaes.

<h:message>
Para exibir erros relacionados a um determinado campo, podemos utilizar o componente <h:me-
ssage>. 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:me-
ssage> igual ao valor do atributo id do campo em questo.

1 @ManagedBean

www.facebook.com/k19treinamentos 167
C ONVERSO E VALIDAO 168

2 public class TesteBean {


3
4 private Double numero ;
5
6 // GETTERS E SETTERS
7 }

Cdigo Java 10.6: TesteBean.java

1 <h : inputText value = " #{ testeBean . numero } " id = " campo - numero " / >
2 <h : message for = " campo - numero " / >

Cdigo XHTML 10.11: Exibindo mensagens de erro relacionadas a um campo de texto

As imagens abaixo exibem o campo de texto com o valor digitado pelo usurio e aps o proces-
samento da requisio.

K19 Treinamentos
Enviar

Figura 10.1: Campo de texto associado a uma propriedade numrica de um managed bean

K19 Treinamentos
form:campo-numero: K19 Treinamentos must be a number between
4.9E-324 and 1.7976931348623157E308 Example: 1999999
Enviar

Figura 10.2: Mensagem de erro de converso

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 pa-
dro, 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, en-
quanto o segundo indica se a mensagem detalhada deve ser exibida. Esses atributos devem as-
sumir valores true ou false. Veja o exemplo abaixo.

1 <h : inputText value = " #{ testeBean . numero } " id = " campo - numero " / >
2 <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.

168 www.k19.com.br
169 C ONVERSO E VALIDAO

<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 <h : messages / >

Cdigo XHTML 10.13: Exibindo todas as mensagens

Ao contrrio da tag <h:message>, os valores padro dos atributos showSummary e showDetail da


tag <h:messages> so true e false, respectivamente.

Alterando as Mensagens de Erro


O texto de cada mensagem de erro de converso ou validao est definido na especificao do
JSF 2 que pode ser obtida atravs da url http://jcp.org/en/jsr/detail?id=314. Normalmente,
queremos personalizar essas mensagens. Para isso, so necessrios dois passos:

1. Criar um arquivo de mensagens.

2. Registrar esse arquivo no faces-config.xml.

Criando um Arquivo de Mensagens

Um arquivo de mensagens um conjunto de chaves e valores. As chaves so utilizadas para


recuperar as mensagens, enquanto os valores definem os textos que sero exibidos.

O maior problema para definir um arquivo de mensagens no JSF saber quais so as chaves
que podemos utilizar. Para conhecer as chaves, devemos consultar a especificao do JSF que pode
ser obtida atravs da url http://jcp.org/en/jsr/detail?id=314. Veja um exemplo de arquivo de
mensagens:

1 javax . faces . converter . BooleanConverter . BOOLEAN ={1} : {0} must be true or false -
.

Cdigo XML 10.1: Exemplo de arquivo de mensagens

Os nomes dos arquivos de mensagens devem possuir o sufixo .properties.

Registrando um Arquivo de Mensagens

Suponha que voc tenha criado um arquivo de mensagens chamado Messages.properties num
pacote chamado resources. Para registr-lo, voc deve acrescentar uma configurao no arquivo
faces-config.xml.

1 ...
2 < application >
3 < message - bundle > resources . Messages </ message - bundle >
4 </ application >
5 ...

Cdigo XML 10.2: faces-config.xml

www.facebook.com/k19treinamentos 169
C ONVERSO E VALIDAO 170

Note que o sufixo .properties omitido no faces-config.xml.

Mais Sobre
Suponha que uma aplicao tenha um arquivo de mensagens registrado no
faces-config.xml. Para obter uma mensagem de erro, o JSF buscar primeiramente
nesse arquivo. Caso no a encontre, ele utilizar a mensagem padro.

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 <h : inputText value = " #{ testeBean . numero } " id = " campo - numero "
2 converterMessage = " Por favor , digite um nmero " / >
3 <h : message for = " campo - numero " / >

Cdigo XHTML 10.14: Definindo uma mensagem para um erro de converso

No exemplo acima, se o usurio submeter o formulrio com um valor no numrico no campo


campo-numero, ento a mensagem de erro Por favor, digite um nmero ser exibida na tela
de resposta.

Exerccios de Fixao

7 No projeto K19-Conversao-e-Validacao, crie um pacote chamado resources. Adicione a esse


pacote um arquivo de mensagens chamado Messages.properties com o seguinte contedo.

1 javax . faces . converter . NumberConverter . NUMBER = O valor {0} no adequado .


2 javax . faces . converter . NumberConverter . NUMBER_detail ={0} no nmero ou inadequado .
3 javax . faces . converter . IntegerConverter . INTEGER = O valor {0} no adequado .
4 javax . faces . converter . IntegerConverter . INTEGER_detail ={0} no um nmero inteiro .
5 javax . faces . converter . DateTimeConverter . DATE = A data {0} no est correta .
6 javax . faces . converter . DateTimeConverter . DATE_detail = {0} no parece uma data .

Cdigo XML 10.3: Messages.properties

8 Adicione a configurao necessria no faces-config.xml para utilizar o arquivo de mensagens


criado no exerccio anterior.

1 ...
2 < application >
3 < message - bundle > resources . Messages </ message - bundle >
4 </ application >
5 ...

Cdigo XML 10.4: faces-config.xml

Observao: a tag <application> deve ser colocada dentro de da tag <faces-config>.

170 www.k19.com.br
171 C ONVERSO E VALIDAO

9 Acesse a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/cadastro.xhtml.
Preencha o formulrio vrias vezes com valores inadequados e observe as novas mensagens.

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 anterior-
mente, 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 con-
junto de validadores padro. A seguir, veremos alguns detalhes sobre esses validadores.

Campo Obrigatrio (Required)


A validao mais comum de todas a de verificar se um determinado campo foi preenchido.
Podemos aplicar essa validao utilizando o atributo required.

1 <h : inputText value = " #{ testeBean . nome } " id = " campo - nome " required = " true " / >
2 <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 <h : inputText value = " #{ testeBean . nome } " id = " campo - nome " >
2 <f : validateRequired / >
3 </ h : inputText >
4 <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 per-
tence a um determinado intervalo de nmeros. No exemplo abaixo, o validador ir verificar se o valor
da propriedade idade est entre 10 e 130.

www.facebook.com/k19treinamentos 171
C ONVERSO E VALIDAO 172

1 <h : inputText value = " #{ testeBean . idade } " id = " campo - idade " >
2 <f : validateLongRange minimum = " 10 " maximum = " 130 " / >
3 </ h : inputText >
4 <h : message for = " campo - idade " / >

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 <h : inputText value = " #{ testeBean . preco } " id = " campo - preco " >
2 <f : validateDoubleRange minimum = " 20.57 " maximum = " 200.56 " / >
3 </ h : inputText >
4 <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 m-
xima de caracteres. Veja o exemplo abaixo.

1 <h : inputText value = " #{ testeBean . nome } " id = " campo - nome " >
2 <f : validateLength minimum = " 6 " maximum = " 20 " / >
3 </ h : inputText >
4 <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 ex-
presso 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 <h : inputText value = " #{ testeBean . codigo } " id = " campo - codigo " >
2 <f : validateRegex pattern = " [a - zA - Z ]{6 ,20} " / >
3 </ h : inputText >
4 <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

172 www.k19.com.br
173 C ONVERSO E VALIDAO

10 Vamos acrescentar alguns validadores para os campos do formulrio de cadastro de funcion-


rios do projeto K19-Conversao-e-Validacao. Com base nas restries abaixo, acrescente validadores
apropriados.

O salrio de um funcionrio deve ser no-negativo.

O cdigo de um funcionrio deve ser um nmero inteiro maior ou igual a 5 e estritamente


menor do que 20.

Todos os campos so obrigatrios.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Cadastro de Funcionrio </ h1 >
13 <h : form >
14 <h : panelGrid columns = " 3 " >
15 <h : outputLabel value = " Salrio : R$ " for = " campo - salario " / >
16 <h : inputText id = " campo - salario " value = " #{ funcionarioBean . funcionario . salario } "
17 required = " true " >
18 <f : convertNumber locale = " pt_BR " / >
19 <f : validateDoubleRange minimum = " 0 " / >
20 </ h: inputText >
21 <h : message for = " campo - salario " / >
22
23 <h : outputLabel value = " Cdigo : " for = " campo - codigo " / >
24 <h : inputText id = " campo - codigo " value = " #{ funcionarioBean . funcionario . codigo } "
25 required = " true " >
26 <f : validateLongRange minimum = " 5 " maximum = " 19 " / >
27 </ h: inputText >
28 <h : message for = " campo - codigo " / >
29
30 <h : outputLabel value = " Data : ( dd / MM / yyyy ) " for = " campo - aniversario " / >
31 <h : inputText id = " campo - aniversario "
32 value = " #{ funcionarioBean . funcionario . aniversario } "
33 required = " true " >
34 <f : convertDateTime pattern = " dd / MM / yyyy " / >
35 </ h: inputText >
36 <h : message for = " campo - aniversario " / >
37
38 <h : commandButton value = " Cadastrar " / >
39 </ h : panelGrid >
40 <h : messages / >
41 </ h : form >
42 </ h : body >
43 </ html >

Cdigo XHTML 10.21: cadastro.xhtml

11 Acesse a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/cadastro.xhtml

Teste o formulrio com diversos valores e observe o que acontece.

www.facebook.com/k19treinamentos 173
C ONVERSO E VALIDAO 174

Exerccios Complementares

3 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.

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 public class Funcionario {


2 @NotNull
3 private String nome ;
4 ...
5 }

Cdigo Java 10.9: Funcionario.java

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 < context - param >
3 < param - name >
4 javax . faces . INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL
5 </ param - name >
6 < param - value > true </ param - value >
7 </ context - param >
8 ...

Cdigo XML 10.5: web.xml

174 www.k19.com.br
175 C ONVERSO E VALIDAO

Veja abaixo as anotaes disponveis e suas respectivas funes.

@AssertFalse
Verifica se uma propriedade booleana possui valor false.
@AssertTrue
Verifica se uma propriedade booleana possui valor true.
@DecimalMax
Define o valor real mximo que uma propriedade pode armazenar.
@DecimalMin
Define o valor real mnimo que uma propriedade pode assumir.
@Digits
Define a quantidade mxima de dgitos da parte inteira (atravs do atributo integer) ou da
parte fracionria (atravs do atributo fraction) de um nmero.
@Future
Verifica se uma data posterior ao instante atual.
@Max
Define o valor inteiro mximo que uma propriedade pode assumir.
@Min
Define o valor inteiro mnimo que uma propriedade pode armazenar.
@NotNull
Verifica se o valor de uma propriedade no null.
@Null
Verifica se o valor de uma propriedade null.
@Past
Verifica se uma data anterior ao instante atual.
@Pattern
Verifica se o valor de uma propriedade respeita uma expresso regular.
@Size
Define os tamanhos mnimo (atravs do atributo min) e mximo (atravs do atributo max) para
uma Collection, array ou String.

As validaes definidas atravs das anotaes da especificao bean validation so aplicadas au-
tomaticamente pelo JSF. As mensagens de erro referentes a essas validaes so automaticamente
acrescentadas no contexto do processamento da requisio correspondente.

Mais Sobre
Para desabilitar bean validations em um componente particular de um formulrio, po-
demos usar a tag <f:validateBean>. Isso pode ser feito atribuindo o valor true ao
atributo disabled dessa tag. Considere o seguinte managed bean.

www.facebook.com/k19treinamentos 175
C ONVERSO E VALIDAO 176

1 public class FuncionarioBean {


2
3 private Funcionario funcionario = new Funcionario () ;
4
5 // GETTER E SETTER
6 }

Cdigo Java 10.10: FuncionarioBean.java

No exemplo abaixo, a validao introduzida pela anotao @NotNull do atributo nome da classe
Funcionario desabilitada.
1 <h : inputText value = " #{ funcionarioBean . funcionario . nome } " >
2 <f : validateBean disabled = " true " / >
3 </ h : inputText >

Cdigo XHTML 10.23: Desabilitando validaes introduzidas por anotaes

Personalizando as mensagens de erro

Podemos personalizar as mensagens de erro atravs do atributo message das anotaes do bean
validation. Veja o seguinte cdigo.

1 public class Funcionario {


2 @NotNull ( message = " O nome no pode ser nulo " )
3 private String nome ;
4 ...
5 }

Cdigo Java 10.11: Funcionario.java

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 br . com . k19 . Funcionario . nome = O nome do funcionrio no pode ser nulo

Arquivo de Propriedades 10.1: ValidationMessages.properties

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 public class Funcionario {


2 @NotNull ( message = " { br . com . k19 . Funcionario . nome } " )
3 private String nome ;
4 ...
5 }

Cdigo Java 10.12: Funcionario.java

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 va-
lor padro da propriedade message desse validador "{javax.validation.constraints.NotNull-

176 www.k19.com.br
177 C ONVERSO E VALIDAO

.message}", basta definir uma mensagem com essa chave no arquivo ValidationMessages.pro-
perties.

1 javax . validation . constraints . NotNull . message = O valor no pode ser nulo

Arquivo de Propriedades 10.2: ValidationMessages.properties

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 Remova os validadores do arquivo cadastro.xhtml que voc adicionou no exerccio anterior.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Cadastro de Funcionrio </ h1 >
13 <h : form >
14 <h : panelGrid columns = " 3 " >
15 <h : outputLabel value = " Salrio : R$ " for = " campo - salario " / >
16 <h : inputText id = " campo - salario " value = " #{ funcionarioBean . funcionario . salario } " >
17 <f : convertNumber locale = " pt_BR " / >
18 </ h: inputText >
19 <h : message for = " campo - salario " / >
20
21 <h : outputLabel value = " Cdigo : " for = " campo - codigo " / >
22 <h : inputText id = " campo - codigo " value = " #{ funcionarioBean . funcionario . codigo } " / >
23 <h : message for = " campo - codigo " / >
24

www.facebook.com/k19treinamentos 177
C ONVERSO E VALIDAO 178

25 <h : outputLabel value = " Data : ( dd / MM / yyyy ) " for = " campo - aniversario " / >
26 <h : inputText id = " campo - aniversario "
27 value = " #{ funcionarioBean . funcionario . aniversario } " >
28 <f : convertDateTime pattern = " dd / MM / yyyy " / >
29 </ h: inputText >
30 <h : message for = " campo - aniversario " / >
31
32 <h : commandButton value = " Cadastrar " / >
33 </ h : panelGrid >
34 <h : messages / >
35 </ h : form >
36 </ h : body >
37 </ html >

Cdigo XHTML 10.24: cadastro.xhtml

13 Usando bean validation, modifique a classe Funcionario para considerar as restries do exer-

ccio anterior, isto :

O salrio de um funcionrio deve ser no-negativo.


O cdigo de um funcionrio deve ser um nmero inteiro maior ou igual a 5 e estritamente
menor do que 20.
Todos os campos so obrigatrios.

1 package br . com . k19 . modelo ;


2
3 import java . util . Date ;
4 import javax . validation . constraints . Max ;
5 import javax . validation . constraints . Min ;
6 import javax . validation . constraints . NotNull ;
7
8 public class Funcionario {
9
10 @NotNull
11 @Min ( value = 0)
12 private Double salario ;
13
14 @NotNull
15 @Min ( value = 5)
16 @Max ( value = 19)
17 private Integer codigo ;
18
19 @NotNull
20 private Date aniversario ;
21
22 // GETTERS E SETTERS
23 }

Cdigo Java 10.13: Funcionario.java

14 Acesse a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/cadastro.xhtml

Teste o formulrio com diversos valores e observe o que acontece.

Criando o seu Prprio Conversor

178 www.k19.com.br
179 C ONVERSO E VALIDAO

Se os conversores padro no forem suficientes para atender as necessidades de uma aplicao,


podemos criar os nossos prprios conversores. Considere uma aplicao que armazena nmeros de
telefones internacionais. Esses nmeros sero modelados pela seguinte classe.

1 public class Telefone {


2 private String codigoDoPais ;
3 private String codigoDeArea ;
4 private String numeroLocal ;
5
6 // GETTERS E SETTERS
7 }

Cdigo Java 10.14: Telefone.java

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, opcional-
mente, 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 in-
terface javax.faces.convert.Converter. Nessa classe, devemos adicionar a anotao @FacesCon-
verter para indicar a classe associada a esse conversor, como no cdigo abaixo.

1 @FacesConverter ( forClass = Telefone . class )


2 public class ConversorDeTelefone implements Converter {
3 ...
4 }

Cdigo Java 10.15: ConversorDeTelefone.java

A interface Converter exige a implementao de dois mtodos: getAsObject() e getAsStr-


ing(). 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 package br . com . k19 ;


2

www.facebook.com/k19treinamentos 179
C ONVERSO E VALIDAO 180

3 @FacesConverter ( forClass = Telefone . class )


4 public class ConversorDeTelefone implements Converter {
5
6 @Override
7 public Object getAsObject ( FacesContext context , UIComponent component ,
8 String value ) {
9
10 value = value . trim () ;
11
12 if (! Pattern . matches ( " [0 -9]+\\ s +[0 -9]+\\ s +[0 -9 -]+ " , value ) ) {
13 FacesMessage mensagem = new FacesMessage ( " Nmero de telefone invlido " ) ;
14 mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
15 throw new ConverterException ( mensagem ) ;
16 }
17
18 String campos [] = value . split ( " \\ s + " ) ;
19
20 String codigoDoPais = campos [0];
21 String codigoDeArea = campos [1];
22 String numeroLocal = campos [2]. replaceAll ( " -" , " " ) ;
23
24 Telefone telefone = new Telefone ( codigoDoPais , codigoDeArea , numeroLocal ) ;
25 return telefone ;
26 }
27
28 @Override
29 public String getAsString ( FacesContext context , UIComponent component ,
30 Object value ) {
31 Telefone telefone = ( Telefone ) value ;
32 return telefone . getCodigoDoPais ()
33 + " " + telefone . getCodigoDeArea ()
34 + " " + telefone . getNumeroLocal () ;
35 }
36 }

Cdigo Java 10.16: ConversorDeTelefone.java

Se a string recebida pelo mtodo getAsObject() no respeita o formato de nmeros de telefone


definido acima, uma mensagem de erro criada e uma exceo do tipo javax.faces.convert.Con-
verterException guardando essa mensagem lanada.

Exerccios de Fixao

15 Considere um formulrio que possua uma caixa de texto para receber um nmero de CPF (Ca-
dastro de Pessoas Fsicas). Um nmero de CPF dividido em duas partes. A primeira parte do n-
mero 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 d-
gitos 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.

Implemente um conversor de nmeros de CPF. Primeiramente, crie uma classe chamada CPF
dentro do pacote br.com.k19.modelo para representar um nmero de CPF. Essa classe deve ter trs
atributos do tipo int: um para armazenar o nmero de identificao e outros dois para guardar os
dgitos verificadores.

1 package br . com . k19 . modelo ;


2
3 public class CPF {

180 www.k19.com.br
181 C ONVERSO E VALIDAO

4 private int numeroDeIdentificacao ;


5 private int primeiroDigitoVerificador ;
6 private int segundoDigitoVerificador ;
7
8 // GETTERS E SETTERS
9 }

Cdigo Java 10.17: CPF.java

16 Crie um pacote chamado br.com.k19.converters.

17 Agora, dentro do pacote br.com.k19.converters, crie uma classe chamada ConversorDeCPF


para implementar o conversor de nmeros de CPF. Um nmero de CPF deve respeitar o seguinte
formato: XXXXXXXXX-XX. Lembre que essa classe deve ser anotada com @FacesConverter e imple-
mentar a interface javax.faces.convert.Converter.

1 package br . com . k19 . converters ;


2
3 import br . com . k19 . modelo . CPF ;
4 import java . util . regex . Pattern ;
5 import javax . faces . application . FacesMessage ;
6 import javax . faces . component . UIComponent ;
7 import javax . faces . context . FacesContext ;
8 import javax . faces . convert . Converter ;
9 import javax . faces . convert . ConverterException ;
10 import javax . faces . convert . FacesConverter ;
11
12 @FacesConverter ( forClass = CPF . class )
13 public class ConversorDeCPF implements Converter {
14
15 @Override
16 public Object getAsObject ( FacesContext context , UIComponent component ,
17 String value ) {
18
19 value = value . trim () ;
20
21 if (! Pattern . matches ( " [0 -9]{9} -[0 -9]{2} " , value ) ) {
22 FacesMessage mensagem = new FacesMessage ( " Nmero de CPF invlido " ) ;
23 mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
24 throw new ConverterException ( mensagem ) ;
25 }
26
27 String partesDoCPF [] = value . split ( " -" ) ;
28 int numeroDeIdentificacao = Integer . parseInt ( partesDoCPF [0]) ;
29 int primeiroDigitoVerificador = Integer . parseInt ( partesDoCPF [1]. substring (0 , 1) ) ;
30 int segundoDigitoVerificador = Integer . parseInt ( partesDoCPF [1]. substring (1 , 2) ) ;
31
32 CPF cpf = new CPF () ;
33 cpf . setNumeroDeIdentificacao ( numeroDeIdentificacao ) ;
34 cpf . setPrimeiroDigitoVerificador ( primeiroDigitoVerificador ) ;
35 cpf . setSegundoDigitoVerificador ( segundoDigitoVerificador ) ;
36
37 return cpf ;
38 }
39
40 @Override
41 public String getAsString ( FacesContext context , UIComponent component ,
42 Object value ) {
43 CPF cpf = ( CPF ) value ;
44 return cpf . getNumeroDeIdentificacao () + " -" + cpf . getPrimeiroDigitoVerificador ()
45 + cpf . getSegundoDigitoVerificador () ;
46 }
47 }

www.facebook.com/k19treinamentos 181
C ONVERSO E VALIDAO 182

Cdigo Java 10.18: ConversorDeCPF.java

18 No pacote br.com.k19.controle, crie uma classe chamada CPFBean para implementar o mana-

ged bean que dar suporte ao formulrio.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . CPF ;
4 import javax . faces . bean . ManagedBean ;
5
6 @ManagedBean
7 public class CPFBean {
8 private CPF cpf ;
9
10 // GETTER E SETTER
11 }

Cdigo Java 10.19: CPFBean.java

19 Finalmente, crie uma pgina chamada formulario.xhtml e implemente um formulrio para


receber um nmero de CPF.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6 <h : head >
7 < title > K19 Treinamentos </ title >
8 </ h : head >
9
10 <h : body >
11 < h1 > Formulrio </ h1 >
12 <h : form >
13 <h : outputLabel value = " CPF : " for = " cpf " / >
14 <h : inputText id = " cpf " value = " #{ cPFBean . cpf } " / >
15 <h : commandButton value = " Enviar " / >
16 </ h : form >
17
18 <h : message for = " cpf " style = " color : red " / >
19 </ h : body >
20 </ html >

Cdigo XHTML 10.25: formulario.xhtml

20 Acesse a aplicao no endereo:


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

182 www.k19.com.br
183 C ONVERSO E VALIDAO

4 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.

Criando o seu Prprio Validador

A criao de um validador anloga criao de um conversor. Precisamos criar uma classe


que implemente a interface javax.faces.validator.Validator. Essa interface define um nico
mtodo, o validate(). Alm disso, a classe tambm precisa ser anotada com @FacesValidator.

Considere um formulrio HTML que possui uma caixa de texto para o usurio digitar um nmero
primo. Um nmero primo um nmero natural maior do que 1 cujos nicos divisores positivos so
1 e ele mesmo. Essa caixa de texto est associada a uma propriedade do tipo long em um managed
bean.

Aps o usurio submeter esse formulrio e uma vez que a etapa de converso foi concluda, pre-
cisamos validar os dados do formulrio. Em particular, precisamos verificar se o nmero digitado
pelo usurio primo. Criaremos uma classe chamada ValidadorDeNumerosPrimos para implemen-
tar um validador que execute essa tarefa.

1 package br . com . k19 ;


2
3 @FacesValidator ( " br . com . k19 . ValidadorDeNumerosPrimos " )
4 public class ValidadorDeNumerosPrimos implements Validator {
5 ...
6 }

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 package br . com . k19 ;


2
3 @FacesValidator ( " br . com . k19 . ValidadorDeNumerosPrimos " )
4 public class ValidadorDeNumerosPrimos implements Validator {
5
6 @Override
7 public void validate ( FacesContext context , UIComponent component , Object value ) {
8
9 long numero = ( Long ) value ;
10 boolean isPrimo = false ;
11
12 if ( numero > 1) {
13 double raizQuadrada = Math . sqrt (( double ) numero ) ;
14 isPrimo = true ;
15
16 for ( long i = 2; i <= raizQuadrada ; i ++) {
17 if ( numero % i == 0) {
18 isPrimo = false ;

www.facebook.com/k19treinamentos 183
C ONVERSO E VALIDAO 184

19 break ;
20 }
21 }
22 }
23
24 if (! isPrimo ) {
25 FacesMessage mensagem = new FacesMessage ( " O nmero " + numero + " no primo " ) -
;
26 mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
27 throw new ValidatorException ( mensagem ) ;
28 }
29 }
30 }

Cdigo Java 10.24: ValidadorDeNumerosPrimos.java

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.Va-
lidadorDeNumerosPrimos".

O cdigo XHTML abaixo define um formulrio com uma caixa de texto e vincula essa caixa ao
validador de nmeros primos.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : form >
13 <h : outputLabel value = " Digite um nmero primo : " for = " numero - primo " / >
14 <h : inputText value = " #{ testeBean . numeroPrimo } " id = " numero - primo " >
15 <f : validator validatorId = " br . com . k19 . ValidadorDeNumerosPrimos " / >
16 </ h : inputText >
17 <h : commandButton value = " Enviar " / >
18 < br / >
19 <h : message for = " numero - primo " style = " color : red " / >
20 </ h : form >
21 </ h : body >
22 </ html >

Cdigo XHTML 10.27: Associando um validador a uma propriedade

Passando Parmetros para o Validador


Para realizar a validao de um determinado dado, informaes adicionais podem ser necess-
rias. Por exemplo, considere o caso em que precisamos verificar se uma data escolhida por um usu-
rio pertence a um determinado intervalo. Nesse caso, precisamos de duas informaes adicionais:
as datas de incio e fim do intervalo.

Da mesma forma que criamos um validador de nmeros primos, podemos criar um validador

184 www.k19.com.br
185 C ONVERSO E VALIDAO

para realizar essa verificao. A diferena que agora precisamos das datas que determinam o inter-
valo. Por exemplo, se tivermos uma caixa de texto para receber a data escolhida pelo usurio, ento
as datas de incio e fim do intervalo podem ser definidas como atributos dessa caixa.

Para definir um atributo de um componente visual, podemos usar a tag <f:attribute>. Essa tag
possui dois parmetros (name e value), que so usados para definir o nome e o valor desse atributo.

Em nosso exemplo, criaremos dois atributos, que chamaremos de "inicio" e "fim", para definir
as datas que delimitam o intervalo a ser considerado. No cdigo abaixo, criamos esses atributos com
valores "01/05/2014" e "30/08/2014", respectivamente.

1 <h : inputText value = " #{ testeBean . data } " id = " campo - data " >
2 <f : attribute name = " inicio " value = " 01/05/2014 " / >
3 <f : attribute name = " fim " value = " 30/08/2014 " / >
4 </ 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 @Override
2 public void validate ( FacesContext context , UIComponent component , Object value ) {
3
4 String inicio = ( String ) component . getAttributes () . get ( " inicio " ) ;
5 String fim = ( String ) component . getAttributes () . get ( " fim " ) ;
6 ...
7 }

Cdigo Java 10.25: Recuperando atributos de um componente visual

Exerccios de Fixao

21 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.

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 br.com.k19.validators no projeto K19-Conversao-e-Validacao.

www.facebook.com/k19treinamentos 185
C ONVERSO E VALIDAO 186

22 No pacote br.com.k19.validators, crie uma classe chamada ValidadorDeCPF. Lembre que essa
classe deve ser anotada com @FacesValidator e implementar a interface javax.faces.validator.Validator.

1 package br . com . k19 . validators ;


2
3 import br . com . k19 . modelo . CPF ;
4 import javax . faces . application . FacesMessage ;
5 import javax . faces . component . UIComponent ;
6 import javax . faces . context . FacesContext ;
7 import javax . faces . validator . FacesValidator ;
8 import javax . faces . validator . Validator ;
9 import javax . faces . validator . ValidatorException ;
10
11 @FacesValidator ( value = " br . com . k19 . validators . ValidadorDeCPF " )
12 public class ValidadorDeCPF implements Validator {
13
14 @Override
15 public void validate ( FacesContext context , UIComponent component ,
16 Object value ) throws ValidatorException {
17
18 CPF cpf = ( CPF ) value ;
19 int numeroDeIdentificacao = cpf . getNumeroDeIdentificacao () ;
20 int primeiroDigitoVerificador = cpf . getPrimeiroDigitoVerificador () ;
21 int segundoDigitoVerificador = cpf . getSegundoDigitoVerificador () ;
22
23 if (! this . validaCPF ( numeroDeIdentificacao , primeiroDigitoVerificador ,
24 segundoDigitoVerificador ) ) {
25
26 String numero = numeroDeIdentificacao + " -"
27 + primeiroDigitoVerificador + segundoDigitoVerificador ;
28
29 FacesMessage mensagem = new FacesMessage ( " O nmero " + numero
30 + " no um CPF vlido " ) ;
31 mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
32 throw new ValidatorException ( mensagem ) ;
33 }
34 }
35
36 private boolean validaCPF ( int numeroDeIdentificacao ,
37 int primeiroDigitoVerificador , int segundoDigitoVerificador ) {
38
39 long primeiroDigito = this . modulo11 (( long ) numeroDeIdentificacao ) ;
40 long segundoDigito = this . modulo11 (( long ) numeroDeIdentificacao * 10
41 + primeiroDigito ) ;
42 return primeiroDigitoVerificador == primeiroDigito
43 && segundoDigitoVerificador == segundoDigito ;
44 }
45
46 private long modulo11 ( long numero ) {
47 long soma = 0;
48 long multiplicador = 2;
49 while ( numero > 0) {
50 long digito = numero % 10;
51 soma += multiplicador * digito ;
52 numero /= 10;
53 multiplicador ++;
54 }
55 long resto = soma % 11;
56 if ( resto < 2)
57 return 0;
58 else
59 return 11 - resto ;
60 }
61 }

Cdigo Java 10.26: ValidadorDeCPF.java

186 www.k19.com.br
187 C ONVERSO E VALIDAO

23 No arquivo formulario.xhtml, associe a caixa de texto ao validador de nmeros de CPF criado.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 < h1 > Formulrio </ h1 >
14 <h : form >
15 <h : outputLabel value = " CPF : " for = " cpf " / >
16 <h : inputText id = " cpf " value = " #{ cPFBean . cpf } " >
17 <f : validator validatorId = " br . com . k19 . validators . ValidadorDeCPF " / >
18 </ h : inputText >
19 <h : commandButton value = " Enviar " / >
20 </ h : form >
21 <h : message for = " cpf " style = " color : red " / >
22 </ h : body >
23 </ html >

Cdigo XHTML 10.29: formulario.xhtml

24 Acesse a aplicao no endereo:


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

5 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 res-
trio. As datas que definem o intervalo devem ser passadas como parmetro para o validador com
o uso da tag <f:attribute>.

Criando o seu Prprio Bean Validator

Vimos que os bean validators podem ser registrados atravs de anotaes. Agora, mostraremos
como criar o seu prprio bean validator e uma anotao para aplic-lo. Para exemplificar, considere
a validao de nmeros primos. No exemplo abaixo, definimos a anotao @Primo.

1 package br . com . k19 ;


2
3 import static java . lang . annotation . ElementType . ANNOTATION_TYPE ;
4 import static java . lang . annotation . ElementType . FIELD ;
5 import static java . lang . annotation . ElementType . METHOD ;
6 import static java . lang . annotation . RetentionPolicy . RUNTIME ;
7

www.facebook.com/k19treinamentos 187
C ONVERSO E VALIDAO 188

8 import java . lang . annotation . Retention ;


9 import java . lang . annotation . Target ;
10
11 import javax . validation . Constraint ;
12 import javax . validation . Payload ;
13
14 @Target ({ METHOD , FIELD , ANNOTATION_TYPE })
15 @Retention ( RUNTIME )
16 @Constraint ( validatedBy = ValidadorDePrimo . class )
17 public @interface Primo {
18 String message () default " { br . com . k19 . Primo . message } " ;
19 Class <? >[] groups () default {};
20 Class <? extends Payload >[] payload () default {};
21 }

Cdigo Java 10.29: Primo.java

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.vali-
dation.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 public class ValidadorDePrimo implements ConstraintValidator < Primo , Long > {


2
3 @Override
4 public void initialize ( Primo constraintAnnotation ) {
5
6 }
7
8 @Override
9 public boolean isValid ( Long value , ConstraintValidatorContext context ) {
10 if ( value <= 1) {
11 return false ;
12 }
13 double raizQuadrada = Math . sqrt (( double ) value ) ;
14
15 for ( long i = 2; i <= raizQuadrada ; i ++) {
16 if ( value % i == 0) {
17 return false ;
18 }
19 }
20 return true ;
21 }
22 }

Cdigo Java 10.30: ValidadorDePrimo.java

Por fim, devemos definir o valor da mensagem associada chave br.com.k19.Primo.message


no arquivo ValidationMessages.properties.

1 br . com . k19 . Primo . message = O nmero no primo

Arquivo de Propriedades 10.3: ValidationMessages.properties

188 www.k19.com.br
189 C ONVERSO E VALIDAO

Exerccios de Fixao

25 Seguindo o exerccio anterior, crie um bean validator para validar nmeros de CPF. Primeiro,
crie um pacote chamado br.com.k19.beanvalidators.

26 No pacote br.com.k19.beanvalidators, defina a anotao @CPF como no cdigo abaixo.

1 package br . com . k19 . beanvalidators ;


2
3 import static java . lang . annotation . ElementType . ANNOTATION_TYPE ;
4 import static java . lang . annotation . ElementType . FIELD ;
5 import static java . lang . annotation . ElementType . METHOD ;
6 import static java . lang . annotation . RetentionPolicy . RUNTIME ;
7
8 import java . lang . annotation . Retention ;
9 import java . lang . annotation . Target ;
10
11 import javax . validation . Constraint ;
12 import javax . validation . Payload ;
13
14 @Target ({ METHOD , FIELD , ANNOTATION_TYPE })
15 @Retention ( RUNTIME )
16 @Constraint ( validatedBy = br . com . k19 . beanvalidators . CPFBeanValidator . class )
17 public @interface CPF {
18 String message () default " O nmero de CPF no vlido " ;
19 Class <? >[] groups () default {};
20 Class <? extends Payload >[] payload () default {};
21 }

Cdigo Java 10.31: CPF.java

27 No pacote br.com.k19.beanvalidators, crie uma classe chamada CPFBeanValidator para imple-


mentar o validador associado anotao @CPF. Essa classe deve implementar a interface javax.va-
lidation.ConstraintValidator.

1 package br . com . k19 . beanvalidators ;


2
3 import javax . validation . ConstraintValidator ;
4 import javax . validation . ConstraintValidatorContext ;
5
6 public class CPFBeanValidator implements
7 ConstraintValidator < CPF , br . com . k19 . modelo . CPF > {
8
9 @Override
10 public void initialize ( CPF constraintAnnotation ) {
11 }
12
13 @Override
14 public boolean isValid ( br . com . k19 . modelo . CPF cpf , ConstraintValidatorContext -
context ) {
15
16 int numeroDeIdentificacao = cpf . getNumeroDeIdentificacao () ;
17 int primeiroDigitoVerificador = cpf . getPrimeiroDigitoVerificador () ;
18 int segundoDigitoVerificador = cpf . getSegundoDigitoVerificador () ;
19
20 return this . validaCPF ( numeroDeIdentificacao , primeiroDigitoVerificador ,
21 segundoDigitoVerificador ) ;
22 }
23

www.facebook.com/k19treinamentos 189
C ONVERSO E VALIDAO 190

24 private boolean validaCPF ( int numeroDeIdentificacao ,


25 int primeiroDigitoVerificador , int segundoDigitoVerificador ) {
26
27 long primeiroDigito = this . modulo11 (( long ) numeroDeIdentificacao ) ;
28 long segundoDigito = this . modulo11 (( long ) numeroDeIdentificacao * 10
29 + primeiroDigito ) ;
30 return primeiroDigitoVerificador == primeiroDigito
31 && segundoDigitoVerificador == segundoDigito ;
32 }
33
34 private long modulo11 ( long numero ) {
35 long soma = 0;
36 long multiplicador = 2;
37 while ( numero > 0) {
38 long digito = numero % 10;
39 soma += multiplicador * digito ;
40 numero /= 10;
41 multiplicador ++;
42 }
43 long resto = soma % 11;
44 if ( resto < 2)
45 return 0;
46 else
47 return 11 - resto ;
48 }
49 }

Cdigo Java 10.32: CPFBeanValidator.java

28 Na classe CPFBean, adicione a anotao @CPF ao atributo cpf para usar o validador que voc
acabou de criar.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . CPF ;
4 import javax . faces . bean . ManagedBean ;
5
6 @ManagedBean
7 public class CPFBean {
8
9 @br . com . k19 . beanvalidators . CPF
10 private CPF cpf ;
11
12 // GETTER E SETTER
13 }

Cdigo Java 10.33: CPFBean.java

29 Modifique no arquivo formulario.xhtml a linha em destaque.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6 <h : head >
7 < title > K19 Treinamentos </ title >
8 </ h : head >
9
10 <h : body >
11 < h1 > Formulrio </ h1 >
12 <h : form >
13 <h : outputLabel value = " CPF : " for = " cpf " / >
14 <h : inputText id = " cpf " value = " #{ cPFBean . cpf } " / >

190 www.k19.com.br
191 C ONVERSO E VALIDAO

15 <h : commandButton value = " Enviar " / >


16 </ h : form >
17 <h : message for = " cpf " style = " color : red " / >
18 </ h : body >
19 </ html >

Cdigo XHTML 10.32: formulario.xhtml

30 Acesse a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/formulario.xhtml

www.facebook.com/k19treinamentos 191
C ONVERSO E VALIDAO 192

192 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 ocor-
rer. 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 ma-
naged 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 pro-
dutoBean 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.facebook.com/k19treinamentos 193
E VENTOS 194

1 <h : commandButton value = " Salva " action = " #{ produtoBean . salva } " / >

Cdigo XHTML 11.1: Boto associado ao mtodo salva() do managed bean produtoBean

1 @ManagedBean
2 public class ProdutoBean {
3 private Produto produto = new Produto () ;
4 private List < Produto > produtos = new ArrayList < Produto >() ;
5
6 public String salva () {
7 this . produtos . add ( this . produto ) ;
8 this . produto = new Produto () ;
9 return " lista - produtos " ;
10 }
11
12 // GETTERS E SETTERS
13 }

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 al-
tera 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 @ManagedBean
2 public class CliqueBean {
3 public void mudaTexto ( ActionEvent e ) {
4 UICommand c = ( UICommand ) e . getComponent () ;
5 c . setValue ( " Clicado " ) ;
6 }
7 }

Cdigo Java 11.2: CliqueBean.java

Os atributos action e actionListener permitem que no mximo dois mtodos sejam associa-
dos 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 <h : commandLink value = " Enviar " action = " ... " actionListener = " ... " >
2 <f : actionListener type = " br . com . k19 . MudaCorDaFonte " / >
3 </ h : commandLink >

Cdigo XHTML 11.3: Link associado ao mtodo processAction() da classe MudaCorDaFonte

1 package br . com . k19 ;


2
3 public class MudaCorDaFonte implements ActionListener {
4 @Override
5 public void processAction ( ActionEvent e ) {

194 www.k19.com.br
195 E VENTOS

6 UICommand c = ( UICommand ) e . getComponent () ;


7 c . getAttributes () . put ( " style " , " color : red ; " ) ;
8 }
9 }

Cdigo Java 11.3: MudaCorDaFonte.java

Nesse exemplo, usamos a tag <f:actionListener> para associar o link ao mtodo processActi-
on() 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 infor-
maes).

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 esta-
belecer 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 exem-
plo 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 <h : outputLabel value = " Preo : " for = " preco " / >
2 <h : inputText valueChangeListener = " #{ produtoBean . mudaPreco } " id = " preco " / >

Cdigo XHTML 11.4: Caixa de texto associada ao mtodo mudaPreco() do managed bean produtoBean

1 @ManagedBean
2 public class ProdutoBean {
3 public void mudaPreco ( ValueChangeEvent e ) {
4 System . out . println ( " Preo antigo : " + e . getOldValue () ) ;
5 System . out . println ( " Preo novo : " + e . getNewValue () ) ;
6 }
7 }

Cdigo Java 11.4: ProdutoBean.java

www.facebook.com/k19treinamentos 195
E VENTOS 196

O mesmo pode ser feito com o uso da tag <f:valueChangeListener>. No exemplo abaixo, cria-
mos uma classe chamada RegistraAlteracao, que implementa a interface ValueChangeListener,
e associamos a caixa de texto ao mtodo processValueChange() dessa classe.

1 <h : outputLabel value = " Preo : " for = " preco " / >
2 <h : inputText id = " preco " >
3 <f : valueChangeListener type = " br . com . k19 . RegistraAlteracao " / >
4 </ h : inputText >

Cdigo XHTML 11.5: Caixa de texto associada ao mtodo processValueChange() da classe RegistraAlteracao

1 package br . com . k19 ;


2
3 public class RegistraAlteracao implements ValueChangeListener {
4 @Override
5 public void processValueChange ( ValueChangeEvent e ) {
6 System . out . println ( " Preo antigo : " + e . getOldValue () ) ;
7 System . out . println ( " Preo novo : " + e . getNewValue () ) ;
8 }
9 }

Cdigo Java 11.5: RegistraAlteracao.java

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 apare-


cem 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 infor-
maes sobre o processamento de uma requisio.

Exerccios de Fixao

1 Crie um projeto chamado K19-Eventos seguindo os passos vistos no exerccio do Captulo 5.

2 Criaremos uma pgina com trs botes. Um dos botes estar habilitado e os outros dois desa-
bilitados. 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.

Adicione uma pgina chamada botoes.xhtml no projeto K19-Eventos com o seguinte contedo.

196 www.k19.com.br
197 E VENTOS

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 - Eventos </ title >
9 </ h : head >
10
11 <h : body >
12 <h : form >
13 <h : commandButton
14 id =" botao - jonas "
15 value = " Jonas "
16 disabled = " false "
17 actionListener = " #{ botaoBean . sorteiaBotao } " / >
18
19 <h : commandButton
20 id =" botao - marcelo "
21 value = " Marcelo "
22 disabled = " true "
23 actionListener = " #{ botaoBean . sorteiaBotao } " / >
24
25 <h : commandButton
26 id =" botao - rafael "
27 value = " Rafael "
28 disabled = " true "
29 actionListener = " #{ botaoBean . sorteiaBotao } " / >
30 </ h : form >
31 </ h : body >
32 </ html >

Cdigo XHTML 11.6: botoes.xhtml

3 Crie um managed bean para implementar o tratamento dos botes. Adicione em um pacote
chamado br.com.k19.controle uma classe com o nome BotaoBean e com o seguinte contedo.

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4 import javax . faces . component . UIComponent ;
5 import javax . faces . event . ActionEvent ;
6
7 @ManagedBean
8 public class BotaoBean {
9 public void sorteiaBotao ( ActionEvent event ) {
10 UIComponent formulario = event . getComponent () . getParent () ;
11
12 UIComponent botaoJonas = formulario . findComponent ( " botao - jonas " ) ;
13 UIComponent botaoMarcelo = formulario . findComponent ( " botao - marcelo " ) ;
14 UIComponent botaoRafael = formulario . findComponent ( " botao - rafael " ) ;
15
16 botaoJonas . getAttributes () . put ( " disabled " , true ) ;
17 botaoMarcelo . getAttributes () . put ( " disabled " , true ) ;
18 botaoRafael . getAttributes () . put ( " disabled " , true ) ;
19
20 double numero = Math . random () ;
21
22 if ( numero < 1.0/3.0) {
23 botaoJonas . getAttributes () . put ( " disabled " , false ) ;
24 } else if ( numero < 2.0/3.0) {
25 botaoMarcelo . getAttributes () . put ( " disabled " , false ) ;
26 } else {
27 botaoRafael . getAttributes () . put ( " disabled " , false ) ;
28 }

www.facebook.com/k19treinamentos 197
E VENTOS 198

29 }
30 }

Cdigo Java 11.6: BotaoBean.java

4 Remova o projeto K19-Conversao-e-Validacao do Glassfish e do Wildfly. Implante o projeto


K19-Eventos no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o
endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Eventos/botoes.xhtml

5 Implante o projeto K19-Eventos no Wildfly. Certifique-se que o Glassfish esteja parado. Inicie o
Wildfly e acesse o endereo abaixo para testar a aplicao.

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.fa-
ces.event.PhaseListener. Alm disso, precisamos registrar essa classe no arquivo faces-con-
fig.xml. A interface PhaseListener obriga a implementao de trs mtodos: afterPhase(), be-
forePhase() e getPhaseId().

O mtodo getPhaseId() deve devolver a referncia de um objeto do tipo javax.faces.eve-


nt.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 Pha-


seListener. No mtodo getPhaseId(), devolvemos PhaseId.ANY_PHASE, que indica que estamos
interessados nos eventos relacionados a todas as fases.

198 www.k19.com.br
199 E VENTOS

1 package br . com . k19 ;


2
3 public class MonitorPhaseListener implements PhaseListener {
4
5 @Override
6 public void afterPhase ( PhaseEvent event ) {
7 System . out . println ( " MonitorPhaseListener . afterPhase () " ) ;
8 System . out . println ( event . getPhaseId () ) ;
9 }
10
11 @Override
12 public void beforePhase ( PhaseEvent event ) {
13 System . out . println ( " MonitorPhaseListener . beforePhase () " ) ;
14 System . out . println ( event . getPhaseId () ) ;
15 }
16
17 @Override
18 public PhaseId getPhaseId () {
19 return PhaseId . ANY_PHASE ;
20 }
21 }

Cdigo Java 11.7: MonitorPhaseListener.java

No arquivo faces-config.xml, registramos essa classe da seguinte forma:

1 ...
2 < lifecycle >
3 < phase - listener > br . com . k19 . MonitorPhaseListener </ phase - listener >
4 </ lifecycle >
5 ...

Cdigo XML 11.1: faces-config.xml

Exerccios de Fixao

6 Crie uma classe chamada MonitorPhaseListener em um pacote chamado br.com.k19.phaselisteners


no projeto K19-Eventos.

1 package br . com . k19 . phaselisteners ;


2
3 import javax . faces . event . PhaseEvent ;
4 import javax . faces . event . PhaseId ;
5 import javax . faces . event . PhaseListener ;
6
7 public class MonitorPhaseListener implements PhaseListener {
8
9 @Override
10 public void afterPhase ( PhaseEvent event ) {
11 System . out . println ( " MonitorPhaseListener . afterPhase () - " + event . getPhaseId () ) ;
12 }
13
14 @Override
15 public void beforePhase ( PhaseEvent event ) {
16 System . out . println ( " MonitorPhaseListener . beforePhase () - " + event . getPhaseId () ) ;
17 }
18
19 @Override
20 public PhaseId getPhaseId () {
21 return PhaseId . ANY_PHASE ;
22 }

www.facebook.com/k19treinamentos 199
E VENTOS 200

23 }

Cdigo Java 11.8: MonitorPhaseListener.java

7 Registre a classe MonitorPhaseListener no arquivo faces-config.xml.

1 ...
2 < lifecycle >
3 < phase - listener > br . com . k19 . phaselisteners . MonitorPhaseListener </ phase - listener >
4 </ lifecycle >
5 ...

Cdigo XML 11.2: faces-config.xml

8 Acesse a pgina botoes.xhtml, clique nos botes e verifique as mensagens exibidas no Console .

SystemEvent

SystemEvents so similares aos PhaseEvents no sentido de que ambos esto relacionados a pon-
tos 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, res-
pectivamente.

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. Con-
sidere uma aplicao bancria que permite gerar extratos da conta corrente. Os dados de entrada so

200 www.k19.com.br
201 E VENTOS

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 valida-
Datas() do managed bean extratoBean deve ser chamado assim que o evento postValidate for
processado.

1 <h : form >


2 <f : event type = " postValidate " listener = " #{ extratoBean . validaDatas } " / >
3 <h : messages / >
4
5 <h : outputLabel value = " Data inicial : " for = " data - inicial " / >
6 <h : inputText value = " #{ extratoBean . dataInicial } " id = " data - inicial " required = " true " >
7 <f : convertDateTime pattern = " dd / MM / yyyy " / >
8 </ h : inputText >
9
10 <h : outputLabel value = " Data final : " for = " data - final " / >
11 <h : inputText value = " #{ extratoBean . dataFinal } " id = " data - final " required = " true " >
12 <f : convertDateTime pattern = " dd / MM / yyyy " / >
13 </ h : inputText >
14
15 <h : commandButton value = " Ver extrato " action = " #{ extratoBean . geraExtrato } " / >
16 </ h : form >

Cdigo XHTML 11.7: 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, adiciona-
mos 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 package managedbeans ;
2
3 @ManagedBean
4 public class ExtratoBean {
5
6 private Date dataInicial ;
7 private Date dataFinal ;
8
9 public void validaDatas ( ComponentSystemEvent event ) {
10
11 UIComponent source = event . getComponent () ;
12 UIInput dataInicialInput = ( UIInput ) source . findComponent ( " data - inicial " ) ;
13 UIInput dataFinalInput = ( UIInput ) source . findComponent ( " data - final " ) ;
14
15 if ( dataInicialInput . isValid () && dataFinalInput . isValid () ) {
16
17 Date dataInicialEscolhida = ( Date ) dataInicialInput . getLocalValue () ;
18 Date dataFinalEscolhida = ( Date ) dataFinalInput . getLocalValue () ;
19
20 if ( dataFinalEscolhida . before ( dataInicialEscolhida ) ) {
21 FacesMessage message =
22 new FacesMessage ( " A data final no pode vir antes da data inicial " ) ;
23 message . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
24 FacesContext context = FacesContext . getCurrentInstance () ;
25 context . addMessage ( source . getClientId () , message ) ;
26 context . renderResponse () ;
27 }
28 }

www.facebook.com/k19treinamentos 201
E VENTOS 202

29 }
30
31 public void geraExtrato () {
32 FacesMessage message = new FacesMessage ( " extrato gerado com sucesso " ) ;
33 message . setSeverity ( FacesMessage . SEVERITY_INFO ) ;
34 FacesContext context = FacesContext . getCurrentInstance () ;
35 context . addMessage ( null , message ) ;
36 }
37
38 // GETTERS E SETTERS
39 }

Cdigo Java 11.9: ExtratoBean.java

Exerccios de Fixao

9 Adicione uma pgina chamada extrato.xhtml no projeto K19-Eventos com o seguinte contedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets "
6 xmlns : h = " http :// java . sun . com / jsf / html "
7 xmlns : f = " http :// java . sun . com / jsf / core " >
8
9 <h : head >
10 < title > K19 - Eventos </ title >
11 </ h : head >
12
13 <h : body >
14 <h : form >
15 <f : event type = " postValidate " listener = " #{ extratoBean . validaDatas } " / >
16 <h : messages / >
17 <h : outputLabel value = " Data inicial : " for = " data - inicial " / >
18 <h : inputText
19 value = " #{ extratoBean . dataInicial } "
20 id =" data - inicial "
21 required = " true " >
22 <f : convertDateTime pattern = " dd / MM / yyyy " / >
23 </ h : inputText >
24
25 <h : outputLabel value = " Data final : " for = " data - final " / >
26 <h : inputText
27 value = " #{ extratoBean . dataFinal } "
28 id =" data - final "
29 required = " true " >
30 <f : convertDateTime pattern = " dd / MM / yyyy " / >
31 </ h : inputText >
32
33 <h : commandButton value = " Ver extrato " action = " #{ extratoBean . geraExtrato } " / >
34 </ h : form >
35 </ h : body >
36 </ html >

Cdigo XHTML 11.8: extrato.xhtml

10 Crie uma classe chamada ExtratoBean no pacote br.com.k19.controle com o seguinte con-
tedo:

202 www.k19.com.br
203 E VENTOS

1 package br . com . k19 . controle ;


2
3 import java . util . Date ;
4 import javax . faces . application . FacesMessage ;
5 import javax . faces . bean . ManagedBean ;
6 import javax . faces . component . UIComponent ;
7 import javax . faces . component . UIInput ;
8 import javax . faces . context . FacesContext ;
9 import javax . faces . event . ComponentSystemEvent ;
10
11 @ManagedBean
12 public class ExtratoBean {
13
14 private Date dataInicial ;
15 private Date dataFinal ;
16
17 public void validaDatas ( ComponentSystemEvent event ) {
18
19 UIComponent source = event . getComponent () ;
20 UIInput dataInicialInput = ( UIInput ) source . findComponent ( " data - inicial " ) ;
21 UIInput dataFinalInput = ( UIInput ) source . findComponent ( " data - final " ) ;
22
23 if ( dataInicialInput . isValid () && dataFinalInput . isValid () ) {
24
25 Date dataInicialEscolhida = ( Date ) dataInicialInput . getLocalValue () ;
26 Date dataFinalEscolhida = ( Date ) dataFinalInput . getLocalValue () ;
27
28 if ( dataFinalEscolhida . before ( dataInicialEscolhida ) ) {
29 FacesMessage message =
30 new FacesMessage ( " A data final no pode vir antes da data inicial " ) ;
31 message . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
32 FacesContext context = FacesContext . getCurrentInstance () ;
33 context . addMessage ( source . getClientId () , message ) ;
34 context . renderResponse () ;
35 }
36 }
37 }
38
39 public void geraExtrato () {
40 FacesMessage message = new FacesMessage ( " extrato gerado com sucesso " ) ;
41 message . setSeverity ( FacesMessage . SEVERITY_INFO ) ;
42 FacesContext context = FacesContext . getCurrentInstance () ;
43 context . addMessage ( null , message ) ;
44 }
45
46 // GETTERS E SETTERS
47 }

Cdigo Java 11.10: ExtratoBean.java

11 Acesse a pgina extrato.xhtml e teste a validao das datas.

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:com-


mandButton> ou <h:commandLink> so disparados no final da fase Invoke Application do proces-
samento de uma requisio.

www.facebook.com/k19treinamentos 203
E VENTOS 204

Porm, esse comportamento pode ser alterado atravs do atributo immediate desses componen-
tes. Se o valor do atributo immediate de um componente de entrada for true, ento a converso e va-
lidao 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 obriga-
trios. 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.

12 Crie um pacote chamado br.com.k19.modelo no projeto K19-Eventos.

13 No pacote br.com.k19.modelo, 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.

1 package br . com . k19 . modelo ;


2
3 import java . util . ArrayList ;
4 import java . util . List ;
5
6 public class Estado {
7 private String nome ;
8 private String sigla ;
9 private List < String > cidades = new ArrayList < String >() ;
10
11 // GETTERS E SETTERS
12 }

Cdigo Java 11.11: Estado.java

14 No pacote br.com.k19.controle, 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.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Estado ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . bean . SessionScoped ;
8 import javax . faces . event . ValueChangeEvent ;
9
10 @ManagedBean
11 @SessionScoped
12 public class CadastroBean {
13

204 www.k19.com.br
205 E VENTOS

14 private String nome ;


15 private String cidade ;
16 private String siglaDoEstadoEscolhido ;
17
18 private Estado estadoSelecionado = new Estado () ;
19 private List < Estado > estados = new ArrayList < Estado >() ;
20
21 public CadastroBean () {
22 Estado sp = new Estado () ;
23 sp . setSigla ( " SP " ) ;
24 sp . setNome ( " So Paulo " ) ;
25 sp . getCidades () . add ( " So Paulo " ) ;
26 sp . getCidades () . add ( " Campinas " ) ;
27
28 Estado rj = new Estado () ;
29 rj . setSigla ( " RJ " ) ;
30 rj . setNome ( " Rio de Janeiro " ) ;
31 rj . getCidades () . add ( " Rio de Janeiro " ) ;
32 rj . getCidades () . add ( " Niteri " ) ;
33
34 Estado rn = new Estado () ;
35 rn . setSigla ( " RN " ) ;
36 rn . setNome ( " Rio Grande do Norte " ) ;
37 rn . getCidades () . add ( " Natal " ) ;
38 rn . getCidades () . add ( " Mossor " ) ;
39
40 this . estados . add ( sp ) ;
41 this . estados . add ( rj ) ;
42 this . estados . add ( rn ) ;
43 }
44
45 public void mudaEstado ( ValueChangeEvent event ) {
46 this . siglaDoEstadoEscolhido = event . getNewValue () . toString () ;
47 for ( Estado e : this . estados ) {
48 if ( e . getSigla () . equals ( this . siglaDoEstadoEscolhido ) ) {
49 this . estadoSelecionado = e ;
50 break ;
51 }
52 }
53 }
54
55 // GETTERS E SETTERS
56 }

Cdigo Java 11.12: CadastroBean.java

15 Adicione uma pgina chamada cadastro.xhtml no projeto K19-Eventos com o seguinte con-
tedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Cadastro </ h1 >
13 <h : form >
14 <h : panelGrid columns = " 3 " >
15
16 <h : outputLabel value = " Nome : " for = " nome " / >
17 <h : inputText value = " #{ cadastroBean . nome } " required = " true " id = " nome " / >
18 <h : message for = " nome " / >

www.facebook.com/k19treinamentos 205
E VENTOS 206

19
20 <h : outputLabel value = " Estado : " for = " estado " / >
21 <h : selectOneMenu id = " estado "
22 value = " #{ cadastroBean . siglaDoEstadoEscolhido } "
23 valueChangeListener = " #{ cadastroBean . mudaEstado } "
24 onchange = " this . form . submit () ; "
25 required = " true " >
26
27 <f : selectItem itemLabel = " Escolha um estado " noSelectionOption = " true " / >
28 <f : selectItems
29 value = " #{ cadastroBean . estados } "
30 var = " estado "
31 itemLabel = " #{ estado . nome } "
32 itemValue = " #{ estado . sigla } " / >
33
34 </ h: selectOneMenu >
35 <h : message for = " estado " / >
36
37 <h : outputLabel value = " Cidade : " for = " cidade " / >
38 <h : selectOneMenu id = " cidade " value = " #{ cadastroBean . cidade } " required = " true " >
39 <f : selectItem itemLabel = " Escolha uma cidade " noSelectionOption = " true " / >
40 <f : selectItems value = " #{ cadastroBean . estadoSelecionado . cidades } " / >
41 </ h: selectOneMenu >
42 <h : message for = " cidade " / >
43
44 </ h : panelGrid >
45 <h : commandButton value = " Cadastrar " / >
46 </ h : form >
47 </ h : body >
48 </ html >

Cdigo XHTML 11.9: cadastro.xhtml

Para que a lista de cidades seja atualizada assim que o usurio selecionar um novo estado, usa-
mos os atributos onchange e valueChangeListener do componente <h:selectOneMenu>. Defini-
mos o valor do atributo onchange como sendo "this.form.submit();", o que significa que o formul-
rio ser submetido toda vez que um novo estado for selecionado. Alm disso, o atributo valueChan-
geListener 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.

16 Acesse a aplicao no endereo:

http://localhost:8080/K19-Eventos/cadastro.xhtml

Note que, quando selecionamos um estado, o formulrio submetido automaticamente e os


dados de todos os campos so convertidos e validados.

17 Para atualizar a lista de cidades, precisamos que o dado presente na caixa de seleo de estado
passe pelas etapas de converso e validao. Por outro lado, queremos evitar que os demais campos
sejam convertidos e validados, bem como evitar que o cadastro seja efetivado sem que o usurio
tenha submetido o formulrio.

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:selectOneMe-

206 www.k19.com.br
207 E VENTOS

nu>. O fluxo do processamento da requisio pode ser desviado para a fase Render Response se cha-
marmos o mtodo renderResponse() da instncia da classe FacesContext logo aps atualizarmos o
valor do atributo estadoSelecionado do managed bean cadastroBean.

1 ...
2 <h : selectOneMenu id = " estado "
3 value = " #{ cadastroBean . siglaDoEstadoEscolhido } "
4 valueChangeListener = " #{ cadastroBean . mudaEstado } "
5 onchange = " this . form . submit () ; "
6 required = " true "
7 immediate = " true " >
8
9 <f : selectItem itemLabel = " Escolha um estado " noSelectionOption = " true " / >
10 <f : selectItems value = " #{ cadastroBean . estados } " var = " estado "
11 itemLabel = " #{ estado . nome } " itemValue = " #{ estado . sigla } " / >
12 </ h : selectOneMenu >
13 ...

Cdigo XHTML 11.10: cadastro.xhtml

1 ...
2 public void mudaEstado ( ValueChangeEvent event ) {
3 this . siglaDoEstadoEscolhido = event . getNewValue () . toString () ;
4 for ( Estado e : this . estados ) {
5 if ( e. getSigla () . equals ( this . siglaDoEstadoEscolhido ) ) {
6 this . estadoSelecionado = e ;
7 break ;
8 }
9 }
10 FacesContext . getCurrentInstance () . renderResponse () ;
11 }
12 ...

Cdigo Java 11.13: CadastroBean.java

No esquea de importar a classe FacesContext.

www.facebook.com/k19treinamentos 207
E VENTOS 208

208 www.k19.com.br
CAPTULO
A JAX
12
Quando as aplicaes possuem telas complexas, com grande quantidade de contedo, no
interessante recarregar uma pgina inteira s para modificar uma pequena parte da tela.

Com o intuito de melhorar a interatividade entre as aplicaes e os usurios, podemos aplicar o


conceito do AJAX (Asynchronous Javascript And XML). Aplicando esse conceito, obtemos duas ca-
pacidades muito uteis. A primeira a possibilidade de atualizar trechos de uma pgina ao invs da
pgina inteira. A segunda poder realizar requisies sem interromper a navegao dos usurios.

Por exemplo, considere uma aplicao web para a visualizao de fotos. As fotos so exibidas
individualmente em uma tela que tambm apresenta outros contedos. Os usurios podem, atravs
do link Prxima, avanar para a prxima foto, ou voltar para a foto anterior atravs do link Ante-
rior. Quando o usurio decide visualizar a prxima foto ou a anterior, no necessrio recarregar a
pgina inteira, j que o nico contedo alterado da pgina a foto.

Outro exemplo, considere uma aplicao de mensagens instantneas (GTalk, MSN, . . . ). A lista-
gem de contatos de um usurio pode ser atualizada frequentemente sem que ele tenha que pressio-
nar qualquer boto ou link, sem que a pgina tenha de ser recarregada e sem interromper a navega-
o do usurio.

A verso 2 do JSF, diferentemente das anteriores, oferece suporte nativo a AJAX. Neste captulo,
veremos como utilizar esse suporte.

Fazendo requisies AJAX

As requisies AJAX so realizadas quando determinados eventos ocorrem. Esses eventos esto
fortemente relacionados aos componentes visuais adicionados s pginas. Devemos indicar para o
JSF quais componentes e eventos devem realizar requisies AJAX. Para fazer isso, utilizamos a tag
<f:ajax>.

1 <h : inputText >


2 <f : ajax / >
3 </ h : inputText >

Cdigo XHTML 12.1: Aplicando a tag <f:ajax>

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 <h : inputText >

www.facebook.com/k19treinamentos 209
A JAX 210

2 <f : ajax event = " keyup " / >


3 </ 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, pode-
mos agrup-los atravs da tag <f:ajax>.

1 <f : ajax >


2 <h : inputText / >
3 <h : inputSecret / >
4 <h : commandButton value = " OK " / >
5 </ f : ajax >

Cdigo XHTML 12.3: Aplicando a tag <f:ajax> a vrios componentes

Novamente, se no escolhermos explicitamente o evento que vai disparar as requisies AJAX, o


JSF assumir o evento padro de cada componente. O padro dos componentes <h:inputText> e
<h:inputSecret> onchange. J o padro do componente <h:commandButton> onclick.

Podemos explicitar o evento que deve disparar as requisies AJAX para um determinado grupo
de componentes da mesma forma como fizemos anteriormente.

1 <f : ajax event = " mouseout " >


2 <h : inputText / >
3 <h : inputSecret / >
4 <h : commandButton value = " OK " / >
5 </ f : ajax >

Cdigo XHTML 12.4: Definindo o tipo de evento que deve disparar requisies AJAX

Processando uma parte especfica da tela

Quando uma requisio AJAX feita, podemos determinar quais componentes da tela devem
ser avaliados pelo JSF. Por exemplo, quando enviamos um formulrio, talvez seja necessrio avaliar
apenas os componentes que esto no prprio formulrio.

Podemos definir quais componentes devem ser avaliados no servidor atravs do atributo exe-
cute da tag <f:ajax>. O valor desse atributo deve ser uma lista contendo os identificadores dos
componentes que precisam ser avaliados no servidor. Quando um componente avaliado, todos os
componentes definidos em seu corpo tambm sero avaliados.

1 <h : form id = " formulario - login " >


2 <h : inputText / >
3
4 <h : inputSecret / >
5
6 <h : commandButton value = " Enviar " >
7 <f : ajax event = " click " execute = " formulario - login " / >
8 </ h : commandButton >
9 </ h : form >

Cdigo XHTML 12.5: Definindo quais componentes sero avaliados

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.

210 www.k19.com.br
211 A JAX

Recarregando parte da tela

Podemos definir quais componentes devem ser atualizados quando a resposta de uma requisio
AJAX chega no navegador. Para isso, devemos utilizar o atributo render da tag <f:ajax>. O valor
desse atributo deve ser uma lista contendo os identificadores dos componentes que precisam ser
atualizados quando a resposta de uma requisio AJAX chegar no navegador.

1 <h : commandButton value = " Gera Nmero " >


2 <f : ajax event = " click " render = " numero " / >
3 </ h : commandButton >
4 <h : outputText id = " numero " value = " #{ geradorDeNumeroBean . numero } " / >

Cdigo XHTML 12.6: Definindo quais componentes sero atualizados

No exemplo acima, uma requisio AJAX realizada quando o boto Gera Nmero pressio-
nado. Quando a resposta dessa requisio chega no navegador, apenas o componente <h:output-
Text> com o identificador numero ser atualizado. J no cdigo abaixo, dois componentes <h:out-
putText> so atualizados. Mais especificamente, os componentes com os identificadores numero1 e
numero2 so atualizados.

1 <h : commandButton value = " Gera Nmeros " >


2 <f : ajax event = " click " render = " numero1 numero2 " / >
3 </ h : commandButton >
4 <h : outputText id = " numero1 " value = " #{ geradorDeNumeroBean . numero } " / >
5 <h : outputText id = " numero2 " value = " #{ geradorDeNumeroBean . numero } " / >

Cdigo XHTML 12.7: Definindo dois componentes para serem atualizados

Associando um procedimento a uma requisio AJAX

Podemos associar um mtodo a uma requisio AJAX. Esse mtodo ser executado durante o
processamento dessa requisio no servidor. Mais especificamente, ele ser executado na fase In-
voke Application. Essa associao realizada atravs do atributo listener da tag <f:ajax>.

1 <h : commandButton value = " Salva " >


2 <f : ajax
3 event = " click "
4 execute = " formulario "
5 render = " formulario "
6 listener = " #{ produtoBean . salva } " / >
7 </ h : commandButton >

Cdigo XHTML 12.8: Definindo quais componentes sero atualizados

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

www.facebook.com/k19treinamentos 211
A JAX 212

palavras chaves associadas a grupos especiais de componentes.

@all refere-se a todos os componentes da tela.

@none refere-se a nenhum componente.

@this refere-se ao componente que disparou a requisio AJAX.

@form refere-se aos componentes do formulrio que contm o componente que disparou a requi-
sio AJAX.

Podemos alterar o cdigo do formulrio anterior para utilizar a palavra especial @form no lugar
do identificador do formulrio.

1 <h : form id = " formulario - login " >


2 <h : inputText / >
3
4 <h : inputSecret / >
5
6 <h : commandButton value = " Enviar " >
7 <f : ajax event = " click " execute = " @form " / >
8 </ h : commandButton >
9 </ h : form >

Cdigo XHTML 12.9: Utilizando a palavra especial @form

Exerccios de Fixao

1 Crie um projeto chamado K19-Ajax seguindo os passos vistos no exerccio do Captulo 5.

2 Criaremos um formulrio com a validao dos campos realizadas com AJAX. Crie um arquivo
chamado formulario.xhtml com o seguinte contedo:

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 - Ajax </ title >
10 </ h : head >
11
12 <h : body >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15 <h : inputText id = " caixa " >
16 <f : ajax event = " keyup " execute = " caixa " render = " mensagem " / >
17 <f : validateLength minimum = " 5 " maximum = " 10 " / >
18 </ h: inputText >
19
20 <h : message id = " mensagem " for = " caixa " style = " color : red " / >
21
22 <h : commandButton value = " Enviar " / >

212 www.k19.com.br
213 A JAX

23 </ h : panelGrid >


24 </ h : form >
25 </ h : body >
26 </ html >

Cdigo XHTML 12.10: formulario.xhtml

3 Remova o projeto K19-Eventos do Glassfish e do Wildfly. Implante o projeto K19-Ajax no Glas-


sfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o endereo abaixo para
testar a aplicao.

http://localhost:8080/K19-Ajax/formulario.xhtml

Observe a validao ocorrendo ao preenchimento do formulrio.

4 Implante o projeto K19-Ajax no Wildfly. Certifique-se que o Glassfish esteja parado. Inicie o
Wildfly e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Ajax/formulario.xhtml

Observe a validao ocorrendo ao preenchimento do formulrio.

www.facebook.com/k19treinamentos 213
A JAX 214

214 www.k19.com.br
CAPTULO
I NTEGRAO JSF E JPA
13
Como vimos nos primeiros captulos, os SGDBs so utilizados para armazenar os dados mani-
pulados 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 aplica-
o 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 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence
3 version = " 2.1 "
4 xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
5 xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "

www.facebook.com/k19treinamentos 215
I NTEGRAO JSF E JPA 216

6 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence


7 http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd " >
8
9 < persistence - unit name = " K19 - PU " transaction - type = " RESOURCE_LOCAL " >
10 < provider > org . hibernate . ejb . HibernatePersistence </ provider >
11 < properties >
12 < property
13 name = " hibernate . dialect "
14 value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
15
16 < property
17 name = " hibernate . hbm2ddl . auto "
18 value = " update " / >
19
20 < property
21 name = " javax . persistence . jdbc . driver "
22 value = " com . mysql . jdbc . Driver " / >
23
24 < property
25 name = " javax . persistence . jdbc . user "
26 value = " root " / >
27
28 < property
29 name = " javax . persistence . jdbc . password "
30 value = " root " / >
31
32 < property
33 name = " javax . persistence . jdbc . url "
34 value = " jdbc:mysql: // localhost:3306 / K19 - DB " / >
35 </ properties >
36 </ persistence - unit >
37 </ 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 @Entity
2 public class Produto {
3 @Id @GeneratedValue
4 private Long id ;
5
6 private String nome ;
7
8 private Double preco ;
9
10 // GETTERS e SETTERS
11 }

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.

216 www.k19.com.br
217 I NTEGRAO JSF E JPA

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 im-
plantada 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 imple-
mente a interface javax.servlet.Filter.

1 @WebFilter ( servletNames ={ " Faces Servlet " })


2 public class JPAFilter implements Filter {
3
4 private EntityManagerFactory factory ;
5
6 @Override
7 public void init ( FilterConfig filterConfig ) throws ServletException {
8 this . factory = Persistence . createEntityManagerFactory ( " K19 - PU " ) ;
9 }
10
11 @Override
12 public void destroy () {
13 this . factory . close () ;
14 }
15
16 @Override
17 public void doFilter ( ServletRequest request , ServletResponse response ,
18 FilterChain chain ) throws IOException , ServletException {
19
20 // por enquanto vazio
21 }
22 }

Cdigo Java 13.2: JPAFilter.java

Um filtro pode ser registrado no Web Container atravs da anotao @WebFilter. Com essa ano-
tao, 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 automatica-
mente para desativar o filtro no encerramento da aplicao. No exemplo acima, finalizamos a uni-
dade 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 persis-
tncia pode tambm gerenciar a abertura e a confirmao das transaes da aplicao. Para isso,
utilizaremos o mtodo doFilter() desse filtro.

1 @WebFilter ( servletNames ={ " Faces Servlet " })


2 public class JPAFilter implements Filter {
3
4 private EntityManagerFactory factory ;
5

www.facebook.com/k19treinamentos 217
I NTEGRAO JSF E JPA 218

6 @Override
7 public void init ( FilterConfig filterConfig ) throws ServletException {
8 this . factory = Persistence . createEntityManagerFactory ( " K19 - PU " ) ;
9 }
10
11 @Override
12 public void destroy () {
13 this . factory . close () ;
14 }
15
16 @Override
17 public void doFilter ( ServletRequest request , ServletResponse response ,
18 FilterChain chain ) throws IOException , ServletException {
19
20 // CHEGADA
21 EntityManager manager = this . factory . createEntityManager () ;
22 request . setAttribute ( " EntityManager " , manager ) ;
23 entityManager . getTransaction () . begin () ;
24 // CHEGADA
25
26 // FACES SERVLET
27 chain . doFilter ( request , response ) ;
28 // FACES SERVLET
29
30 // SADA
31 try {
32 entityManager . getTransaction () . commit () ;
33 } catch ( Exception e ) {
34 entityManager . getTransaction () . rollback () ;
35 } finally {
36 entityManager . close () ;
37 }
38 // SADA
39 }
40 }

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 Ser-
vlet 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.

Recuperando o EntityManager da Requisio

O EntityManager armazenado dentro da requisio pelo filtro pode ser recuperado a qualquer
momento durante o processamento da requisio. Veja o cdigo abaixo.

1 FacesContext fc = FacesContext . getCurrentInstance () ;


2 ExternalContext ec = fc . getExternalContext () ;
3 HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
4 EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;

Cdigo Java 13.4: Recuperando o EntityManager da requisio

O EntityManager ser utilizado pela aplicao para realizar as operaes de persistncia.

218 www.k19.com.br
219 I NTEGRAO JSF E JPA

Exerccios de Fixao

1 Entre na pasta K19-Arquivos/mysql-connector-java-VERSAO da rea de Trabalho e copie o


arquivo mysql-connector-java-VERSAO-bin.jar para pasta glassfish4/glassfish/lib tambm da sua
rea de Trabalho. OBS: O Glassfish deve ser reiniciado para reconhecer o driver JDBC do MySQL.

Importante
Voc pode obter o arquivo mysql-connector-java-VERSAO-bin.jar no site da K19:
www.k19.com.br/arquivos

2 Crie um projeto chamado K19-Integracao-JSF-JPA seguindo os passos vistos no exerccio do


Captulo 5.

3 Adicione uma pasta chamada META-INF no classpath do projeto K19-Integracao-JSF-JPA. A


pasta META-INF deve ser salva na pasta src.

4 Configure o JPA adicionando o arquivo persistence.xml na pasta META-INF.

1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence
3 version = " 2.1 "
4 xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
5 xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
6 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
7 http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd " >
8
9 < persistence - unit name = " K19 - PU " transaction - type = " RESOURCE_LOCAL " >
10 < provider > org . hibernate . ejb . HibernatePersistence </ provider >
11 < properties >
12 < property
13 name = " hibernate . dialect "
14 value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
15
16 < property
17 name = " hibernate . hbm2ddl . auto "
18 value = " update " / >
19
20 < property
21 name = " javax . persistence . jdbc . driver "
22 value = " com . mysql . jdbc . Driver " / >
23
24 < property
25 name = " javax . persistence . jdbc . user "
26 value = " root " / >
27
28 < property
29 name = " javax . persistence . jdbc . password "
30 value = " root " / >
31
32 < property
33 name = " javax . persistence . jdbc . url "
34 value = " jdbc:mysql: // localhost:3306 / K19 - DB " / >
35 </ properties >
36 </ persistence - unit >

www.facebook.com/k19treinamentos 219
I NTEGRAO JSF E JPA 220

37 </ persistence >

Cdigo XML 13.2: persistence.xml

5 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.

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 - DB ;


Query OK , 0 rows affected , 1 warning (0.00 sec )

mysql > CREATE DATABASE K19 - DB ;


Query OK , 1 row affected (0.02 sec )

6 Crie um pacote chamado br.com.k19.filters no projeto K19-Integracao-JSF-JPA.

7 No pacote br.com.k19.filters, crie uma classe chamada JPAFilter com o seguinte contedo:

1 package br . com . k19 . filters ;


2
3 import java . io . IOException ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . EntityManagerFactory ;
6 import javax . persistence . Persistence ;
7 import javax . servlet . Filter ;
8 import javax . servlet . FilterChain ;
9 import javax . servlet . FilterConfig ;
10 import javax . servlet . ServletException ;
11 import javax . servlet . ServletRequest ;
12 import javax . servlet . ServletResponse ;
13 import javax . servlet . annotation . WebFilter ;
14
15 @WebFilter ( servletNames ={ " Faces Servlet " })
16 public class JPAFilter implements Filter {
17
18 private EntityManagerFactory factory ;
19
20 @Override
21 public void init ( FilterConfig filterConfig ) throws ServletException {
22 this . factory = Persistence . createEntityManagerFactory ( " K19 - PU " ) ;
23 }
24
25 @Override
26 public void destroy () {
27 this . factory . close () ;
28 }
29
30 @Override
31 public void doFilter ( ServletRequest request , ServletResponse response ,
32 FilterChain chain ) throws IOException , ServletException {
33
34 // CHEGADA
35 EntityManager manager = this . factory . createEntityManager () ;
36 request . setAttribute ( " EntityManager " , manager ) ;

220 www.k19.com.br
221 I NTEGRAO JSF E JPA

37 manager . getTransaction () . begin () ;


38 // CHEGADA
39
40 // FACES SERVLET
41 chain . doFilter ( request , response ) ;
42 // FACES SERVLET
43
44 // SADA
45 try {
46 manager . getTransaction () . commit () ;
47 } catch ( Exception e ) {
48 manager . getTransaction () . rollback () ;
49 } finally {
50 manager . close () ;
51 }
52 // SADA
53 }
54 }

Cdigo Java 13.5: JPAFilter.java

8 Crie um pacote chamado br.com.k19.modelo no projeto K19-Integracao-JSF-JPA.

9 No pacote br.com.k19.modelo, crie uma classe chamada Carro com o seguinte contedo:

1 package br . com . k19 . modelo ;


2
3 import java . io . Serializable ;
4 import javax . persistence . Entity ;
5 import javax . persistence . GeneratedValue ;
6 import javax . persistence . Id ;
7
8 @Entity
9 public class Carro implements Serializable {
10
11 @Id @GeneratedValue
12 private Long id ;
13 private String marca ;
14 private String modelo ;
15
16 // GETTERS E SETTERS
17 }

Cdigo Java 13.6: Carro.java

10 No pacote br.com.k19.modelo, crie uma classe chamada CarroRepository com o seguinte con-
tedo:

1 package br . com . k19 . modelo ;


2
3 import java . util . List ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . Query ;
6
7 public class CarroRepository {
8
9 private EntityManager manager ;
10
11 public CarroRepository ( EntityManager manager ) {
12 this . manager = manager ;
13 }
14

www.facebook.com/k19treinamentos 221
I NTEGRAO JSF E JPA 222

15 public void adiciona ( Carro carro ) {


16 this . manager . persist ( carro ) ;
17 }
18
19 public List < Carro > buscaTodos () {
20 Query query = this . manager . createQuery ( " select x from Carro x " ) ;
21 return query . getResultList () ;
22 }
23 }

Cdigo Java 13.7: CarroRepository.java

11 Crie um pacote chamado br.com.k19.controle no projeto K19-Integracao-JSF-JPA.

12 No pacote br.com.k19.controle, crie uma classe chamada CarroBean com o seguinte cdigo:

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Carro ;
4 import br . com . k19 . modelo . CarroRepository ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . context . ExternalContext ;
8 import javax . faces . context . FacesContext ;
9 import javax . persistence . EntityManager ;
10 import javax . servlet . http . HttpServletRequest ;
11
12 @ManagedBean
13 public class CarroBean {
14
15 private Carro carro = new Carro () ;
16
17 public void adicionaCarro () {
18 EntityManager manager = this . getEntityManager () ;
19 CarroRepository repository = new CarroRepository ( manager ) ;
20
21 repository . adiciona ( this . carro ) ;
22 this . carro = new Carro () ;
23 }
24
25 public List < Carro > getCarros () {
26 EntityManager manager = this . getEntityManager () ;
27 CarroRepository repository = new CarroRepository ( manager ) ;
28 return repository . buscaTodos () ;
29 }
30
31 private EntityManager getEntityManager () {
32 FacesContext fc = FacesContext . getCurrentInstance () ;
33 ExternalContext ec = fc . getExternalContext () ;
34 HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
35 EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
36
37 return manager ;
38 }
39 // GETTERS E SETTERS
40 }

Cdigo Java 13.8: CarroBean.java

13 Crie uma pgina chamada carros.xhtml no projeto K19-Integracao-JSF-JPA com o seguinte


contedo:

222 www.k19.com.br
223 I NTEGRAO JSF E JPA

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12 <h : body >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15 <h : outputLabel value = " Marca : " for = " campo - marca " / >
16 <h : inputText value = " #{ carroBean . carro . marca } " id = " campo - marca " / >
17
18 <h : outputLabel value = " Modelo : " for = " campo - modelo " / >
19 <h : inputText value = " #{ carroBean . carro . modelo } " id = " campo - modelo " / >
20
21 <h : commandButton value = " Adicionar " action = " #{ carroBean . adicionaCarro } " / >
22 </ h : panelGrid >
23 </ h : form >
24 </ h : body >
25 </ html >

Cdigo XHTML 13.1: carros.xhtml

14 No arquivo carros.xhtml, adicione tambm um trecho de cdigo para exibir os carros adiciona-
dos.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12 <h : body >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15 <h : outputLabel value = " Marca : " for = " campo - marca " / >
16 <h : inputText value = " #{ carroBean . carro . marca } " id = " campo - marca " / >
17
18 <h : outputLabel value = " Modelo : " for = " campo - modelo " / >
19 <h : inputText value = " #{ carroBean . carro . modelo } " id = " campo - modelo " / >
20
21 <h : commandButton value = " Adicionar " action = " #{ carroBean . adicionaCarro } " / >
22 </ h : panelGrid >
23 </ h : form >
24
25 <h : panelGroup rendered = " #{ not empty carroBean . carros } " >
26 < h1 > Lista de carros : </ h1 >
27 < ul >
28 < ui : repeat value = " #{ carroBean . carros } " var = " carro " >
29 < li > <h : outputText value = " #{ carro . marca } #{ carro . modelo } " / > </ li >
30 </ ui : repeat >
31 </ ul >
32 </ h : panelGroup >
33 </ h : body >
34 </ html >

www.facebook.com/k19treinamentos 223
I NTEGRAO JSF E JPA 224

Cdigo XHTML 13.2: carros.xhtml

15 Remova o projeto K19-Ajax do Glassfish e do Wildfly. Implante o projeto K19-Integracao-JSF-

JPA no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o Glassfish e acesse o endereo
abaixo para testar a aplicao.

http://localhost:8080/K19-Integracao-JSF-JPA/carros.xhtml

Adicione alguns carros e verifique se eles foram adicionados no banco de dados.

Otimizando o nmero de consultas ao SGDB

Durante o processamento de uma requisio, os mtodos getters so chamados pelo JSF. A quan-
tidade 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 lista-
gem 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 @ManagedBean
2 public class CarroBean {
3
4 private Carro carro = new Carro () ;
5 private List < Carro > carros ;
6
7 public void adicionaCarro () {
8 EntityManager manager = this . getEntityManager () ;
9 CarroRepository repository = new CarroRepository ( manager ) ;
10
11 repository . adiciona ( this . carro ) ;
12 this . carro = new Carro () ;
13 this . carros = null ;
14 }
15
16 public List < Carro > getCarros () {
17 if ( this . carros == null ) {
18 EntityManager manager = this . getEntityManager () ;
19 CarroRepository repository = new CarroRepository ( manager ) ;
20 this . carros = repository . buscaTodos () ;
21 }
22
23 return this . carros ;
24 }
25
26 private EntityManager getEntityManager () {
27 FacesContext fc = FacesContext . getCurrentInstance () ;
28 ExternalContext ec = fc . getExternalContext () ;
29 HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
30 EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
31
32 return manager ;
33 }

224 www.k19.com.br
225 I NTEGRAO JSF E JPA

34 // GETTERS E SETTERS
35 }

Cdigo Java 13.9: CarroBean.java

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 car-
regar 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, descarta-
mos 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.

Exerccios de Fixao

16 Vamos monitorar a quantidade de chamadas ao mtodo getCarros() do managed bean carro-

Bean. Altere a classe desse managed bean da seguinte forma:

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Carro ;
4 import br . com . k19 . modelo . CarroRepository ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . context . ExternalContext ;
8 import javax . faces . context . FacesContext ;
9 import javax . persistence . EntityManager ;
10 import javax . servlet . http . HttpServletRequest ;
11
12 @ManagedBean
13 public class CarroBean {
14
15 private Carro carro = new Carro () ;
16
17 public void adicionaCarro () {
18 EntityManager manager = this . getEntityManager () ;
19 CarroRepository repository = new CarroRepository ( manager ) ;
20
21 repository . adiciona ( this . carro ) ;
22 this . carro = new Carro () ;
23 }
24
25 public List < Carro > getCarros () {
26 EntityManager manager = this . getEntityManager () ;
27 CarroRepository repository = new CarroRepository ( manager ) ;
28
29 System . out . println ( " CHAMANDO O REPOSITORIO " ) ;
30 return repository . buscaTodos () ;
31 }
32
33 private EntityManager getEntityManager () {
34 FacesContext fc = FacesContext . getCurrentInstance () ;
35 ExternalContext ec = fc . getExternalContext () ;
36 HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
37 EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
38
39 return manager ;
40 }
41
42 // GETTERS E SETTERS

www.facebook.com/k19treinamentos 225
I NTEGRAO JSF E JPA 226

43 }

Cdigo Java 13.10: CarroBean.java

17 Acesse a pgina http://localhost:8080/K19-Integracao-JSF-JPA/carros.xhtml e depois


verifique as mensagens impressas.

18 Altere o comportamento do managed bean carroBean para diminuir o nmero de chamadas ao

repositrio de carros.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Carro ;
4 import br . com . k19 . modelo . CarroRepository ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . context . ExternalContext ;
8 import javax . faces . context . FacesContext ;
9 import javax . persistence . EntityManager ;
10 import javax . servlet . http . HttpServletRequest ;
11
12 @ManagedBean
13 public class CarroBean {
14
15 private Carro carro = new Carro () ;
16
17 private List < Carro > carros ;
18
19 public void adicionaCarro () {
20 EntityManager manager = this . getEntityManager () ;
21 CarroRepository repository = new CarroRepository ( manager ) ;
22
23 repository . adiciona ( this . carro ) ;
24 this . carro = new Carro () ;
25 this . carros = null ;
26 }
27
28 public List < Carro > getCarros () {
29 if ( this . carros == null ) {
30 EntityManager manager = this . getEntityManager () ;
31 CarroRepository repository = new CarroRepository ( manager ) ;
32 System . out . println ( " CHAMANDO O REPOSITORIO " ) ;
33 this . carros = repository . buscaTodos () ;
34 }
35
36 return this . carros ;
37 }
38
39 private EntityManager getEntityManager () {
40 FacesContext fc = FacesContext . getCurrentInstance () ;
41 ExternalContext ec = fc . getExternalContext () ;
42 HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
43 EntityManager manager = ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
44
45 return manager ;
46 }
47
48 // GETTERS E SETTERS
49 }

Cdigo Java 13.11: CarroBean.java

226 www.k19.com.br
227 I NTEGRAO JSF E JPA

19 Acesse novamente a pgina http://localhost:8080/K19-Integracao-JSF-JPA/carros.xhtml


e depois verifique as mensagens impressas.

www.facebook.com/k19treinamentos 227
I NTEGRAO JSF E JPA 228

228 www.k19.com.br
APNDICE
AUTENTICAO
A
Neste captulo, apresentaremos uma maneira de implementar o processo de autenticao dos
usurios de uma aplicao JSF.

Exerccios de Fixao

1 Crie um projeto chamado K19-Autenticacao seguindo os passos vistos no exerccio do Cap-


tulo 5.

2 Por simplicidade, utilizaremos um atributo de um managed bean para armazenar os usurios


da aplicao e suas respectivas senhas. A implementao que ser apresentada a seguir pode ser
alterada para que esses dados sejam armazenadas em um arquivo ou em um banco de dados.

Importante
Por motivos de segurana, as senhas dos usurios no devem ser armazenadas literal-
mente. Ao invs disso, as senhas dos usurios devem passar por um processo de trans-
formao (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 di-
gitado 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 com-
parar 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.

Crie uma classe chamada AutenticadorBean em um pacote chamado br.com.k19.controle no


projeto K19-Autenticacao com o seguinte contedo:

1 package br . com . k19 . controle ;


2
3 import java . util . HashMap ;
4 import java . util . Map ;
5 import javax . faces . bean . ManagedBean ;
6
7 @ManagedBean
8 public class AutenticadorBean {
9
10 private static Map < String , String > mapa = new HashMap < String , String >() ;
11
12 }

Cdigo Java A.1: AutenticadorBean.java

www.facebook.com/k19treinamentos 229
AUTENTICAO 230

3 Acrescente alguns usurios e suas respectivas senhas no atributo mapa.

1 package br . com . k19 . controle ;


2
3 import java . util . HashMap ;
4 import java . util . Map ;
5 import javax . faces . bean . ManagedBean ;
6
7 @ManagedBean
8 public class AutenticadorBean {
9
10 private static Map < String , String > mapa = new HashMap < String , String >() ;
11
12 static {
13 AutenticadorBean . mapa . put ( " k19 " , " k19 " ) ;
14 AutenticadorBean . mapa . put ( " jonas . hirata " , " jonas . hirata " ) ;
15 AutenticadorBean . mapa . put ( " marcelo . martins " , " marcelo . martins " ) ;
16 AutenticadorBean . mapa . put ( " rafael . cosentino " , " rafael . cosentino " ) ;
17 }
18 }

Cdigo Java A.2: AutenticadorBean.java

4 Crie propriedades para armazenar os dados enviados atravs do formulrio de identificao,


um mtodo para implementar o processo de autenticao e outro mtodo para registrar a sada do
usurio.

1 package br . com . k19 . controle ;


2
3 import java . util . HashMap ;
4 import java . util . Map ;
5 import javax . faces . application . FacesMessage ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . context . ExternalContext ;
8 import javax . faces . context . FacesContext ;
9 import javax . servlet . http . HttpSession ;
10
11 @ManagedBean
12 public class AutenticadorBean {
13
14 private static Map < String , String > mapa = new HashMap < String , String >() ;
15
16 private String usuario ;
17
18 private String senha ;
19
20 static {
21 AutenticadorBean . mapa . put ( " k19 " , " k19 " ) ;
22 AutenticadorBean . mapa . put ( " jonas . hirata " , " jonas . hirata " ) ;
23 AutenticadorBean . mapa . put ( " marcelo . martins " , " marcelo . martins " ) ;
24 AutenticadorBean . mapa . put ( " rafael . cosentino " , " rafael . cosentino " ) ;
25 }
26
27 public String autentica () {
28 FacesContext fc = FacesContext . getCurrentInstance () ;
29
30 if ( AutenticadorBean . mapa . containsKey ( this . usuario )
31 && AutenticadorBean . mapa . get ( this . usuario ) . equals ( this . senha ) ) {
32
33 ExternalContext ec = fc . getExternalContext () ;
34 HttpSession session = ( HttpSession ) ec . getSession ( false ) ;
35 session . setAttribute ( " usuario " , this . usuario ) ;
36
37 return " / home " ;
38 } else {
39 FacesMessage fm = new FacesMessage ( " usurio e / ou senha invlidos " ) ;

230 www.k19.com.br
231 AUTENTICAO

40 fm . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;


41 fc . addMessage ( null , fm ) ;
42 return " / login " ;
43 }
44 }
45
46 public String registraSaida () {
47 FacesContext fc = FacesContext . getCurrentInstance () ;
48 ExternalContext ec = fc . getExternalContext () ;
49 HttpSession session = ( HttpSession ) ec . getSession ( false ) ;
50 session . removeAttribute ( " usuario " ) ;
51
52 return " / login " ;
53 }
54
55 // GETTERS E SETTERS
56 }

Cdigo Java A.3: AutenticadorBean.java

O mtodo autentica() verifica se os dados enviados pelo formulrio de autenticao esto ca-
dastrados no mapa. Se esses dados estiverem cadastrados, registramos o nome do usurio na sesso
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 formul-
rio de autenticao. O mtodo registraSaida() simplesmente retira da sesso HTTP o nome do
usurio anteriormente autenticado.

5 Para testar, crie a tela do formulrio de autenticao e a tela principal da aplicao.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 <h : messages / >
13 <h : form >
14 <h : outputLabel value = " Usurio : " for = " campo - usuario " / >
15 <h : inputText value = " #{ autenticadorBean . usuario } " id = " campo - usuario " / >
16
17 <h : outputLabel value = " Senha : " for = " campo - senha " / >
18 <h : inputSecret value = " #{ autenticadorBean . senha } " id = " campo - senha " / >
19
20 <h : commandButton value = " Entrar " action = " #{ autenticadorBean . autentica } " / >
21 </ h : form >
22 </ h : body >
23 </ html >

Cdigo XHTML A.1: login.xhtml

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets "
6 xmlns : h = " http :// java . sun . com / jsf / html "
7 xmlns : f = " http :// java . sun . com / jsf / core " >
8
9 <h : head >

www.facebook.com/k19treinamentos 231
AUTENTICAO 232

10 < title > K19 Treinamentos </ title >


11 </ h : head >
12
13 <h : body >
14 Ol #{ sessionScope . usuario }!
15 Voc est logado .
16
17 <h : form >
18 <h : commandLink value = " Sair " action = " #{ autenticadorBean . registraSaida } " / >
19 </ h : form >
20 </ h : body >
21 </ html >

Cdigo XHTML A.2: home.xhtml

Na tela principal da aplicao, utilizamos a varivel sessionScope para recuperar o nome do


usurio autenticado.

6 Implante o projeto K19-Autenticacao no Glassfish. Certifique-se que o Wildfly esteja parado.


Inicie o Glassfish e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Autenticacao/login.xhtml

7 Somente usurios autenticados podem acessar a pgina principal da aplicao. Para controlar
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 br.com.k19.filters no pro-


jeto K19-Autenticacao com o seguinte contedo:

1 package br . com . k19 . filters ;


2
3 import java . io . IOException ;
4 import javax . servlet . Filter ;
5 import javax . servlet . FilterChain ;
6 import javax . servlet . FilterConfig ;
7 import javax . servlet . ServletException ;
8 import javax . servlet . ServletRequest ;
9 import javax . servlet . ServletResponse ;
10 import javax . servlet . annotation . WebFilter ;
11 import javax . servlet . http . HttpServletRequest ;
12 import javax . servlet . http . HttpServletResponse ;
13 import javax . servlet . http . HttpSession ;
14
15 @WebFilter ( servletNames = { " Faces Servlet " })
16 public class ControleDeAcesso implements Filter {
17
18 @Override
19 public void doFilter ( ServletRequest request , ServletResponse response ,
20 FilterChain chain ) throws IOException , ServletException {
21
22 HttpServletRequest req = ( HttpServletRequest ) request ;
23 HttpSession session = req . getSession () ;
24
25 if ( session . getAttribute ( " usuario " ) != null
26 || req . getRequestURI () . endsWith ( " login . xhtml " ) ) {
27 chain . doFilter ( request , response ) ;
28 } else {
29 HttpServletResponse res = ( HttpServletResponse ) response ;
30 res . sendRedirect ( " login . xhtml " ) ;
31 }
32 }

232 www.k19.com.br
233 AUTENTICAO

33
34 @Override
35 public void init ( FilterConfig filterConfig ) throws ServletException {
36 }
37
38 @Override
39 public void destroy () {
40 }
41 }

Cdigo Java A.4: ControleDeAcesso.java

A anotao @WebServlet registra o filtro no Web Container. O atributo servletNames utilizado


para definir quais servlets sero interceptadas pelo filtro. O mtodo doFilter() chamado toda vez
que uma requisio HTTP servlet Faces Servlet realizada. Esse mtodo verifica se existe um
usurio registrado na sesso HTTP ou se a pgina requisitada a do formulrio de autenticao. Se
uma dessas condies for satisfeita, o filtro permite que o fluxo prossiga para a Faces Servlet. Caso
contrrio, ele redireciona o usurio para a pgina do formulrio de autenticao.

8 Tente acessar diretamente a pgina principal da aplicao acessando http://localhost:8080/


K19-Autenticacao/home.xhtml. Observe que a aplicao redireciona o navegador para a pgina do
formulrio de autenticao.

www.facebook.com/k19treinamentos 233
AUTENTICAO 234

www.k19.com.br

L
HTMscript
a
Jav
C S S

Requisio HTTP Resposta HTTP

Filtro de Controle de Acesso

Faces Servlet

Restore Apply Request Process Update Ivoke Render


View Values Validation Model Application Response

MANAGED BEANS

CONTROLE
MODELO VISO

TELAS

ENTIDADES

TEMPLATES

REPOSITRIOS TELAS PARCIAIS

Figura A.1: Filtro e Managed Bean para implementar o controle de autenticao

234 www.k19.com.br
APNDICE
PGINAS DE E RRO
B
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)
Hi Hi Hi!! 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

Figura B.1: Expondo possveis falhas de segurana

Neste captulo, apresentaremos uma maneira de personalizar as pginas de erro da aplicao.

Exerccios de Fixao

1 Crie um projeto chamado K19-Paginas-de-Erro seguindo os passos vistos no exerccio do Cap-


tulo 5.

2 Criaremos uma pgina de erro padro. Adicione uma pgina chamada pagina-de-erro.xhtml
no projeto K19-Paginas-de-Erro.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Ocorreu um erro interno no sistema . </ h1 >

www.facebook.com/k19treinamentos 235
PGINAS DE E RRO 236

13 < h3 > Tente novamente em alguns instantes . </ h3 >


14 </ h : body >
15 </ html >

Cdigo XHTML B.1: pagina-de-erro.xhtml

3 Criaremos uma pgina com um boto que sempre produzir um erro ao ser clicado. Adicione
uma pgina chamada gerador-de-erro.xhtml no projeto K19-Paginas-de-Erro.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 <h : form >
13 <h : commandButton value = " Gera Erro " action = " #{ erroBean . geraErro } " / >
14 </ h : form >
15 </ h : body >
16 </ html >

Cdigo XHTML B.2: gerador-de-erro.xhtml

4 Crie um managed bean que provoque propositalmente um erro. Adicione em um pacote cha-
mado br.com.k19.controle uma classe chamada ErroBean com o seguinte cdigo:

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4
5 @ManagedBean
6 public class ErroBean {
7 public void geraErro () {
8 System . out . println (10/0) ;
9 }
10 }

Cdigo Java B.1: ErroBean.java

5 Implante o projeto K19-Paginas-de-Erro no Glassfish. Certifique-se que o Wildfly esteja parado.


Inicie o Glassfish e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Paginas-de-Erro/gerador-de-erro.xhtml

6 Configure o Web Container para direcionar todas as exceptions para a pgina de erro padro.
Adicione o seguinte cdigo no arquivo web.xml.

1 ...
2 < error - page >
3 < exception - type > java . lang . Exception </ exception - type >
4 < location >/ pagina - de - erro . xhtml </ location >
5 </ error - page >

236 www.k19.com.br
237 PGINAS DE E RRO

6 ...

Cdigo XML B.1: web.xml

7 Teste a aplicao novamente acessando o seguinte endereo:

http://localhost:8080/K19-Paginas-de-Erro/gerador-de-erro.xhtml

www.facebook.com/k19treinamentos 237
PGINAS DE E RRO 238

238 www.k19.com.br
APNDICE
P RIME FACES
C
Atualmente, a principal biblioteca de componentes visuais JSF o PrimeFaces. Visite o site do
PrimeFaces http://www.primefaces.org/ para maiores informaes.

Instalao

Para ter acesso aos recursos do PrimeFaces, necessrio adicionar o JAR dessa biblioteca no
classpath de uma aplicao JSF.

Nas pginas, devemos adicionar o namespace do PrimeFaces para ter acesso aos componentes
dessa biblioteca.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : p = " http :// primefaces . org / ui " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 ...
14 </ h : body >
15 </ html >

Cdigo XHTML C.1: Namespace do PrimeFaces

Exerccios de Fixao

www.facebook.com/k19treinamentos 239
P RIME FACES 240

1 Crie um projeto chamado K19-PrimeFaces seguindo os passos vistos no exerccio do Captulo 5.

2 Adicione o JAR do PrimeFaces no projeto K19-PrimeFaces. Voc pode encontrar esse arquivo
na pasta K19-Arquivos/primefaces.

Importante
Voc tambm pode obter o JAR do PrimeFaces atravs do site da K19: www.k19.com.
br/arquivos.

Copie o arquivo primefaces-VERSAO.jar da pasta K19-Arquivos/primefaces para a pasta WEB-


INF/lib do projeto K19-PrimeFaces.

3 Analogamente ao exerccio anterior, adicione os arquivos itext-2.1.7.jar e poi-3.9-20121203.jar


no projeto K19-PrimeFaces. O primeiro arquivo corresponde biblioteca iText (http://itextpdf.
com/). O segundo arquivo corresponde biblioteca Apache POI (http://poi.apache.org/). Essas
bibliotecas so utilizadas pelo PrimeFaces para exportar dados em PDF e XLS respectivamente.

Importante
Voc tambm pode obter os arquivos itext-2.1.7.jar e poi-3.9-20121203.jar atravs
do site da K19: www.k19.com.br/arquivos.

4 Adicione uma pgina chamada spinner.xhtml no projeto K19-PrimeFaces com o seguinte con-
tedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "

240 www.k19.com.br
241 P RIME FACES

2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : p = " http :// primefaces . org / ui " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 <p : spinner / >
14 </ h : body >
15 </ html >

Cdigo XHTML C.2: spinner.xhtml

5 Implante o projeto K19-PrimeFaces no Glassfish. Certifique-se que o Wildfly esteja parado.


Inicie o Glassfish e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-PrimeFaces/spinner.xhtml

AutoComplete

O componente AutoComplete permite que as aplicaes ofeream aos usurios sugestes para
o preenchimento de campos.

Exerccios de Fixao

6 Adicione uma pgina chamada auto-complete.xhtml no projeto K19-PrimeFaces com o se-


guinte contedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : p = " http :// primefaces . org / ui " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15
16 <h : outputLabel value = " Valor : " / >
17 <p : autoComplete
18 value = " #{ autoCompleteBean . value } "
19 completeMethod = " #{ autoCompleteBean . completeMethod } "
20 minQueryLength = " 3 "
21 effect = " fade "
22 effectDuration = " 400 "
23 queryDelay = " 1000 " / >
24

www.facebook.com/k19treinamentos 241
P RIME FACES 242

25 <h : outputLabel value = " Valores : " / >


26 <p : autoComplete
27 value = " #{ autoCompleteBean . values } "
28 completeMethod = " #{ autoCompleteBean . completeMethod } "
29 minQueryLength = " 4 "
30 maxResults = " 5 "
31 effect = " blind "
32 effectDuration = " 600 "
33 queryDelay = " 500 "
34 multiple = " true " / >
35 </ h: panelGrid >
36 </ h : form >
37 </ h : body >
38 </ html >

Cdigo XHTML C.3: auto-complete.xhtml

7 Adicione uma classe chamada AutoCompleteBean em um pacote chamado br.com.k19.controle


no projeto K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . controle ;


2
3 import java . util . ArrayList ;
4 import java . util . List ;
5 import javax . faces . bean . ManagedBean ;
6
7 @ManagedBean
8 public class AutoCompleteBean {
9
10 private String value ;
11 private List < String > values ;
12
13 public List < String > completeMethod ( String query ) {
14 List < String > lista = new ArrayList < String >() ;
15
16 for ( int i = 0; i < 10; i ++) {
17 lista . add ( query + Math . random () ) ;
18 }
19 return lista ;
20 }
21
22 // GETTERS E SETTERS
23 }

Cdigo Java C.1: AutoCompleteBean.java

Execute o projeto K19-PrimeFaces e acesse o endereo:

http://localhost:8080/K19-PrimeFaces/auto-complete.xhtml

Poll

O componente Poll utilizado quando desejamos que os navegadores realizem requisies AJAX
periodicamente.

Exerccios de Fixao

242 www.k19.com.br
243 P RIME FACES

8 Adicione uma pgina chamada poll.xhtml no projeto K19-PrimeFaces com o seguinte con-
tedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : p = " http :// primefaces . org / ui " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 <h : form >
14 <h : outputText
15 id = " placar "
16 value = " #{ pollBean . placarTimeA } X #{ pollBean . placarTimeB } " / >
17
18 <p : poll
19 interval = " 1 "
20 listener = " #{ pollBean . update } "
21 update = " placar " / >
22 </ h : form >
23 </ h : body >
24 </ html >

Cdigo XHTML C.4: poll.xhtml

9 Adicione uma classe chamada PollBean em um pacote chamado br.com.k19.controle no pro-


jeto K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4 import javax . faces . bean . ViewScoped ;
5
6 @ManagedBean
7 @ViewScoped
8 public class PollBean {
9
10 private int placarTimeA ;
11 private int placarTimeB ;
12
13 public void update () {
14 if ( Math . random () > 0.5) {
15 this . placarTimeA ++;
16 } else {
17 this . placarTimeB ++;
18 }
19 }
20
21 // GETTERS E SETTERS
22 }

Cdigo Java C.2: PollBean.java

Teste a aplicao acessando o endereo:

http://localhost:8080/K19-PrimeFaces/poll.xhtml

www.facebook.com/k19treinamentos 243
P RIME FACES 244

Calendar

O componente Calendar oferece uma interface sofisticada para a seleo de uma data.

Exerccios de Fixao

10 Adicione uma pgina chamada calendar.xhtml no projeto K19-PrimeFaces com o seguinte


contedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : p = " http :// primefaces . org / ui " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 <h : outputScript name = " calendar . js " library = " js " target = " head " / >
14 <h : form >
15 <h : panelGrid columns = " 2 " >
16 <h : outputLabel value = " Data de nascimento : " / >
17 <p : calendar
18 value = " #{ calendarBean . dataDeNascimento } "
19 locale = " pt_BR "
20 mode = " inline " / >
21
22 <h : outputLabel value = " Data de nascimento : " / >
23 <p : calendar
24 value = " #{ calendarBean . dataDeNascimento } "
25 locale = " pt_BR "
26 effect = " slide " / >
27
28 <h : outputLabel value = " Data de nascimento : " / >
29 <p : calendar
30 value = " #{ calendarBean . dataDeNascimento } "
31 locale = " pt_BR "
32 showOn = " button "
33 effect = " fold " / >
34
35 <h : outputLabel value = " Data de nascimento : " / >
36 <p : calendar
37 value = " #{ calendarBean . dataDeNascimento } "
38 locale = " pt_BR "
39 navigator = " true "
40 effect = " slideDown " / >
41 </ h : panelGrid >
42 </ h : form >
43 </ h : body >
44 </ html >

Cdigo XHTML C.5: calendar.xhtml

11 Adicione um arquivo chamado calendar.js em uma pasta chamada resources/js na raiz da apli-
cao K19-PrimeFaces com o seguinte contedo. A pasta resources/js deve ser ficar em WebContent

244 www.k19.com.br
245 P RIME FACES

1 PrimeFaces . locales [ pt_BR ] = {


2 closeText : Fechar ,
3 prevText : Anterior ,
4 nextText : Prximo ,
5 currentText : Hoje ,
6 monthNames : [ Janeiro , Fevereiro , Maro , Abril , Maio , Junho ,
7 Julho , Agosto , Setembro , Outubro , Novembro , Dezembro ] ,
8 monthNamesShort : [ Jan , Fev , Mar , Abr , Mai , Jun ,
9 Jul , Ago , Set , Out , Nov , Dez ] ,
10 dayNames : [ Domingo , Segunda , Tera , Quarta , Quinta , Sexta , Sbado ] ,
11 dayNamesShort : [ Dom , Seg , Ter , Qua , Qui , Sex , Sb ] ,
12 dayNamesMin : [ D , S , T , Q , Q , S , S ] ,
13 weekHeader : Semana ,
14 firstDay : 0 ,
15 isRTL : false ,
16 showMonthAfterYear : false ,
17 yearSuffix : ,
18 timeOnlyTitle : S Horas ,
19 timeText : Tempo ,
20 hourText : Hora ,
21 minuteText : Minuto ,
22 secondText : Segundo ,
23 ampm : false ,
24 month : Ms ,
25 week : Semana ,
26 day : Dia ,
27 allDayText : Todo o Dia
28 };

Cdigo Javascript C.1: calendar.js

12 Adicione uma classe chamada CalendarBean em um pacote chamado br.com.k19.controle no


projeto K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . controle ;


2
3 import java . util . Date ;
4
5 import javax . faces . bean . ManagedBean ;
6
7 @ManagedBean
8 public class CalendarBean {
9 private Date dataDeNascimento ;
10
11 // GETTERS E SETTERS
12 }

Cdigo Java C.3: Calendar.java

Teste a aplicao acessando o endereo:

http://localhost:8080/K19-PrimeFaces/calendar.xhtml

InputMask

O componente InputMask permite a definio de mscaras de preenchimento para caixas de


texto.

www.facebook.com/k19treinamentos 245
P RIME FACES 246

Exerccios de Fixao

13 Adicione uma pgina chamada input-mask.xhtml no projeto K19-PrimeFaces com o seguinte


contedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : p = " http :// primefaces . org / ui " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15 <h : outputLabel value = " Data : " / >
16 <p : inputMask mask = " 99/99/9999 " / >
17
18 <h : outputLabel value = " Telefone : " / >
19 <p : inputMask mask = " (99) 9999 -9999?9 " / >
20
21 <h : outputLabel value = " CPF : " / >
22 <p : inputMask mask = " 999.999.999 -99 " / >
23
24 <h : outputLabel value = " Cdigo " / >
25 <p : inputMask mask = " a * -99 -* a " / >
26 </ h : panelGrid >
27 </ h : form >
28 </ h : body >
29 </ html >

Cdigo XHTML C.6: input-mask.xhtml

Teste a aplicao acessando o endereo:

http://localhost:8080/K19-PrimeFaces/input-mask.xhtml

DataTable

O componente DataTable utilizado para apresentar dados de forma tabular. Ele possui recursos
como: paginao, filtragem e ordenao.

Exerccios de Fixao

14 Adicione uma pgina chamada data-table.xhtml no projeto K19-PrimeFaces com o seguinte


contedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "

246 www.k19.com.br
247 P RIME FACES

2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets "
8 xmlns : p = " http :// primefaces . org / ui " >
9
10 <h : head >
11 < title > K19 Treinamentos </ title >
12 </ h : head >
13
14 <h : body >
15 <h : form id = " form " >
16 <p : dataTable
17 value = " #{ dataTableBean . cursos } "
18 var = " curso "
19 rowKey = " #{ curso . sigla } "
20 paginator = " true "
21 rows = " 4 "
22 selectionMode = " multiple "
23 filteredValue = " #{ dataTableBean . cursosFiltrados } "
24 selection = " #{ dataTableBean . cursosSelecionados } " >
25
26 <f : facet name = " header " > Cursos da K19 </ f : facet >
27
28 <p : column
29 headerText = " ID "
30 sortBy = " #{ curso . id } "
31 filterBy = " #{ curso . id } " >
32 #{ curso . id }
33 </ p: column >
34
35 <p : column
36 headerText = " Logo " >
37 <h : graphicImage value = " #{ curso . logo } " / >
38 </ p: column >
39
40 <p : column
41 headerText = " Sigla "
42 sortBy = " #{ curso . sigla } "
43 filterBy = " #{ curso . sigla } " >
44 #{ curso . sigla }
45 </ p: column >
46
47 <p : column
48 headerText = " Nome "
49 sortBy = " #{ curso . nome } "
50 filterBy = " #{ curso . nome } " >
51 #{ curso . nome }
52 </ p: column >
53
54 <f : facet name = " footer " >
55 <p : commandButton
56 value = " Escolher Curso "
57 update = " : form : curso - escolhido " / >
58 </ f: facet >
59 </ p : dataTable >
60
61 <p : panel id = " curso - escolhido " header = " Cursos Escolhidos " >
62 < ul >
63 < ui : repeat
64 var = " curso "
65 value = " #{ dataTableBean . cursosSelecionados } "
66 rendered = " #{ not empty dataTableBean . cursosSelecionados } " >
67 < li >
68 <h : outputText value = " #{ curso . nome } " / >
69 </ li >
70 </ ui : repeat >
71

www.facebook.com/k19treinamentos 247
P RIME FACES 248

72 <h : panelGroup
73 rendered = " #{ dataTableBean . cursosSelecionados == null or empty dataTableBean -
. cursosSelecionados } " >
74 < li > Nenhum curso escolhido </ li >
75 </ h : panelGroup >
76 </ ul >
77 </ p : panel >
78 </ h : form >
79 </ h : body >
80 </ html >

Cdigo XHTML C.7: data-table.xhtml

15 Adicione uma classe chamada Curso em um pacote chamado br.com.k19.modelo no projeto


K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . modelo ;


2
3 public class Curso {
4 private Long id ;
5 private String sigla ;
6 private String nome ;
7 private String logo ;
8
9 public Curso ( Long id , String sigla , String nome , String logo ) {
10 this . id = id ;
11 this . sigla = sigla ;
12 this . nome = nome ;
13 this . logo = logo ;
14 }
15
16 // GETTERS E SETTERS
17 }

Cdigo Java C.4: Curso.java

16 Adicione uma classe chamada CursoRepository em um pacote chamado br.com.k19.modelo


no projeto K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . modelo ;


2
3 import java . util . ArrayList ;
4 import java . util . List ;
5
6 public class CursoRepository {
7 private static List < Curso > cursos = new ArrayList < Curso >() ;
8
9 static {
10 cursos . add ( new Curso (1 L , " K01 " ,
11 " Lgica de Programao " ,
12 " http :// www . k19 . com . br / css / img / k01 - logo - small . png " ) ) ;
13
14 cursos . add ( new Curso (2 L , " K02 " ,
15 " Desenvolvimento Web com HTML , CSS e JavaScript " ,
16 " http :// www . k19 . com . br / css / img / k02 - logo - small . png " ) ) ;
17
18 cursos . add ( new Curso (3 L , " K03 " ,
19 " SQL e Modelo Relacional " ,
20 " http :// www . k19 . com . br / css / img / k03 - logo - small . png " ) ) ;
21
22 cursos . add ( new Curso (4 L , " K11 " ,
23 " Orientao a Objetos em Java " ,
24 " http :// www . k19 . com . br / css / img / k11 - logo - small . png " ) ) ;

248 www.k19.com.br
249 P RIME FACES

25
26 cursos . add ( new Curso (5 L , " K12 " ,
27 " Desenvolvimento Web com JSF2 e JPA2 " ,
28 " http :// www . k19 . com . br / css / img / k12 - logo - small . png " ) ) ;
29
30 cursos . add ( new Curso (6 L , " K21 " ,
31 " Persistncia com JAP2 e Hibernate " ,
32 " http :// www . k19 . com . br / css / img / k21 - logo - small . png " ) ) ;
33
34 cursos . add ( new Curso (7 L , " K22 " ,
35 " Desenvolvimento Web Avanado com EJB , JSF e CDI " ,
36 " http :// www . k19 . com . br / css / img / k22 - logo - small . png " ) ) ;
37
38 cursos . add ( new Curso (8 L , " K23 " ,
39 " Integrao de Sistemas com Webservices , JMS e EJB " ,
40 " http :// www . k19 . com . br / css / img / k23 - logo - small . png " ) ) ;
41
42 cursos . add ( new Curso (9 L , " K31 " ,
43 " C # e Orientao a Objetos " ,
44 " http :// www . k19 . com . br / css / img / k31 - logo - small . png " ) ) ;
45
46 cursos . add ( new Curso (10 L , " K32 " ,
47 " Desenvolvimento Web com ASP . NET MVC " ,
48 " http :// www . k19 . com . br / css / img / k32 - logo - small . png " ) ) ;
49
50 cursos . add ( new Curso (11 L , " K41 " ,
51 " Desenvolvimento Mobile com Android " ,
52 " http :// www . k19 . com . br / css / img / k41 - logo - small . png " ) ) ;
53
54 cursos . add ( new Curso (12 L , " K51 " ,
55 " Design Patterns em Java " ,
56 " http :// www . k19 . com . br / css / img / k51 - logo - small . png " ) ) ;
57
58 cursos . add ( new Curso (13 L , " K52 " ,
59 " Desenvolvimento Web com Struts " ,
60 " http :// www . k19 . com . br / css / img / k52 - logo - small . png " ) ) ;
61 }
62
63 public List < Curso > getCursos () {
64 return cursos ;
65 }
66 }

Cdigo Java C.5: CursoRepository.java

17 Adicione uma classe chamada DataTableBean em um pacote chamado br.com.k19.controle no


projeto K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . controle ;


2
3 import java . util . List ;
4
5 import javax . faces . bean . ManagedBean ;
6
7 import br . com . k19 . modelo . Curso ;
8 import br . com . k19 . modelo . CursoRepository ;
9
10 @ManagedBean
11 public class DataTableBean {
12 private List < Curso > cursosSelecionados ;
13 private List < Curso > cursosFiltrados ;
14
15 public List < Curso > getCursos () {
16 return new CursoRepository () . getCursos () ;
17 }
18
19 // GETTERS E SETTERS

www.facebook.com/k19treinamentos 249
P RIME FACES 250

20 }

Cdigo Java C.6: DataTableBean.java

Teste a aplicao acessando o endereo:

http://localhost:8080/K19-PrimeFaces/data-table.xhtml

DataExporter

O componente DataExporter permite que os dados apresentados em um DataTable sejam ex-


portados para diversos formatos como: xls, pdf, cvs e xml.

Exerccios de Fixao

18 Adicione uma pgina chamada data-exporter.xhtml no projeto K19-PrimeFaces com o seguinte


contedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets "
8 xmlns : p = " http :// primefaces . org / ui " >
9
10 <h : head >
11 < title > K19 Treinamentos </ title >
12 </ h : head >
13
14 <h : body >
15 <h : form id = " form " >
16 <p : dataTable
17 id =" tabela "
18 value = " #{ dataTableBean . cursos } "
19 var = " curso "
20 rowKey = " #{ curso . sigla } "
21 paginator = " true "
22 rows = " 4 "
23 selectionMode = " multiple "
24 filteredValue = " #{ dataTableBean . cursosFiltrados } "
25 selection = " #{ dataTableBean . cursosSelecionados } " >
26
27 <f : facet name = " header " > Cursos da K19 </ f : facet >
28
29 <p : column sortBy = " #{ curso . id } " filterBy = " #{ curso . id } " >
30 <f : facet name = " header " >
31 <h : outputText value = " ID " / >
32 </ f : facet >
33 <h : outputText value = " #{ curso . id } " / >
34 </ p: column >
35
36 <p : column exportable = " false " >
37 <f : facet name = " header " >
38 <h : outputText value = " Logo " / >
39 </ f : facet >
40 <h : graphicImage value = " #{ curso . logo } " / >

250 www.k19.com.br
251 P RIME FACES

41 </ p: column >


42
43 <p : column sortBy = " #{ curso . sigla } " filterBy = " #{ curso . sigla } " >
44 <f : facet name = " header " >
45 <h : outputText value = " Sigla " / >
46 </ f : facet >
47 <h : outputText value = " #{ curso . sigla } " / >
48 </ p: column >
49
50 <p : column sortBy = " #{ curso . nome } " filterBy = " #{ curso . nome } " >
51 <f : facet name = " header " >
52 <h : outputText value = " Nome " / >
53 </ f : facet >
54 <h : outputText value = " #{ curso . nome } " / >
55 </ p: column >
56
57 <f : facet name = " footer " >
58 <h : panelGrid columns = " 3 " >
59 <h : panelGroup >
60 Exportar toda a tabela para :
61
62 <h : commandButton value = " XLS " >
63 <p : dataExporter
64 type = " xls "
65 target = " tabela "
66 fileName = " cursos " / >
67 </ h : commandButton >
68
69 <h : commandButton value = " PDF " >
70 <p : dataExporter
71 type = " pdf "
72 target = " tabela "
73 fileName = " cursos " / >
74 </ h : commandButton >
75
76 <h : commandButton value = " CSV " >
77 <p : dataExporter
78 type = " csv "
79 target = " tabela "
80 fileName = " cursos " / >
81 </ h : commandButton >
82
83 <h : commandButton value = " XML " >
84 <p : dataExporter
85 type = " xml "
86 target = " tabela "
87 fileName = " cursos " / >
88 </ h : commandButton >
89 </ h : panelGroup >
90 <h : panelGroup >
91 Exportar apenas esta pgina para :
92
93 <h : commandButton value = " XLS " >
94 <p : dataExporter
95 type = " xls "
96 target = " tabela "
97 fileName = " cursos "
98 pageOnly = " true " / >
99 </ h : commandButton >
100
101 <h : commandButton value = " PDF " >
102 <p : dataExporter
103 type = " pdf "
104 target = " tabela "
105 fileName = " cursos "
106 pageOnly = " true " / >
107 </ h : commandButton >
108
109 <h : commandButton value = " CSV " >
110 <p : dataExporter

www.facebook.com/k19treinamentos 251
P RIME FACES 252

111 type = " csv "


112 target = " tabela "
113 fileName = " cursos "
114 pageOnly = " true " / >
115 </ h : commandButton >
116
117 <h : commandButton value = " XML " >
118 <p : dataExporter
119 type = " xml "
120 target = " tabela "
121 fileName = " cursos "
122 pageOnly = " true " / >
123 </ h : commandButton >
124 </ h : panelGroup >
125 </ h : panelGrid >
126 </ f : facet >
127 </ p : dataTable >
128 </ h : form >
129 </ h : body >
130 </ html >

Cdigo XHTML C.8: data-exporter.xhtml

PickList

O componente PickList oferece uma interface simples para seleo de elementos de um con-
junto.

Exerccios de Fixao

19 Adicione uma pgina chamada pick-list.xhtml no projeto K19-PrimeFaces com o seguinte con-
tedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : p = " http :// primefaces . org / ui " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12
13 <h : body >
14 <h : form >
15 <p : growl id = " msg " showDetail = " true " escape = " false " / >
16
17 <p : pickList
18 value = " #{ pickListBean . cursos } "
19 var = " curso "
20 effect = " bounce "
21 itemValue = " #{ curso . id } "
22 itemLabel = " #{ curso . sigla } "
23 showSourceControls = " true "
24 showTargetControls = " true "
25 showCheckbox = " true "
26 showSourceFilter = " true "

252 www.k19.com.br
253 P RIME FACES

27 showTargetFilter = " true "


28 filterMatchMode = " contains " >
29
30 <f : facet name = " sourceCaption " > Cursos </ f : facet >
31 <f : facet name = " targetCaption " > Selecionados </ f : facet >
32
33 <p : ajax
34 event = " transfer "
35 listener = " #{ pickListBean . onTransfer } "
36 update = " msg " / >
37
38 <p : column >
39 <p : graphicImage value = " #{ curso . logo } " / >
40 </ p : column >
41
42 <p : column >
43 <h : outputText value = " #{ curso . sigla } " / >
44 </ p : column >
45 </ p : pickList >
46 </ h : form >
47 </ h : body >
48 </ html >

Cdigo XHTML C.9: pick-list.xhtml

20 Adicione uma classe chamada PickListBean em um pacote chamado br.com.k19.controle no


projeto K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . controle ;


2
3 import java . util . ArrayList ;
4 import java . util . List ;
5
6 import javax . faces . application . FacesMessage ;
7 import javax . faces . bean . ManagedBean ;
8 import javax . faces . context . FacesContext ;
9
10 import org . primefaces . event . TransferEvent ;
11 import org . primefaces . model . DualListModel ;
12
13 import br . com . k19 . modelo . Curso ;
14 import br . com . k19 . modelo . CursoRepository ;
15
16 @ManagedBean
17 public class PickListBean {
18
19 private DualListModel < Curso > cursos ;
20
21 public PickListBean () {
22 List < Curso > source = new CursoRepository () . getCursos () ;
23 List < Curso > target = new ArrayList < Curso >() ;
24
25 this . cursos = new DualListModel < Curso >( source , target ) ;
26 }
27
28 public void onTransfer ( TransferEvent event ) {
29 StringBuilder builder = new StringBuilder () ;
30
31 for ( Object obj : event . getItems () ) {
32 Integer id = Integer . valueOf ( obj . toString () ) ;
33 Curso c = this . cursos . getSource () . get ( id - 1) ;
34 builder . append ( c . getNome () ) . append ( " < br / > " ) ;
35 }
36
37 FacesMessage msg = new FacesMessage () ;
38 msg . setSeverity ( FacesMessage . SEVERITY_INFO ) ;
39

www.facebook.com/k19treinamentos 253
P RIME FACES 254

40 if ( event . isAdd () ) {
41 msg . setSummary ( " Cursos Selecionados " ) ;
42 } else {
43 msg . setSummary ( " Cursos Removidos " ) ;
44 }
45
46 msg . setDetail ( builder . toString () ) ;
47
48 FacesContext . getCurrentInstance () . addMessage ( null , msg ) ;
49 }
50
51 // GETTERS E SETTERS
52 }

Cdigo Java C.7: PickListBean.java

Teste a aplicao acessando o endereo:

http://localhost:8080/K19-PrimeFaces/pick-list.xhtml

MegaMenu

O componente MegaMenu utilizado para criao dos menus de uma aplicao JSF.

Exerccios de Fixao

Exerccios de Fixao

21 Adicione uma pgina chamada mega-menu.xhtml no projeto K19-PrimeFaces com o seguinte

contedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : p = " http :// primefaces . org / ui " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11
12 <h : body >
13 <p : megaMenu model = " #{ megaMenuBean . menuModel } " / >
14 </ h : body >
15 </ html >

Cdigo XHTML C.10: mega-menu.xhtml

22 Adicione uma classe chamada MegaMenuBean em um pacote chamado br.com.k19.controle


no projeto K19-PrimeFaces com o seguinte contedo.

254 www.k19.com.br
255 P RIME FACES

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4
5 import org . primefaces . component . column . Column ;
6 import org . primefaces . component . menuitem . MenuItem ;
7 import org . primefaces . component . submenu . Submenu ;
8 import org . primefaces . model . DefaultMenuModel ;
9 import org . primefaces . model . MenuModel ;
10
11 @ManagedBean
12 public class MegaMenuBean {
13 private MenuModel menuModel ;
14
15 public MegaMenuBean () {
16 this . menuModel = new DefaultMenuModel () ;
17
18 Submenu esporteMenu = new Submenu () ;
19 esporteMenu . setLabel ( " Esportes " ) ;
20
21 Submenu futebolMenu = new Submenu () ;
22 futebolMenu . setLabel ( " Futebol " ) ;
23
24 MenuItem item = new MenuItem () ;
25 item . setValue ( " Brasileiro " ) ;
26 item . setUrl ( " # " ) ;
27 futebolMenu . getChildren () . add ( item ) ;
28
29 item = new MenuItem () ;
30 item . setValue ( " Europeu " ) ;
31 item . setUrl ( " # " ) ;
32 futebolMenu . getChildren () . add ( item ) ;
33
34 item = new MenuItem () ;
35 item . setValue ( " Japons " ) ;
36 item . setUrl ( " # " ) ;
37 futebolMenu . getChildren () . add ( item ) ;
38
39 Submenu voleiMenu = new Submenu () ;
40 voleiMenu . setLabel ( " Volei " ) ;
41
42 item = new MenuItem () ;
43 item . setValue ( " Liga Mundial " ) ;
44 item . setUrl ( " # " ) ;
45 voleiMenu . getChildren () . add ( item ) ;
46
47 item = new MenuItem () ;
48 item . setValue ( " Eliminatrias da Copa " ) ;
49 item . setUrl ( " # " ) ;
50 voleiMenu . getChildren () . add ( item ) ;
51
52 Submenu automobilismoMenu = new Submenu () ;
53 automobilismoMenu . setLabel ( " Automobilismo " ) ;
54
55 item = new MenuItem () ;
56 item . setValue ( " Frmula 1 " ) ;
57 item . setUrl ( " # " ) ;
58 automobilismoMenu . getChildren () . add ( item ) ;
59
60 item = new MenuItem () ;
61 item . setValue ( " Frmula 3 " ) ;
62 item . setUrl ( " # " ) ;
63 automobilismoMenu . getChildren () . add ( item ) ;
64
65 item = new MenuItem () ;
66 item . setValue ( " Fotos " ) ;
67 item . setUrl ( " # " ) ;
68 automobilismoMenu . getChildren () . add ( item ) ;
69
70 Column esporteColuna1 = new Column () ;

www.facebook.com/k19treinamentos 255
P RIME FACES 256

71 esporteColuna1 . getChildren () . add ( futebolMenu ) ;


72 esporteColuna1 . getChildren () . add ( voleiMenu ) ;
73 esporteMenu . getChildren () . add ( esporteColuna1 ) ;
74
75 Column esporteColuna2 = new Column () ;
76 esporteColuna2 . getChildren () . add ( automobilismoMenu ) ;
77 esporteMenu . getChildren () . add ( esporteColuna2 ) ;
78
79 this . menuModel . addSubmenu ( esporteMenu ) ;
80
81 Submenu noticiaMenu = new Submenu () ;
82 noticiaMenu . setLabel ( " Notcias " ) ;
83
84 Submenu economiaMenu = new Submenu () ;
85 economiaMenu . setLabel ( " Economia " ) ;
86
87 item = new MenuItem () ;
88 item . setValue ( " Brasil " ) ;
89 item . setUrl ( " # " ) ;
90 economiaMenu . getChildren () . add ( item ) ;
91
92 item = new MenuItem () ;
93 item . setValue ( " Mundo " ) ;
94 item . setUrl ( " # " ) ;
95 economiaMenu . getChildren () . add ( item ) ;
96
97 Submenu tecnologiaMenu = new Submenu () ;
98 tecnologiaMenu . setLabel ( " Tecnologia " ) ;
99
100 item = new MenuItem () ;
101 item . setValue ( " Segurana " ) ;
102 item . setUrl ( " # " ) ;
103 tecnologiaMenu . getChildren () . add ( item ) ;
104
105 item = new MenuItem () ;
106 item . setValue ( " Negcios em TI " ) ;
107 item . setUrl ( " # " ) ;
108 tecnologiaMenu . getChildren () . add ( item ) ;
109
110 Submenu educacaoMenu = new Submenu () ;
111 educacaoMenu . setLabel ( " Educao " ) ;
112
113 item = new MenuItem () ;
114 item . setValue ( " Vestibular " ) ;
115 item . setUrl ( " # " ) ;
116 educacaoMenu . getChildren () . add ( item ) ;
117
118 item = new MenuItem () ;
119 item . setValue ( " ENEM " ) ;
120 item . setUrl ( " # " ) ;
121 educacaoMenu . getChildren () . add ( item ) ;
122
123 item = new MenuItem () ;
124 item . setValue ( " ProUni " ) ;
125 item . setUrl ( " # " ) ;
126 educacaoMenu . getChildren () . add ( item ) ;
127
128 Column noticiaColuna1 = new Column () ;
129 noticiaColuna1 . getChildren () . add ( economiaMenu ) ;
130 noticiaColuna1 . getChildren () . add ( tecnologiaMenu ) ;
131 noticiaMenu . getChildren () . add ( noticiaColuna1 ) ;
132
133 Column noticiaColuna2 = new Column () ;
134 noticiaColuna2 . getChildren () . add ( educacaoMenu ) ;
135 noticiaMenu . getChildren () . add ( noticiaColuna2 ) ;
136
137 this . menuModel . addSubmenu ( noticiaMenu ) ;
138 }
139
140 public MenuModel getMenuModel () {

256 www.k19.com.br
257 P RIME FACES

141 return menuModel ;


142 }
143 }

Cdigo Java C.8: MegaMenuBean.java

Teste a aplicao acessando o endereo:

http://localhost:8080/K19-PrimeFaces/mega-menu.xhtml

Chart

Os componentes de charts permitem que grficos sejam criados de forma extremamente sim-
ples.

Exerccios de Fixao

23 Adicione uma pgina chamada chart.xhtml no projeto K19-PrimeFaces com o seguinte con-
tedo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : p = " http :// primefaces . org / ui " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12
13 <h : body >
14 <h : form >
15 <p : lineChart
16 value = " #{ chartBean . linearModel } "
17 legendPosition = " e "
18 animate = " true "
19 title = " Grfico de Linhas " / >
20
21 <p : barChart
22 value = " #{ chartBean . categoryModel } "
23 legendPosition = " ne "
24 animate = " true "
25 title = " Grfico de Barras " / >
26
27 <p : pieChart
28 value = " #{ chartBean . pieModel } "
29 legendPosition = " w "
30 title = " Libertadores " / >
31 </ h : form >
32 </ h : body >
33 </ html >

Cdigo XHTML C.11: chart.xhtml

www.facebook.com/k19treinamentos 257
P RIME FACES 258

24 Adicione uma classe chamada ChartBean em um pacote chamado br.com.k19.controle no


projeto K19-PrimeFaces com o seguinte contedo.

1 package br . com . k19 . controle ;


2
3 @ManagedBean
4 public class ChartBean {
5
6 private PieChartModel pieModel = new PieChartModel () ;
7 private CartesianChartModel categoryModel = new CartesianChartModel () ;;
8 private CartesianChartModel linearModel = new CartesianChartModel () ;;
9
10 public ChartBean () {
11 this . pieModel . set ( " So Paulo " , 3) ;
12 this . pieModel . set ( " Santos " , 3) ;
13 this . pieModel . set ( " Palmeiras " , 1) ;
14 this . pieModel . set ( " Corinthians " , 1) ;
15
16 ChartSeries serieA = new ChartSeries () ;
17 serieA . setLabel ( " A " ) ;
18
19 serieA . set ( " 2004 " , 10) ;
20 serieA . set ( " 2005 " , 200) ;
21 serieA . set ( " 2006 " , 77) ;
22 serieA . set ( " 2007 " , 13) ;
23 serieA . set ( " 2008 " , 177) ;
24
25 ChartSeries serieB = new ChartSeries () ;
26 serieB . setLabel ( " B " ) ;
27
28 serieB . set ( " 2004 " , 100) ;
29 serieB . set ( " 2005 " , 95) ;
30 serieB . set ( " 2006 " , 115) ;
31 serieB . set ( " 2007 " , 105) ;
32 serieB . set ( " 2008 " , 111) ;
33
34 categoryModel . addSeries ( serieA ) ;
35 categoryModel . addSeries ( serieB ) ;
36
37 LineChartSeries series1 = new LineChartSeries () ;
38 series1 . setLabel ( " 1 " ) ;
39
40 series1 . set (1 , 1) ;
41 series1 . set (2 , 2) ;
42 series1 . set (3 , 2) ;
43 series1 . set (4 , 7) ;
44 series1 . set (5 , 1) ;
45
46 LineChartSeries series2 = new LineChartSeries () ;
47 series2 . setLabel ( " 1 " ) ;
48
49 series2 . set (1 , 5) ;
50 series2 . set (2 , 6) ;
51 series2 . set (3 , 7) ;
52 series2 . set (4 , 1) ;
53 series2 . set (5 , 7) ;
54
55 linearModel . addSeries ( series1 ) ;
56 linearModel . addSeries ( series2 ) ;
57 }
58
59 // GETTERS E SETTERS
60 }

Cdigo Java C.9: ChartBean.java

Teste a aplicao acessando o endereo:

258 www.k19.com.br
259 P RIME FACES

http://localhost:8080/K19-PrimeFaces/chart.xhtml

www.facebook.com/k19treinamentos 259
P RIME FACES 260

260 www.k19.com.br
APNDICE
P ROJETO F UTEBOL K19
D
Para consolidar o conhecimento obtido durante o treinamento, desenvolveremos uma aplica-
o 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.

Integrao JSF e JPA

Criaremos uma aplicao web Java com JSF e adicionaremos os recursos do JPA nessa aplicao
como foi visto no Captulo 13.

Exerccios de Fixao

1 Entre na pasta K19-Arquivos/mysql-connector-java-VERSAO da rea de Trabalho e copie o


arquivo mysql-connector-java-VERSAO-bin.jar para pasta glassfish4/glassfish/lib tambm da sua
rea de Trabalho. OBS: O Glassfish deve ser reiniciado para reconhecer o driver JDBC do MySQL.

2 Crie um projeto chamado K19-Futebol seguindo os passos vistos no exerccio do Captulo 5.

3 Adicione uma pasta chamada META-INF no classpath do projeto K19-Futebol. A pasta META-
INF deve ser salva na pasta src.

4 Configure o JPA adicionando o arquivo persistence.xml na pasta META-INF.

1 <? xml version = " 1.0 " encoding = " UTF -8 " ? >
2 < persistence
3 version = " 2.1 "
4 xmlns = " http: // xmlns . jcp . org / xml / ns / persistence "
5 xmlns:xsi = " http: // www . w3 . org /2001/ XMLSchema - instance "
6 xsi:schemaLocation = " http: // xmlns . jcp . org / xml / ns / persistence
7 http: // xmlns . jcp . org / xml / ns / persistence / persistence_2_1 . xsd " >
8
9 < persistence - unit name = " K19 - Futebol - PU " transaction - type = " RESOURCE_LOCAL " >
10 < provider > org . hibernate . ejb . HibernatePersistence </ provider >
11 < properties >
12 < property
13 name = " hibernate . dialect "
14 value = " org . hibernate . dialect . MySQL5InnoDBDialect " / >
15

www.facebook.com/k19treinamentos 261
P ROJETO F UTEBOL K19 262

16 < property
17 name = " hibernate . hbm2ddl . auto "
18 value = " update " / >
19
20 < property
21 name = " javax . persistence . jdbc . driver "
22 value = " com . mysql . jdbc . Driver " / >
23
24 < property
25 name = " javax . persistence . jdbc . user "
26 value = " root " / >
27
28 < property
29 name = " javax . persistence . jdbc . password "
30 value = " root " / >
31
32 < property
33 name = " javax . persistence . jdbc . url "
34 value = " jdbc:mysql: // localhost:3306 / K19 - Futebol - DB " / >
35 </ properties >
36 </ persistence - unit >
37 </ persistence >

Cdigo XML D.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 )

6 Crie um pacote chamado br.com.k19.filters no projeto K19-Futebol.

7 No pacote br.com.k19.filters, crie uma classe chamada JPAFilter com o seguinte contedo:

1 package br . com . k19 . filters ;


2
3 import java . io . IOException ;
4 import javax . persistence . EntityManager ;
5 import javax . persistence . EntityManagerFactory ;
6 import javax . persistence . Persistence ;
7 import javax . servlet . Filter ;
8 import javax . servlet . FilterChain ;
9 import javax . servlet . FilterConfig ;
10 import javax . servlet . ServletException ;
11 import javax . servlet . ServletRequest ;
12 import javax . servlet . ServletResponse ;
13 import javax . servlet . annotation . WebFilter ;
14
15 @WebFilter ( servletNames ={ " Faces Servlet " })

262 www.k19.com.br
263 P ROJETO F UTEBOL K19

16 public class JPAFilter implements Filter {


17
18 private EntityManagerFactory factory ;
19
20 @Override
21 public void init ( FilterConfig filterConfig ) throws ServletException {
22 this . factory = Persistence . createEntityManagerFactory ( " K19 - Futebol - PU " ) ;
23 }
24
25 @Override
26 public void destroy () {
27 this . factory . close () ;
28 }
29
30 @Override
31 public void doFilter ( ServletRequest request , ServletResponse response ,
32 FilterChain chain ) throws IOException , ServletException {
33
34 // CHEGADA
35 EntityManager manager = this . factory . createEntityManager () ;
36 request . setAttribute ( " EntityManager " , manager ) ;
37 manager . getTransaction () . begin () ;
38 // CHEGADA
39
40 // FACES SERVLET
41 chain . doFilter ( request , response ) ;
42 // FACES SERVLET
43
44 // SADA
45 try {
46 manager . getTransaction () . commit () ;
47 } catch ( Exception e ) {
48 manager . getTransaction () . rollback () ;
49 } finally {
50 manager . close () ;
51 }
52 // SADA
53 }
54 }

Cdigo Java D.1: JPAFilter.java

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 relaciona-
das persistncia dessas duas entidades.

Exerccios de Fixao

8 Crie um pacote chamado br.com.k19.modelo no projeto K19-Futebol. Depois crie um subpa-


cote chamado entidades.

9 No pacote br.com.k19.modelo.entidades, crie duas classes para modelar times e jogadores.

1 package br . com . k19 . modelo . entidades ;


2

www.facebook.com/k19treinamentos 263
P ROJETO F UTEBOL K19 264

3 import javax . persistence . Entity ;


4 import javax . persistence . GeneratedValue ;
5 import javax . persistence . Id ;
6
7 @Entity
8 public class Time {
9
10 @Id @GeneratedValue
11 private Long id ;
12
13 private String nome ;
14
15 private String tecnico ;
16
17 // GETTERS E SETTERS
18 }

Cdigo Java D.2: Time.java

1 package br . com . k19 . modelo . entidades ;


2
3 import java . util . Calendar ;
4 import java . util . GregorianCalendar ;
5 import javax . persistence . Entity ;
6 import javax . persistence . GeneratedValue ;
7 import javax . persistence . Id ;
8 import javax . persistence . ManyToOne ;
9
10 @Entity
11 public class Jogador {
12
13 @Id @GeneratedValue
14 private Long id ;
15
16 private String nome ;
17
18 private String posicao ;
19
20 private Calendar dataDeNascimento = new GregorianCalendar () ;
21
22 @ManyToOne
23 private Time time ;
24
25 // GETTERS E SETTERS
26 }

Cdigo Java D.3: Jogador.java

10 Dentro do pacote br.com.k19.modelo crie um pacote chamado repositorios.

11 No pacote br.com.k19.modelo.repositorios, implemente as classes JogadorRepository e Time-


Repository.

1 package br . com . k19 . modelo . repositorios ;


2
3 import br . com . k19 . modelo . entidades . Jogador ;
4 import java . util . List ;
5 import javax . persistence . EntityManager ;
6 import javax . persistence . Query ;
7
8 public class JogadorRepository {
9
10 private EntityManager manager ;
11

264 www.k19.com.br
265 P ROJETO F UTEBOL K19

12 public JogadorRepository ( EntityManager manager ) {


13 this . manager = manager ;
14 }
15
16 public void adiciona ( Jogador jogador ) {
17 this . manager . persist ( jogador ) ;
18 }
19
20 public void remove ( Long id ) {
21 Jogador jogador = this . procura ( id ) ;
22 this . manager . remove ( jogador ) ;
23 }
24
25 public Jogador atualiza ( Jogador jogador ) {
26 return this . manager . merge ( jogador ) ;
27 }
28
29 public Jogador procura ( Long id ) {
30 return this . manager . find ( Jogador . class , id ) ;
31 }
32
33 public List < Jogador > getLista () {
34 Query query = this . manager . createQuery ( " select x from Jogador x " ) ;
35 return query . getResultList () ;
36 }
37 }

Cdigo Java D.4: JogadorRepository.java

1 package br . com . k19 . modelo . repositorios ;


2
3 import br . com . k19 . modelo . entidades . Jogador ;
4 import br . com . k19 . modelo . entidades . Time ;
5 import java . util . List ;
6 import javax . persistence . EntityManager ;
7 import javax . persistence . Query ;
8
9 public class TimeRepository {
10
11 private EntityManager manager ;
12
13 public TimeRepository ( EntityManager manager ) {
14 this . manager = manager ;
15 }
16
17 public void adiciona ( Time time ) {
18 this . manager . persist ( time ) ;
19 }
20
21 public void remove ( Long id ) {
22 Time time = this . procura ( id ) ;
23 Query query = this . manager . createQuery ( " select x from Jogador x where x . time = : -
time " ) ;
24 query . setParameter ( " time " , time ) ;
25 List < Jogador > jogadores = query . getResultList () ;
26 for ( Jogador jogador : jogadores ) {
27 jogador . setTime ( null ) ;
28 }
29 this . manager . remove ( time ) ;
30 }
31
32 public Time atualiza ( Time time ) {
33 return this . manager . merge ( time ) ;
34 }
35
36 public Time procura ( Long id ) {
37 return this . manager . find ( Time . class , id ) ;
38 }
39

www.facebook.com/k19treinamentos 265
P ROJETO F UTEBOL K19 266

40 public List < Time > getLista () {


41 Query query = this . manager . createQuery ( " select x from Time x " ) ;
42 return query . getResultList () ;
43 }
44 }

Cdigo Java D.5: TimeRepository.java

Managed Beans

Na camada de controle, implementaremos managed beans para controlar as operaes relacio-


nadas s entidades Jogador e Time.

Exerccios de Fixao

12 Crie um pacote chamado br.com.k19.controle no projeto K19-Futebol.

13 No pacote br.com.k19.controle, implemente uma classe chamada TimeBean.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . entidades . Time ;
4 import br . com . k19 . modelo . repositorios . TimeRepository ;
5 import java . util . List ;
6 import java . util . Map ;
7 import javax . faces . bean . ManagedBean ;
8 import javax . faces . context . ExternalContext ;
9 import javax . faces . context . FacesContext ;
10 import javax . persistence . EntityManager ;
11 import javax . servlet . http . HttpServletRequest ;
12
13 @ManagedBean
14 public class TimeBean {
15
16 private Time time = new Time () ;
17 private List < Time > times ;
18
19 public void adiciona () {
20 EntityManager manager = this . getManager () ;
21 TimeRepository repository = new TimeRepository ( manager ) ;
22 if ( this . time . getId () == null ) {
23 repository . adiciona ( this . time ) ;
24 } else {
25 repository . atualiza ( this . time ) ;
26 }
27 this . time = new Time () ;
28 this . times = null ;
29 }
30
31 public void preparaAlteracao () {
32 Map < String , String > params =
33 FacesContext . getCurrentInstance () . getExternalContext () . -
getRequestParameterMap () ;
34 Long id = Long . parseLong ( params . get ( " id " ) ) ;
35 EntityManager manager = this . getManager () ;
36 TimeRepository repository = new TimeRepository ( manager ) ;
37 this . time = repository . procura ( id ) ;

266 www.k19.com.br
267 P ROJETO F UTEBOL K19

38 }
39
40 public void remove () {
41 Map < String , String > params =
42 FacesContext . getCurrentInstance () . getExternalContext () . -
getRequestParameterMap () ;
43 Long id = Long . parseLong ( params . get ( " id " ) ) ;
44 EntityManager manager = this . getManager () ;
45 TimeRepository repository = new TimeRepository ( manager ) ;
46 repository . remove ( id ) ;
47 this . times = null ;
48 }
49
50 public List < Time > getTimes () {
51 if ( this . times == null ) {
52 EntityManager manager = this . getManager () ;
53 TimeRepository repository = new TimeRepository ( manager ) ;
54 this . times = repository . getLista () ;
55 }
56 return this . times ;
57 }
58
59 private EntityManager getManager () {
60 FacesContext fc = FacesContext . getCurrentInstance () ;
61 ExternalContext ec = fc . getExternalContext () ;
62 HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
63 return ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
64 }
65
66 // GETTERS E SETTERS
67 }

Cdigo Java D.6: TimeBean.java

14 No pacote br.com.k19.controle, implemente uma classe chamada JogadorBean.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . entidades . Jogador ;
4 import br . com . k19 . modelo . entidades . Time ;
5 import br . com . k19 . modelo . repositorios . JogadorRepository ;
6 import br . com . k19 . modelo . repositorios . TimeRepository ;
7 import java . util . List ;
8 import java . util . Map ;
9 import javax . faces . bean . ManagedBean ;
10 import javax . faces . context . ExternalContext ;
11 import javax . faces . context . FacesContext ;
12 import javax . persistence . EntityManager ;
13 import javax . servlet . http . HttpServletRequest ;
14
15 @ManagedBean
16 public class JogadorBean {
17
18 private Jogador jogador = new Jogador () ;
19
20 private Long timeID ;
21
22 private List < Jogador > jogadores ;
23
24 public void adiciona () {
25 EntityManager manager = this . getManager () ;
26 TimeRepository timeRepository = new TimeRepository ( manager ) ;
27 JogadorRepository jogadorRepository = new JogadorRepository ( manager ) ;
28
29 if ( this . timeID != null ) {
30 Time time = timeRepository . procura ( this . timeID ) ;
31 this . jogador . setTime ( time ) ;

www.facebook.com/k19treinamentos 267
P ROJETO F UTEBOL K19 268

32 }
33
34 if ( this . jogador . getId () == null ) {
35 jogadorRepository . adiciona ( this . jogador ) ;
36
37 } else {
38 jogadorRepository . atualiza ( this . jogador ) ;
39 }
40
41 this . jogador = new Jogador () ;
42 this . jogadores = null ;
43 }
44
45 public void preparaAlteracao () {
46 Map < String , String > params =
47 FacesContext . getCurrentInstance () . getExternalContext () . -
getRequestParameterMap () ;
48 Long id = Long . parseLong ( params . get ( " id " ) ) ;
49 EntityManager manager = this . getManager () ;
50 JogadorRepository repository = new JogadorRepository ( manager ) ;
51 this . jogador = repository . procura ( id ) ;
52 }
53
54 public void remove () {
55 Map < String , String > params =
56 FacesContext . getCurrentInstance () . getExternalContext () . -
getRequestParameterMap () ;
57 Long id = Long . parseLong ( params . get ( " id " ) ) ;
58 EntityManager manager = this . getManager () ;
59 JogadorRepository repository = new JogadorRepository ( manager ) ;
60 repository . remove ( id ) ;
61 this . jogadores = null ;
62 }
63
64 public List < Jogador > getJogadores () {
65 if ( this . jogadores == null ) {
66 EntityManager manager = this . getManager () ;
67 JogadorRepository repository = new JogadorRepository ( manager ) ;
68 this . jogadores = repository . getLista () ;
69 }
70 return this . jogadores ;
71 }
72
73 private EntityManager getManager () {
74 FacesContext fc = FacesContext . getCurrentInstance () ;
75 ExternalContext ec = fc . getExternalContext () ;
76 HttpServletRequest request = ( HttpServletRequest ) ec . getRequest () ;
77 return ( EntityManager ) request . getAttribute ( " EntityManager " ) ;
78 }
79
80 // GETTERS E SETTERS
81 }

Cdigo Java D.7: JogadorBean.java

Telas

Vamos implementar a camada de apresentao da nossa aplicao. Criaremos algumas telas


usando templates e telas parciais.

Exerccios de Fixao

268 www.k19.com.br
269 P ROJETO F UTEBOL K19

15 Adicione o diretrio resources no projeto K19-Futebol. Nesse diretrio, crie diretrios chama-
dos css e imagens. O diretrio resources deve ser salvo em WebContent

16 No diretrio resources/css, crie um arquivo chamado style.css com o seguinte contedo:

1 body {
2 font : 18 px Arial ;
3 margin : 0 0 0 0;
4 background - color :# EEEEEE ;
5 }
6
7 h1 {
8 margin : 0;
9 padding : 16 px 0;
10 color : #000000;
11 font : bold 40 px Arial ;
12 }
13
14 h2 {
15 font : bold 24 px Arial ;
16 color : #595959;
17 }
18
19 a {
20 color : #3 a34c3 ;
21 text - decoration : none ;
22 }
23
24 a : hover {
25 text - decoration : underline ;
26 }
27
28 . dados {
29 border - collapse : collapse ;
30 }
31
32 . dados td ,. dados th {
33 border : 1 px solid #0000 c6 ;
34 padding : 3 px 7 px 2 px 7 px ;
35 }
36
37 . dados th {
38 padding - top : 5 px ;
39 padding - bottom : 4 px ;
40 background - color : #156 bbd ;
41 color : # ffffff ;
42 }
43
44 . dados tr . impar td {
45 color : #000000;
46 background - color : # d4d4d9 ;
47 }
48
49 . dados tr . par td {
50 color : #000000;
51 background - color : # f6f6fa ;
52 }
53
54 input {
55 font - size : 16 px ;
56 border : 1 px solid #0000 c6 ;
57 background - color : # f6f6fa ;
58 }
59
60 # header {
61 color : # FFFFFF ;
62 background - color : #252525;

www.facebook.com/k19treinamentos 269
P ROJETO F UTEBOL K19 270

63 padding : 10 px 0 px 28 px 10 px ;
64 }
65
66 # header a {
67 color : # FFFFFF ;
68 font : bold 24 px Arial ;
69 }
70
71 # conteudo {
72 margin : 0 px 0 px 50 px 10 px ;
73 }

Cdigo CSS D.1: style.css

17 Copie o arquivo k19-logo.png da pasta K19-Arquivos/imagens da rea de Trabalho para a pasta


resources/imagens.

Importante
Voc tambm pode obter o arquivo k19-logo.png atravs do site da K19: www.k19.
com.br/arquivos.

18 Na pasta WEB-INF, crie um diretrio chamado templates.

19 No diretrio WEB-INF/templates, crie um arquivo chamado template.xhtml com o seguinte


contedo:

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets "
6 xmlns : h = " http :// java . sun . com / jsf / html " >
7
8 <h : head >
9 < title > K19 Futebol </ title >
10 </ h : head >
11
12 <h : body >
13 <h : outputStylesheet library = " css " name = " style . css " / >
14
15 < div id = " header " >
16 <h : form style = " float : left ; " >
17 <h : link value = " Times " outcome = " times " / >
18 & nbsp ;
19 <h : link value = " Jogadores " outcome = " jogadores " / >
20 </ h : form >
21 <h : graphicImage library = " imagens " name = " k19 - logo . png " style = " float : right ; " / >
22 < div style = " clear : both " > </ div >
23 </ div >
24
25 < div id = " conteudo " >
26 < ui : insert name = " conteudo " > Espao para o contedo da tela </ ui : insert >
27 </ div >
28
29 < div id = " footer " style = " text - align : center " >
30 < hr / >
31 & copy ; 2012 K19 . Todos os direitos reservados .
32 </ div >

270 www.k19.com.br
271 P ROJETO F UTEBOL K19

33 </ h : body >


34 </ html >

Cdigo XHTML D.1: template.xhtml

20 Crie uma pgina chamada times.xhtml no projeto K19-Futebol com o contedo abaixo.

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core " >
6
7 < ui : define name = " conteudo " >
8
9 < h1 > Times </ h1 >
10
11 <h : form >
12 < ui : include src = " / WEB - INF / partials / formulario - novo - time . xhtml " / >
13 < ui : include src = " / WEB - INF / partials / lista - de - times . xhtml " / >
14 </ h : form >
15 </ ui : define >
16 </ ui : composition >

Cdigo XHTML D.2: times.xhtml

21 Na pasta WEB-INF, crie um diretrio chamado partials.

22 Na pasta WEB-INF/partials, crie as telas parciais definidas pelos arquivos formulario-novo-ti-

me.xhtml e lista-de-times.xhtml.

1 < ui : composition
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core " >
6
7 <h : inputHidden value = " #{ timeBean . time . id } " / >
8 <h : panelGrid columns = " 3 " >
9 <h : outputLabel value = " Nome : " for = " nome " / >
10 <h : inputText
11 id = " nome "
12 required = " true "
13 requiredMessage = " O nome do time obrigatrio "
14 value = " #{ timeBean . time . nome } " >
15 </ h : inputText >
16 <h : message for = " nome " / >
17
18 <h : outputLabel value = " Tcnico : " for = " tecnico " / >
19 <h : inputText
20 id = " tecnico "
21 required = " true "
22 requiredMessage = " O nome do tcnico obrigatrio "
23 value = " #{ timeBean . time . tecnico } " >
24 </ h : inputText >
25 <h : message for = " tecnico " / >
26
27 <h : commandButton value = " Cadastrar " >
28 <f : ajax
29 event = " click "
30 execute = " @form "
31 listener = " #{ timeBean . adiciona } "

www.facebook.com/k19treinamentos 271
P ROJETO F UTEBOL K19 272

32 render = " @all " / >


33 </ h : commandButton >
34 </ h : panelGrid >
35 </ ui : composition >

Cdigo XHTML D.3: formulario-novo-time.xhtml

1 < ui : composition
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core " >
6
7 <h : panelGroup rendered = " #{ not empty timeBean . times } " >
8 < h2 > Lista de Times </ h2 >
9
10 <h : dataTable
11 id = " tabela "
12 value = " #{ timeBean . times } "
13 var = " time "
14 styleClass = " dados "
15 rowClasses = " par , impar " >
16
17 <h : column >
18 <f : facet name = " header " >
19 <h : outputText value = " Id " / >
20 </ f: facet >
21 #{ time . id }
22 </ h : column >
23
24 <h : column >
25 <f : facet name = " header " >
26 <h : outputText value = " Nome " / >
27 </ f: facet >
28 #{ time . nome }
29 </ h : column >
30
31 <h : column >
32 <f : facet name = " header " >
33 <h : outputText value = " Tcnico " / >
34 </ f: facet >
35 #{ time . tecnico }
36 </ h : column >
37
38 <h : column >
39 <f : facet name = " header " >
40 <h : outputText value = " Alterar " / >
41 </ f: facet >
42
43 <f : ajax
44 event = " click "
45 render = " @form "
46 listener = " #{ timeBean . preparaAlteracao } " >
47 <h : commandLink >
48 <f : param name = " id " value = " #{ time . id } " / >
49 Alterar
50 </ h : commandLink >
51 </ f: ajax >
52 </ h : column >
53
54 <h : column >
55 <f : facet name = " header " >
56 <h : outputText value = " Remover " / >
57 </ f: facet >
58
59 <f : ajax
60 event = " click "
61 render = " @form "
62 listener = " #{ timeBean . remove } " >

272 www.k19.com.br
273 P ROJETO F UTEBOL K19

63 <h : commandLink >


64 <f : param name = " id " value = " #{ time . id } " / >
65 Remover
66 </ h : commandLink >
67 </ f: ajax >
68 </ h : column >
69 </ h : dataTable >
70 </ h : panelGroup >
71 </ ui : composition >

Cdigo XHTML D.4: lista-de-times.xhtml

23 Crie uma pgina chamada jogadores.xhtml no projeto K19-Futebol com o contedo abaixo.

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core " >
6
7 < ui : define name = " conteudo " >
8
9 < h1 > Jogadores </ h1 >
10
11 <h : form >
12 < ui : include src = " / WEB - INF / partials / formulario - novo - jogador . xhtml " / >
13 < ui : include src = " / WEB - INF / partials / lista - de - jogadores . xhtml " / >
14 </ h : form >
15 </ ui : define >
16 </ ui : composition >

Cdigo XHTML D.5: jogadores.xhtml

24 Na pasta WEB-INF/partials, crie as telas parciais definidas pelos arquivos formulario-novo-jo-

gador.xhtml e lista-de-jogadores.xhtml.

1 < ui : composition
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core " >
6
7 <h : inputHidden value = " #{ jogadorBean . jogador . id } " / >
8 <h : panelGrid columns = " 3 " >
9 <h : outputLabel value = " Nome : " for = " jogador - nome " / >
10 <h : inputText
11 id = " jogador - nome "
12 required = " true "
13 requiredMessage = " O nome do jogador obrigatrio "
14 value = " #{ jogadorBean . jogador . nome } " >
15 </ h : inputText >
16 <h : message for = " jogador - nome " / >
17
18 <h : outputLabel value = " Posio : " for = " jogador - posicao " / >
19 <h : inputText
20 id = " jogador - posicao "
21 required = " true "
22 requiredMessage = " A posio do jogador deve ser especificada "
23 value = " #{ jogadorBean . jogador . posicao } " >
24 </ h : inputText >
25 <h : message for = " jogador - posicao " / >
26
27 <h : outputLabel value = " Data de Nascimento : " for = " jogador - nascimento " / >
28 <h : inputText

www.facebook.com/k19treinamentos 273
P ROJETO F UTEBOL K19 274

29 id = " jogador - nascimento "


30 required = " true "
31 requiredMessage = " Informe a data de nascimento do jogador "
32 value = " #{ jogadorBean . jogador . dataDeNascimento . time } " >
33 <f : convertDateTime pattern = " dd / MM / yyyy " / >
34 </ h : inputText >
35 <h : message for = " jogador - nascimento " / >
36
37 <h : outputLabel value = " Time : " for = " jogador - time " / >
38 <h : selectOneMenu id = " jogador - time " value = " #{ jogadorBean . timeID } " >
39 <f : selectItems
40 value = " #{ timeBean . times } "
41 var = " time "
42 itemLabel = " #{ time . nome } "
43 itemValue = " #{ time . id } " / >
44 </ h : selectOneMenu >
45 <h : message for = " jogador - time " / >
46
47 <h : commandButton value = " Cadastrar " styleClass = " botao - formulario " >
48 <f : ajax
49 event = " click "
50 execute = " @form "
51 listener = " #{ jogadorBean . adiciona } "
52 render = " @form " / >
53 </ h : commandButton >
54 </ h : panelGrid >
55 </ ui : composition >

Cdigo XHTML D.6: formulario-novo-jogador.xhtml

1 < ui : composition
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core " >
6
7 <h : panelGroup rendered = " #{ not empty jogadorBean . jogadores } " >
8 < h2 > Lista de Jogadores </ h2 >
9
10 <h : dataTable
11 id = " tabela "
12 value = " #{ jogadorBean . jogadores } "
13 var = " jogador "
14 styleClass = " dados " rowClasses = " par , impar " >
15
16 <h : column >
17 <f : facet name = " header " >
18 <h : outputText value = " Id " / >
19 </ f: facet >
20 #{ jogador . id }
21 </ h : column >
22
23 <h : column >
24 <f : facet name = " header " >
25 <h : outputText value = " Nome " / >
26 </ f: facet >
27 #{ jogador . nome }
28 </ h : column >
29
30 <h : column >
31 <f : facet name = " header " >
32 <h : outputText value = " Posio " / >
33 </ f: facet >
34 #{ jogador . posicao }
35 </ h : column >
36
37 <h : column >
38 <f : facet name = " header " >
39 <h : outputText value = " Data de Nascimento " / >

274 www.k19.com.br
275 P ROJETO F UTEBOL K19

40 </ f: facet >


41
42 <h : outputText value = " #{ jogador . dataDeNascimento . time } " >
43 <f : convertDateTime pattern = " dd / MM / yyyy " / >
44 </ h: outputText >
45 </ h : column >
46
47 <h : column >
48 <f : facet name = " header " >
49 <h : outputText value = " Time " / >
50 </ f: facet >
51 #{ jogador . time . nome }
52 </ h : column >
53
54 <h : column >
55 <f : facet name = " header " >
56 <h : outputText value = " Alterar " / >
57 </ f: facet >
58
59 <f : ajax
60 event = " click "
61 render = " @form "
62 listener = " #{ jogadorBean . preparaAlteracao } " >
63 <h : commandLink >
64 <f : param name = " id " value = " #{ jogador . id } " / >
65 Alterar
66 </ h : commandLink >
67 </ f: ajax >
68 </ h : column >
69
70 <h : column >
71 <f : facet name = " header " >
72 <h : outputText value = " Remover " / >
73 </ f: facet >
74
75 <f : ajax
76 event = " click "
77 render = " @form "
78 listener = " #{ jogadorBean . remove } " >
79 <h : commandLink >
80 <f : param name = " id " value = " #{ jogador . id } " / >
81 Remover
82 </ h : commandLink >
83 </ f: ajax >
84 </ h : column >
85 </ h : dataTable >
86 </ h : panelGroup >
87 </ ui : composition >

Cdigo XHTML D.7: lista-de-jogadores.xhtml

25 Implante o projeto K19-Futebol no Glassfish. Certifique-se que o Wildfly esteja parado. Inicie o
Glassfish e acesse o endereo abaixo para testar a aplicao.

http://localhost:8080/K19-Futebol/times.xhtml

Autenticao

Vamos acrescentar um controle de segurana nossa aplicao como vimos no Apndice A.

Exerccio 26

www.facebook.com/k19treinamentos 275
P ROJETO F UTEBOL K19 276

No pacote br.com.k19.controle, crie um managed bean de autenticao chamado Autentica-


dorBean.

1 package br . com . k19 . controle ;


2
3 import java . util . HashMap ;
4 import java . util . Map ;
5 import javax . faces . application . FacesMessage ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . context . ExternalContext ;
8 import javax . faces . context . FacesContext ;
9 import javax . servlet . http . HttpSession ;
10
11 @ManagedBean
12 public class AutenticadorBean {
13
14 private static Map < String , String > mapa = new HashMap < String , String >() ;
15
16 private String usuario ;
17
18 private String senha ;
19
20 static {
21 AutenticadorBean . mapa . put ( " k19 " , " k19 " ) ;
22 AutenticadorBean . mapa . put ( " jonas . hirata " , " jonas . hirata " ) ;
23 AutenticadorBean . mapa . put ( " marcelo . martins " , " marcelo . martins " ) ;
24 AutenticadorBean . mapa . put ( " rafael . cosentino " , " rafael . cosentino " ) ;
25 }
26
27 public String autentica () {
28 FacesContext fc = FacesContext . getCurrentInstance () ;
29
30 if ( AutenticadorBean . mapa . containsKey ( this . usuario )
31 && AutenticadorBean . mapa . get ( this . usuario ) . equals ( this . senha ) ) {
32
33 ExternalContext ec = fc . getExternalContext () ;
34 HttpSession session = ( HttpSession ) ec . getSession ( false ) ;
35 session . setAttribute ( " usuario " , this . usuario ) ;
36
37 return " / times " ;
38 } else {
39 FacesMessage fm = new FacesMessage ( " usurio e / ou senha invlidos " ) ;
40 fm . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
41 fc . addMessage ( null , fm ) ;
42 return " / login " ;
43 }
44 }
45
46 public String registraSaida () {
47 FacesContext fc = FacesContext . getCurrentInstance () ;
48 ExternalContext ec = fc . getExternalContext () ;
49 HttpSession session = ( HttpSession ) ec . getSession ( false ) ;
50 session . removeAttribute ( " usuario " ) ;
51
52 return " / login " ;
53 }
54
55 // GETTERS E SETTERS
56 }

Cdigo Java D.8: AutenticadorBean.java

Exerccio 27

No pacote br.com.k19.filters, implemente um filtro para o controle de acesso.

1 package br . com . k19 . filters ;

276 www.k19.com.br
277 P ROJETO F UTEBOL K19

2
3 import java . io . IOException ;
4 import javax . servlet . Filter ;
5 import javax . servlet . FilterChain ;
6 import javax . servlet . FilterConfig ;
7 import javax . servlet . ServletException ;
8 import javax . servlet . ServletRequest ;
9 import javax . servlet . ServletResponse ;
10 import javax . servlet . annotation . WebFilter ;
11 import javax . servlet . http . HttpServletRequest ;
12 import javax . servlet . http . HttpServletResponse ;
13 import javax . servlet . http . HttpSession ;
14
15 @WebFilter ( servletNames ={ " Faces Servlet " })
16 public class ControleDeAcesso implements Filter {
17
18 @Override
19 public void doFilter ( ServletRequest request , ServletResponse response ,
20 FilterChain chain ) throws IOException , ServletException {
21
22 HttpServletRequest req = ( HttpServletRequest ) request ;
23 HttpSession session = req . getSession () ;
24
25 if ( session . getAttribute ( " usuario " ) != null
26 || req . getRequestURI () . endsWith ( " login . xhtml " ) ) {
27 chain . doFilter ( request , response ) ;
28 } else {
29 HttpServletResponse res = ( HttpServletResponse ) response ;
30 res . sendRedirect ( " login . xhtml " ) ;
31 }
32 }
33
34 @Override
35 public void init ( FilterConfig filterConfig ) throws ServletException {
36
37 }
38
39 @Override
40 public void destroy () {
41
42 }
43 }

Cdigo Java D.9: ControleDeAcesso.java

Exerccio 28

Crie uma pgina chamada login.xhtml e implemente o formulrio de autenticao.

1 < ui : composition template = " / WEB - INF / templates / template . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : ui = " http :// java . sun . com / jsf / facelets "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core " >
6
7 < ui : define name = " conteudo " >
8 <p > Preencha o formulrio abaixo para entrar no sistema . </ p >
9 <h : form >
10 <h : panelGrid columns = " 2 " >
11 <h : outputLabel value = " Usurio : " for = " campo - usuario " / >
12 <h : inputText value = " #{ autenticadorBean . usuario } " id = " campo - usuario " / >
13
14 <h : outputLabel value = " Senha : " for = " campo - senha " / >
15 <h : inputSecret value = " #{ autenticadorBean . senha } " id = " campo - senha " / >
16 </ h : panelGrid >
17
18 <h : commandButton value = " Entrar " action = " #{ autenticadorBean . autentica } " / >
19 </ h : form >

www.facebook.com/k19treinamentos 277
P ROJETO F UTEBOL K19 278

20
21 <h : messages / >
22 </ ui : define >
23 </ ui : composition >

Cdigo XHTML D.8: login.xhtml

Exerccio 29

No arquivo template.xhtml, acrescente um link para o usurio fazer logout. O menu de navega-
o deve ser exibido apenas se o usurio estiver logado.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets "
6 xmlns : h = " http :// java . sun . com / jsf / html "
7 xmlns : f = " http :// java . sun . com / jsf / core " >
8
9 <h : head >
10 < title > K19 Futebol </ title >
11 </ h : head >
12
13 <h : body >
14 <h : outputStylesheet library = " css " name = " style . css " / >
15
16 < div id = " header " >
17 <h : form style = " float : left ; " rendered = " #{ not empty sessionScope . usuario } " >
18 <h : link value = " Times " outcome = " times " / >
19 & nbsp ;
20 <h : link value = " Jogadores " outcome = " jogadores " / >
21 & nbsp ;
22 <h : commandLink value = " Logout " action = " #{ autenticadorBean . registraSaida } " / >
23 </ h : form >
24 <h : graphicImage library = " imagens " name = " k19 - logo . png " style = " float : right ; " / >
25 < div style = " clear : both " > </ div >
26 </ div >
27
28 < div id = " conteudo " >
29 < ui : insert name = " conteudo " > Espao para o contedo da tela </ ui : insert >
30 </ div >
31
32 < div id = " footer " style = " text - align : center " >
33 < hr / >
34 & copy ; 2012 K19 . Todos os direitos reservados .
35 </ div >
36 </ h : body >
37 </ html >

Cdigo XHTML D.9: template.xhtml

Exerccio 30

Acessa a aplicao no endereo:

http://localhost:8080/K19-Futebol/login.xhtml

278 www.k19.com.br
APNDICE
R ESPOSTAS
E
Exerccio Complementar 2.1

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . PreparedStatement ;
6 import java . util . Scanner ;
7
8 public class InsereLivro {
9 public static void main ( String [] args ) {
10 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
11 String usuario = " root " ;
12 String senha = " root " ;
13
14 try {
15 System . out . println ( " Abrindo conexo ... " ) ;
16 Connection conexao =
17 DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
18
19 Scanner entrada = new Scanner ( System . in ) ;
20
21 System . out . println ( " Digite o ttulo do livro : " ) ;
22 String titulo = entrada . nextLine () ;
23
24 System . out . println ( " Digite o preo do livro : " ) ;
25 String preco = entrada . nextLine () ;
26
27 System . out . println ( " Digite o id da editora do livro : " ) ;
28 String id = entrada . nextLine () ;
29
30 entrada . close () ;
31
32 String sql = " INSERT INTO Livro ( titulo , preco , editora_id ) " +
33 " VALUES ( " + titulo + " , " + preco + " , " + id + " ) " ;
34
35 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
36
37 System . out . println ( " Executando comando ... " ) ;
38 comando . execute () ;
39
40 System . out . println ( " Fechando conexo ... " ) ;
41 conexao . close () ;
42 }
43 catch ( Exception e ) {
44 e . printStackTrace () ;
45 }
46 }
47 }

Cdigo Java 2.7: InsereLivro.java

Exerccio Complementar 2.3

www.facebook.com/k19treinamentos 279
R ESPOSTAS 280

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . PreparedStatement ;
6 import java . util . Scanner ;
7
8 public class InsereLivro {
9 public static void main ( String [] args ) {
10 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
11 String usuario = " root " ;
12 String senha = " root " ;
13
14 try {
15 System . out . println ( " Abrindo conexo ... " ) ;
16 Connection conexao =
17 DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
18
19 Scanner entrada = new Scanner ( System . in ) ;
20
21 System . out . println ( " Digite o ttulo do livro : " ) ;
22 String titulo = entrada . nextLine () ;
23
24 System . out . println ( " Digite o preo do livro : " ) ;
25 String preco = entrada . nextLine () ;
26
27 System . out . println ( " Digite o id da editora do livro : " ) ;
28 String id = entrada . nextLine () ;
29
30 entrada . close () ;
31
32 String sql = " INSERT INTO Livro ( titulo , preco , editora_id ) " +
33 " VALUES (? , ? , ?) " ;
34
35 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
36 comando . setString (1 , titulo ) ;
37 comando . setString (2 , preco ) ;
38 comando . setString (3 , id ) ;
39
40 System . out . println ( " Executando comando ... " ) ;
41 comando . execute () ;
42
43 System . out . println ( " Fechando conexo ... " ) ;
44 conexao . close () ;
45 }
46 catch ( Exception e ) {
47 e . printStackTrace () ;
48 }
49 }
50 }

Cdigo Java 2.12: InsereLivro.java

Exerccio Complementar 2.5

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . DriverManager ;
5 import java . sql . PreparedStatement ;
6 import java . sql . ResultSet ;
7

280 www.k19.com.br
281 R ESPOSTAS

8 public class ListaLivros {


9 public static void main ( String [] args ) {
10 String stringDeConexao = " jdbc : mysql :// localhost :3306/ livraria " ;
11 String usuario = " root " ;
12 String senha = " root " ;
13
14 try {
15 System . out . println ( " Abrindo conexo ... " ) ;
16 Connection conexao =
17 DriverManager . getConnection ( stringDeConexao , usuario , senha ) ;
18
19 String sql = " SELECT * FROM Livro ; " ;
20
21 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
22
23 System . out . println ( " Executando comando ... " ) ;
24 ResultSet resultado = comando . executeQuery () ;
25
26 System . out . println ( " Resultados encontrados : \ n " ) ;
27 while ( resultado . next () ) {
28 System . out . printf ( " ID : % d - TTULO : % s - PREO : % f - EDITORA : % d \ n " ,
29 resultado . getInt ( " id " ) ,
30 resultado . getString ( " titulo " ) ,
31 resultado . getDouble ( " preco " ) ,
32 resultado . getInt ( " editora_id " ) ) ;
33 }
34
35 System . out . println ( " \ nFechando conexo ... " ) ;
36 conexao . close () ;
37 } catch ( Exception e ) {
38 e . printStackTrace () ;
39 }
40 }
41 }

Cdigo Java 2.18: ListaLivros.java

Exerccio Complementar 2.6

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . PreparedStatement ;
5 import java . util . Scanner ;
6
7 public class InsereLivro {
8 public static void main ( String [] args ) {
9 try {
10 System . out . println ( " Abrindo conexo ... " ) ;
11 Connection conexao = ConnectionFactory . createConnection () ;
12
13 Scanner entrada = new Scanner ( System . in ) ;
14
15 System . out . println ( " Digite o ttulo do livro : " ) ;
16 String titulo = entrada . nextLine () ;
17
18 System . out . println ( " Digite o preo do livro : " ) ;
19 String preco = entrada . nextLine () ;
20
21 System . out . println ( " Digite o id da editora do livro : " ) ;
22 String id = entrada . nextLine () ;
23
24 entrada . close () ;
25

www.facebook.com/k19treinamentos 281
R ESPOSTAS 282

26 String sql = " INSERT INTO Livro ( titulo , preco , editora_id ) " +
27 " VALUES (? , ? , ?) " ;
28
29 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
30 comando . setString (1 , titulo ) ;
31 comando . setString (2 , preco ) ;
32 comando . setString (3 , id ) ;
33
34 System . out . println ( " Executando comando ... " ) ;
35 comando . execute () ;
36
37 System . out . println ( " Fechando conexo ... " ) ;
38 conexao . close () ;
39 }
40 catch ( Exception e ) {
41 e . printStackTrace () ;
42 }
43 }
44 }

Cdigo Java 2.23: InsereLivro.java

1 package br . com . k19 . jdbc ;


2
3 import java . sql . Connection ;
4 import java . sql . PreparedStatement ;
5 import java . sql . ResultSet ;
6
7 public class ListaLivros {
8 public static void main ( String [] args ) {
9 try {
10 System . out . println ( " Abrindo conexo ... " ) ;
11 Connection conexao = ConnectionFactory . createConnection () ;
12
13 String sql = " SELECT * FROM Livro ; " ;
14
15 PreparedStatement comando = conexao . prepareStatement ( sql ) ;
16
17 System . out . println ( " Executando comando ... " ) ;
18 ResultSet resultado = comando . executeQuery () ;
19
20 System . out . println ( " Resultados encontrados : \ n " ) ;
21 while ( resultado . next () ) {
22 System . out . printf ( " ID : % d - TTULO : % s - PREO : % f - EDITORA : % d \ n " ,
23 resultado . getInt ( " id " ) ,
24 resultado . getString ( " titulo " ) ,
25 resultado . getDouble ( " preco " ) ,
26 resultado . getInt ( " editora_id " ) ) ;
27 }
28
29 System . out . println ( " \ nFechando conexo ... " ) ;
30 conexao . close () ;
31 } catch ( Exception e ) {
32 e . printStackTrace () ;
33 }
34 }
35 }

Cdigo Java 2.24: ListaLivros.java

Exerccio Complementar 6.1

No projeto K19-Componentes-Visuais, crie uma classe chamada ContatoSACBean em um pacote


chamado br.com.k19.controle para implementar o managed bean que dar suporte ao formulrio.

282 www.k19.com.br
283 R ESPOSTAS

1 package br . com . k19 . controle ;


2
3 import java . util . ArrayList ;
4 import java . util . List ;
5 import javax . faces . bean . ManagedBean ;
6
7 @ManagedBean
8 public class ContatoSACBean {
9 private String nome ;
10 private String email ;
11 private String codigoDeArea ;
12 private String numeroDoTelefone ;
13
14 private Integer numeroDoPedido ;
15
16 private String assunto ;
17 private String comentario ;
18
19 private Boolean sexoFeminino ;
20
21 private List < String > assuntos = new ArrayList < String >() ;
22
23 public ContatoSACBean () {
24 assuntos . add ( " Entrega " ) ;
25 assuntos . add ( " Pagamento " ) ;
26 assuntos . add ( " Trocas ou devolues " ) ;
27 assuntos . add ( " Dvidas gerais " ) ;
28 assuntos . add ( " Comentrios " ) ;
29 }
30
31 // GETTERS E SETTERS
32 }

Cdigo Java 6.8: ContatoSACBean.java

Crie um arquivo XHTML chamado contato-sac.xhtml e implemente o formulrio de contato.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 < h1 > Servio de Atendimento ao Consumidor </ h1 >
13
14 <h : form >
15 <h : panelGrid columns = " 2 " >
16 <h : outputLabel value = " Nome : " for = " campo - nome " / >
17 <h : inputText value = " #{ contatoSACBean . nome } " id = " campo - nome " / >
18
19 <h : outputLabel value = "E - mail : " for = " campo - email " / >
20 <h : inputText value = " #{ contatoSACBean . email } " id = " campo - email " / >
21
22 <h : outputLabel value = " Telefone : " for = " campo - telefone " / >
23 <h : panelGroup >
24 ( <h : inputText value = " #{ contatoSACBean . codigoDeArea } " id = " campo - telefone "
25 size = " 2 " / >)
26 <h : inputText value = " #{ contatoSACBean . numeroDoTelefone } " / > ( DDD ) XXXX - XXXX
27 </ h: panelGroup >
28
29 <h : outputLabel value = " Sexo : " for = " campo - sexo " / >
30 <h : selectOneRadio value = " #{ contatoSACBean . sexoFeminino } " id = " campo - sexo " >
31 <f : selectItem itemLabel = " Feminino " itemValue = " true " / >

www.facebook.com/k19treinamentos 283
R ESPOSTAS 284

32 <f : selectItem itemLabel = " Masculino " itemValue = " false " / >
33 </ h: selectOneRadio >
34
35 <h : outputLabel value = " Nmero do pedido : " for = " campo - pedido " / >
36 <h : inputText value = " #{ contatoSACBean . numeroDoPedido } " id = " campo - pedido " / >
37
38 <h : outputLabel value = " Assunto " for = " campo - assunto " / >
39 <h : selectOneMenu value = " #{ contatoSACBean . assunto } " >
40 <f : selectItem noSelectionOption = " true " itemLabel = " Escolha um assunto " / >
41 <f : selectItems
42 value = " #{ contatoSACBean . assuntos } "
43 var = " assunto "
44 itemLabel = " #{ assunto } "
45 itemValue = " #{ assunto } " / >
46 </ h: selectOneMenu >
47
48 <h : outputLabel value = " Comentrio : " for = " campo - comentario " / >
49 <h : inputTextarea value = " #{ contatoSACBean . comentario } " id = " campo - comentario " / >
50
51 <h : commandButton value = " Enviar " / >
52 </ h : panelGrid >
53 </ h : form >
54 </ h : body >
55 </ html >

Cdigo XHTML 6.36: contato-sac.xhtml

Acesse a aplicao em
http://localhost:8080/K19-Componentes-Visuais/contato-sac.xhtml

Exerccio Complementar 6.2

Primeiramente, crie a classe Produto em um pacote chamado chamado br.com.k19.modelo do pro-


jeto K19-Componentes-Visuais.

1 package br . com . k19 . modelo ;


2
3 public class Produto {
4 private String nome ;
5 private Double preco ;
6
7 public Produto ( String nome , Double preco ) {
8 this . nome = nome ;
9 this . preco = preco ;
10 }
11
12 // GETTERS E SETTERS
13 }

Cdigo Java 6.12: Produto.java

Agora, crie um managed bean que guardar a lista de produtos disponveis.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Produto ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7
8 @ManagedBean
9 public class ProdutosBean {
10 private List < Produto > produtos = new ArrayList < Produto >() ;

284 www.k19.com.br
285 R ESPOSTAS

11
12 public ProdutosBean () {
13 this . produtos . add ( new Produto ( " Camiseta branca " , 29.90) ) ;
14 this . produtos . add ( new Produto ( " Camiseta preta " , 39.99) ) ;
15 this . produtos . add ( new Produto ( " Cala jeans " , 95.99) ) ;
16 this . produtos . add ( new Produto ( " Gravata " , 19.90) ) ;
17 this . produtos . add ( new Produto ( " Terno " , 289.95) ) ;
18 }
19
20 // GETTER E SETTER
21 }

Cdigo Java 6.13: ProdutosBean.java

Finalmente, crie o arquivo XHTML lista-de-produtos.xhtml e implemente a listagem dos produ-


tos.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : dataTable value = " #{ produtosBean . produtos } " var = " produto " >
13 <f : facet name = " header " > Lista de produtos </ f : facet >
14
15 <h : column >
16 <f : facet name = " header " > Nome </ f : facet >
17 #{ produto . nome }
18 </ h : column >
19
20 <h : column >
21 <f : facet name = " header " > Preo </ f : facet >
22 <h : outputFormat value = " {0 , number , R$ .00} " >
23 <f : param value = " #{ produto . preco } " / >
24 </ h: outputFormat >
25 </ h : column >
26 </ h : dataTable >
27 </ h : body >
28 </ html >

Cdigo XHTML 6.51: lista-de-produtos.xhtml

Acesse a aplicao no endereo:


http://localhost:8080/K19-Componentes-Visuais/lista-de-produtos.xhtml

Exerccio Complementar 6.3

Na classe Produto, adicione um atributo booleano chamado mostraPreco.

1 package br . com . k19 . modelo ;


2
3 public class Produto {
4 private String nome ;
5 private Double preco ;
6 private Boolean mostraPreco ;
7
8 public Produto ( String nome , Double preco ) {

www.facebook.com/k19treinamentos 285
R ESPOSTAS 286

9 this . nome = nome ;


10 this . preco = preco ;
11 this . mostraPreco = true ;
12 }
13
14 // GETTERS E SETTERS
15 }

Cdigo Java 6.14: Produto.java

No arquivo lista-de-produtos.xhtml 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 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 <h : dataTable value = " #{ produtosBean . produtos } " var = " produto " >
13 <f : facet name = " header " > Lista de produtos </ f : facet >
14
15 <h : column >
16 <f : facet name = " header " > Nome </ f : facet >
17 #{ produto . nome }
18 </ h : column >
19
20 <h : column >
21 <f : facet name = " header " > Preo </ f : facet >
22 <h : outputFormat value = " {0 , number , R$ .00} " rendered = " #{ produto . mostraPreco } " >
23 <f : param value = " #{ produto . preco } " / >
24 </ h: outputFormat >
25 <h : outputText value = " Adicione o produto ao carrinho para ver o preo "
26 rendered = " #{! produto . mostraPreco } " / >
27 </ h : column >
28 </ h : dataTable >
29 </ h : body >
30 </ html >

Cdigo XHTML 6.52: lista-de-produtos.xhtml

Defina como false o atributo mostraPreco de alguns produtos.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Produto ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7
8 @ManagedBean
9 public class ProdutosBean {
10 private List < Produto > produtos = new ArrayList < Produto >() ;
11
12 public ProdutosBean () {
13 this . produtos . add ( new Produto ( " Camiseta branca " , 29.90) ) ;
14 this . produtos . add ( new Produto ( " Camiseta preta " , 39.99) ) ;
15 this . produtos . add ( new Produto ( " Cala jeans " , 95.99) ) ;
16 this . produtos . add ( new Produto ( " Gravata " , 19.90) ) ;
17 Produto produto = new Produto ( " Terno " , 289.95) ;

286 www.k19.com.br
287 R ESPOSTAS

18 produto . setMostraPreco ( false ) ;


19 this . produtos . add ( produto ) ;
20 }
21
22 // GETTER E SETTER
23 }

Cdigo Java 6.15: ProdutosBean.java

Acesse a aplicao no endereo:


http://localhost:8080/K19-Componentes-Visuais/lista-de-produtos.xhtml

Exerccio 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 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Curso ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7 import javax . faces . bean . SessionScoped ;
8
9 @ManagedBean
10 @SessionScoped
11 public class CursosBean {
12 private List < Curso > cursos = new ArrayList < Curso >() ;
13 private Curso curso = new Curso () ;
14
15 public void adicionaCurso () {
16 this . cursos . add ( this . curso ) ;
17 this . adicionaMensagemDeConfirmacao ( curso ) ;
18 this . curso = new Curso () ;
19 }
20
21 private void adicionaMensagemDeConfirmacao ( Curso curso ) {
22 FacesMessage mensagem = new FacesMessage ( " O curso " + curso . getSigla ()
23 + " - " + curso . getNome () + " foi adicionado " ) ;
24 FacesContext . getCurrentInstance () . addMessage (
25 " form - adiciona : botao - adiciona " , mensagem ) ;
26 }
27
28 // GETTERS E SETTERS
29 }

Cdigo Java 6.17: CursosBean.java

Modifique o arquivo cursos.xhtml para exibir a mensagem. Faa isso usando a tag <h:message>,
como mostrado abaixo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >

www.facebook.com/k19treinamentos 287
R ESPOSTAS 288

12 <h : body >


13 <h : form id = " form - adiciona " >
14 <h : panelGrid columns = " 2 " >
15 <h : outputLabel value = " Sigla : " for = " campo - sigla " / >
16 <h : inputText value = " #{ cursosBean . curso . sigla } " id = " campo - sigla " / >
17
18 <h : outputLabel value = " Nome : " for = " campo - nome " / >
19 <h : inputText value = " #{ cursosBean . curso . nome } " id = " campo - nome " / >
20
21 <h : commandButton value = " Adicionar " action = " #{ cursosBean . adicionaCurso } "
22 id = " botao - adiciona " / >
23 </ h: panelGrid >
24 </ h : form >
25
26 <p > <h : message for = " botao - adiciona " style = " color : green " / > </ p >
27
28 < h1 > Alguns cursos da K19 : </ h1 >
29 < ul >
30 < ui : repeat value = " #{ cursosBean . cursos } " var = " curso " >
31 < li >
32 <h : outputText value = " #{ curso . sigla }: #{ curso . nome } " / >
33 </ li >
34 </ ui : repeat >
35 </ ul >
36 </ h : body >
37 </ html >

Cdigo XHTML 6.59: cursos.xhtml

Acesse a aplicao em:


http://localhost:8080/K19-Componentes-Visuais/cursos.xhtml

Exerccio Complementar 7.1

No pacote br.com.k19.modelo, crie uma classe chamada Produto para representar os produtos da
loja.

1 package br . com . k19 . modelo ;


2
3 public class Produto {
4
5 private String nome ;
6 private String descricao ;
7 private String caminhoDaFigura ;
8 private double preco ;
9 private int id ;
10
11 public Produto ( String nome , String descricao , String caminhoDaFigura ,
12 double preco , int id ) {
13 this . nome = nome ;
14 this . descricao = descricao ;
15 this . caminhoDaFigura = caminhoDaFigura ;
16 this . preco = preco ;
17 this . id = id ;
18 }
19
20 // GETTERS E SETTERS
21 }

Cdigo Java 7.3: Produto.java

Copie os arquivos da pasta K19-Arquivos/imagens para o diretrio imagens do projeto K19-


Templates-e-Modularizacao.

288 www.k19.com.br
289 R ESPOSTAS

Importante
Voc tambm pode obter esses arquivos atravs do site da K19: www.k19.com.br/
arquivos.

No pacote br.com.k19.controle, crie uma classe chamada ProdutosBean. Essa classe deve ar-
mazenar uma lista de produtos e deve ter um atributo para guardar o produto cujos detalhes devem
ser exibidos.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Produto ;
4 import java . util . ArrayList ;
5 import java . util . List ;
6 import javax . faces . bean . ManagedBean ;
7
8 @ManagedBean
9 public class ProdutosBean {
10
11 private Produto produtoSelecionado ;
12 private int idDoProdutoSelecionado ;
13 private List < Produto > produtos = new ArrayList < Produto >() ;
14
15 public ProdutosBean () {
16 this . produtos . add ( new Produto (
17 " Camiseta branca " ,
18 " Esta uma camiseta bsica na cor branca . Ela feita de algodo e " +
19 " est disponvel nos tamanhos P , M e G . " ,
20 " / imagens / camiseta - branca . jpg " , 29.90 , 1) ) ;
21
22 this . produtos . add ( new Produto (
23 " Camiseta preta " ,
24 " Esta uma camiseta na cor preta , que est disponvel " +
25 " nos tamanhos P , M e G . Seu material 100% algodo . " ,
26 " / imagens / camiseta - preta . jpg " , 39.90 , 2) ) ;
27
28 this . produtos . add ( new Produto (
29 " Cala jeans " ,
30 " Cala jeans disponvel nos tamanhos 38 a 50. " ,
31 " / imagens / calca - jeans . jpg " , 95.99 , 3) ) ;
32
33 this . produtos . add ( new Produto (
34 " Terno " ,
35 " Terno de seda na cor cinza . " ,
36 " / imagens / terno . jpg " , 589.95 , 4) ) ;
37
38 this . produtos . add ( new Produto (
39 " Gravata " ,
40 " Gravata nas cores vermelha , azul e verde . " ,
41 " / imagens / gravata . jpg " , 19.90 , 5) ) ;
42
43 this . produtoSelecionado = this . produtos . get (0) ;
44 }
45
46 public void carregaProduto () {
47 for ( Produto produto : produtos ) {
48 if ( this . idDoProdutoSelecionado == produto . getId () ) {
49 this . produtoSelecionado = produto ;
50 break ;
51 }
52 }
53 }
54
55 // GETTERS E SETTERS
56 }

www.facebook.com/k19treinamentos 289
R ESPOSTAS 290

Cdigo Java 7.4: ProdutosBean.java

No diretrio WEB-INF/templates, crie um arquivo chamado template-loja-virtual.xhtml para


definir um template para as pginas da loja.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 <h : head >
9 < title > K19 Treinamentos </ title >
10 </ h : head >
11 <h : body >
12 < div id = " header " >
13 < h1 > Loja virtual </ h1 >
14 < hr / >
15 </ div >
16
17 < ui : insert name = " conteudo " / >
18
19 < div id = " footer " style = " text - align : center " >
20 < hr / >
21 & copy ; 2012 K19 . Todos os direitos reservados .
22 </ div >
23 </ h : body >
24 </ html >

Cdigo XHTML 7.13: template-loja-virtual.xhtml

No diretrio partials, 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 < ui : composition xmlns = " http :// www . w3 . org /1999/ xhtml "
2 xmlns : h = " http :// java . sun . com / jsf / html "
3 xmlns : f = " http :// java . sun . com / jsf / core "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 <h : panelGrid columns = " 2 " cellspacing = " 5 " >
7 <h : graphicImage value = " #{ produto . caminhoDaFigura } " width = " 100 " / >
8 <h : panelGroup >
9 < h2 > #{ produto . nome } </ h2 >
10
11 Preo :
12 <h : outputFormat value = " {0 , number , R$ .00} " style = " color : red " >
13 <f : param value = " #{ produto . preco } " / >
14 </ h: outputFormat >
15 </ h : panelGroup >
16 </ h : panelGrid >
17
18 < h3 > Descrio </ h3 >
19 #{ produto . descricao }
20
21 </ ui : composition >

Cdigo XHTML 7.14: produto-info.xhtml

Note que o parmetro para o arquivo produto-info.xhtml deve se chamar produto. Crie uma
pgina chamada loja.xhtml. Esse arquivo usar o template que voc acabou de criar. O contedo

290 www.k19.com.br
291 R ESPOSTAS

da pgina ser formado pela caixa de seleo de produto e pelo pedao de tela de informaes do
produto.

1 < ui : composition
2 template = " / WEB - INF / templates / template - loja - virtual . xhtml "
3 xmlns = " http :// www . w3 . org /1999/ xhtml "
4 xmlns : h = " http :// java . sun . com / jsf / html "
5 xmlns : f = " http :// java . sun . com / jsf / core "
6 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
7
8 < ui : define name = " conteudo " >
9
10 <h : form >
11 <h : selectOneMenu value = " #{ produtosBean . idDoProdutoSelecionado } " >
12 <f : selectItems
13 value = " #{ produtosBean . produtos } "
14 var = " produto "
15 itemValue = " #{ produto . id } "
16 itemLabel = " #{ produto . nome } " >
17 </ f : selectItems >
18 </ h: selectOneMenu >
19 <h : commandButton value = " Detalhes " action = " #{ produtosBean . carregaProduto } " / >
20 </ h : form >
21
22 < ui : include src = " / WEB - INF / partials / produto - info . xhtml " >
23 < ui : param name = " produto " value = " #{ produtosBean . produtoSelecionado } " / >
24 </ ui : include >
25
26 </ ui : define >
27 </ ui : composition >

Cdigo XHTML 7.15: loja.xhtml

Acesse a aplicao no endereo:

http://localhost:8080/K19-Templates-e-Modularizacao/loja.xhtml

Exerccio Complementar 8.1

No pacote br.com.k19.controle, do projeto K19-Navegacao crie uma classe chamada UsuarioBean


e implemente um managed bean para armazenar a preferncia do usurio.

1 package br . com . k19 . controle ;


2
3 import javax . faces . bean . ManagedBean ;
4 import javax . faces . bean . SessionScoped ;
5
6 @SessionScoped
7 @ManagedBean
8 public class UsuarioBean {
9 private String versaoPreferida = " Simples " ;
10
11 public String principal () {
12 if ( this . versaoPreferida . equals ( " Avanada " ) ) {
13 return " principal - avancada . xhtml " ;
14 } else {
15 return " principal - simples . xhtml " ;
16 }
17 }
18
19 // GETTERS E SETTERS
20 }

Cdigo Java 8.3: UsuarioBean.java

www.facebook.com/k19treinamentos 291
R ESPOSTAS 292

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 /WEB-INF/templates, crie um arquivo chamado template-aplicacao.xhtml para im-


plementar um template para as pginas da aplicao.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12 <h : body >
13 < div id = " header " style = " text - align : center " >
14 <h : outputText value = " Loja Virtual " style = " font - size : 36 px ; font - weight : bold " / >
15 <h : form >
16 <h : commandLink value = " Pgina principal " action = " #{ usuarioBean . principal } " / >
17 -
18 <h : link value = " Configuraes " outcome = " configuracoes " / >
19 </ h : form >
20 </ div >
21
22 < ui : insert name = " conteudo " / >
23
24 < div id = " footer " style = " text - align : center " >
25 < hr / >
26 & copy ; 2012 K19 . Todos os direitos reservados .
27 </ div >
28
29 </ h : body >
30 </ html >

Cdigo XHTML 8.18: template-aplicacao.xhtml

Note que o menu para navegar entre as pginas da aplicao foi definido nesse arquivo. Ob-
serve 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.

Crie duas pginas no projeto K19-Navegacao chamadas principal-simples.xhtml e principal-a-


vancada.xhtml para implementar as verses simples e avanada da pgina principal, respectiva-
mente.

1 < ui : composition template = " / WEB - INF / templates / template - aplicacao . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 < ui : define name = " conteudo " >
7 < h1 > Pgina Principal Simples </ h1 >
8 < ul >
9 < li > <h : link > Visualizar produtos cadastrados </ h : link > </ li >
10 </ ul >
11 </ ui : define >
12 </ ui : composition >

Cdigo XHTML 8.19: principal-simples.xhtml

1 < ui : composition template = " / WEB - INF / templates / template - aplicacao . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "

292 www.k19.com.br
293 R ESPOSTAS

3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
5
6 < ui : define name = " conteudo " >
7 < h1 > Pgina Principal Avanada </ h1 >
8 < ul >
9 < li > <h : link > Visualizar produtos cadastrados </ h : link > </ li >
10 < li > <h : link > Editar produtos cadastrados </ h : link > </ li >
11 < li > <h : link > Adicionar ou remover produtos </ h : link > </ li >
12 < li > <h : link > Adicionar ou remover usurios </ h : link > </ li >
13 </ ul >
14 </ ui : define >
15 </ ui : composition >

Cdigo XHTML 8.20: principal-avancada.xhtml

Finalmente, crie uma pgina chamada configuracoes.xhtml para implementar a pgina da apli-
cao em que o usurio pode alterar suas preferncias.

1 < ui : composition template = " / WEB - INF / templates / template - aplicacao . xhtml "
2 xmlns = " http :// www . w3 . org /1999/ xhtml "
3 xmlns : h = " http :// java . sun . com / jsf / html "
4 xmlns : f = " http :// java . sun . com / jsf / core "
5 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
6
7 < ui : define name = " conteudo " >
8 < h1 > Configuraes </ h1 >
9
10 <p > Voc est usando a verso <b > #{ usuarioBean . versaoPreferida } </ b >
11 da aplicao . Se desejar , escolha outra verso abaixo e clique no
12 boto " Salvar " . </ p >
13
14 <h : form >
15 <h : panelGrid columns = " 3 " >
16 <h : outputLabel value = " Verso da aplicao : " for = " versao " / >
17
18 <h : selectOneMenu value = " #{ usuarioBean . versaoPreferida } " id = " versao " >
19 <f : selectItem itemLabel = " Simples " itemValue = " Simples " / >
20 <f : selectItem itemLabel = " Avanada " itemValue = " Avanada " / >
21 </ h : selectOneMenu >
22
23 <h : commandButton value = " Salvar " / >
24 </ h: panelGrid >
25 </ h : form >
26 </ ui : define >
27 </ ui : composition >

Cdigo XHTML 8.21: configuracoes.xhtml

Acesse a aplicao no endereo:

http://localhost:8080/K19-Navegacao/principal-simples.xhtml

Exerccio Complementar 8.2

No arquivo template-aplicacao.xhtml, altere o link para a pgina principal para que ele emita o sinal
"principal".

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "

www.facebook.com/k19treinamentos 293
R ESPOSTAS 294

6 xmlns : f = " http :// java . sun . com / jsf / core "
7 xmlns : ui = " http :// java . sun . com / jsf / facelets " >
8
9 <h : head >
10 < title > K19 Treinamentos </ title >
11 </ h : head >
12 <h : body >
13 < div id = " header " style = " text - align : center " >
14 <h : outputText value = " Loja Virtual " style = " font - size : 36 px ; font - weight : bold " / >
15 <h : form >
16 <h : link value = " Pgina principal " outcome = " principal " / >
17 -
18 <h : link value = " Configuraes " outcome = " configuracoes " / >
19 </ h : form >
20 </ div >
21
22 < ui : insert name = " conteudo " / >
23
24 < div id = " footer " style = " text - align : center " >
25 < hr / >
26 & copy ; 2012 K19 . Todos os direitos reservados .
27 </ div >
28
29 </ h : body >
30 </ html >

Cdigo XHTML 8.22: template-aplicacao.xhtml

No arquivo faces-config.xhtml, defina as regras de navegao para a pgina principal. Se o usu-


rio prefere a verso simples da aplicao, ento o sinal "principal" deve direcionar o usurio para
a pgina definida pelo arquivo principal-simples.xhtml. Por outro lado, se o usurio prefere a ver-
so avanada da aplicao, ento o sinal "principal" deve direcion-lo para a pgina definida pelo
arquivo principal-avancada.xhtml.

1 ...
2 < navigation - rule >
3 < from - view - id >* </ from - view - id >
4
5 < navigation - case >
6 < from - outcome > principal </ from - outcome >
7 < if > #{ usuarioBean . versaoPreferida == Simples } </ if >
8 <to - view - id > principal - simples . xhtml </ to - view - id >
9 </ navigation - case >
10
11 < navigation - case >
12 < from - outcome > principal </ from - outcome >
13 < if > #{ usuarioBean . versaoPreferida == Avanada } </ if >
14 <to - view - id > principal - avancada . xhtml </ to - view - id >
15 </ navigation - case >
16
17 </ navigation - rule >
18 ...

Cdigo XML 8.6: faces-config.xml

Acesse a aplicao no endereo:

http://localhost:8080/K19-Navegacao/principal-simples.xhtml

Exerccio Complementar 10.1

No projeto K19-Conversao-e-Validacao, crie uma classe chamada Cotacao para modelar a cotao

294 www.k19.com.br
295 R ESPOSTAS

de uma moeda. Essa classe deve estar no pacote br.com.k19.modelo.

1 package br . com . k19 . modelo ;


2
3 import java . util . Date ;
4
5 public class Cotacao {
6 private Double valor ;
7 private Double variacao ;
8 private Date horario ;
9
10 // GETTERS E SETTERS
11 }

Cdigo Java 10.4: Cotacao.java

Crie uma classe chamada CotacaoBean no pacote br.com.k19.controle para armazenar os valo-
res submetidos pelo formulrio.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Cotacao ;
4 import javax . faces . bean . ManagedBean ;
5
6 @ManagedBean
7 public class CotacaoBean {
8 private Cotacao cotacao = new Cotacao () ;
9
10 // GETTER E SETTER
11 }

Cdigo Java 10.5: CotacaoBean.java

Crie uma pgina chamada registrar-cotacao.xhtml e implemente o formulrio para registrar


uma cotao.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Registrar cotao do dlar </ h1 >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15 <h : outputLabel value = " Valor : " for = " valor " / >
16 <h : panelGroup >
17 <h : inputText value = " #{ cotacaoBean . cotacao . valor } " id = " valor " required = " true " >
18 <f : convertNumber locale = " pt_BR " type = " currency " / >
19 </ h : inputText >
20 <h : message for = " valor " style = " color : red " / >
21 </ h: panelGroup >
22
23 <h : outputLabel value = " Variao : " for = " variacao " / >
24 <h : panelGroup >
25 <h : inputText value = " #{ cotacaoBean . cotacao . variacao } " id = " variacao " required = " -
true " >
26 <f : convertNumber maxFractionDigits = " 5 " type = " percent " / >
27 </ h : inputText >
28 <h : message for = " variacao " style = " color : red " / >
29 </ h: panelGroup >

www.facebook.com/k19treinamentos 295
R ESPOSTAS 296

30
31 <h : outputLabel value = " Horrio : " for = " horario " / >
32 <h : panelGroup >
33 <h : inputText value = " #{ cotacaoBean . cotacao . horario } " id = " horario " required = " -
true " >
34 <f : convertDateTime pattern = " HH : mm dd - MM - yyyy " / >
35 </ h : inputText >
36 <h : message for = " horario " style = " color : red " / >
37 </ h: panelGroup >
38
39 <h : commandButton value = " Registrar " / >
40 </ h : panelGrid >
41 </ h : form >
42 </ h : body >
43 </ html >

Cdigo XHTML 10.9: registrar-cotacao.xhtml

Acesse a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/registrar-cotacao.xhtml

Exerccio Complementar 10.2

No arquivo registrar-cotacao.xhtml, adicione as linhas em destaque do cdigo abaixo.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Registrar cotao do dlar </ h1 >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15 <h : outputLabel value = " Valor : " for = " valor " / >
16 <h : panelGroup >
17 <h : inputText value = " #{ cotacaoBean . cotacao . valor } " id = " valor " required = " true " >
18 <f : convertNumber locale = " pt_BR " type = " currency " / >
19 </ h : inputText >
20 <h : message for = " valor " style = " color : red " / >
21 </ h: panelGroup >
22
23 <h : outputLabel value = " Variao : " for = " variacao " / >
24 <h : panelGroup >
25 <h : inputText value = " #{ cotacaoBean . cotacao . variacao } " id = " variacao " required = " -
true " >
26 <f : convertNumber maxFractionDigits = " 5 " type = " percent " / >
27 </ h : inputText >
28 <h : message for = " variacao " style = " color : red " / >
29 </ h: panelGroup >
30
31 <h : outputLabel value = " Horrio : " for = " horario " / >
32 <h : panelGroup >
33 <h : inputText value = " #{ cotacaoBean . cotacao . horario } " id = " horario " required = " -
true " >
34 <f : convertDateTime pattern = " HH : mm dd - MM - yyyy " / >
35 </ h : inputText >
36 <h : message for = " horario " style = " color : red " / >
37 </ h: panelGroup >
38

296 www.k19.com.br
297 R ESPOSTAS

39 <h : commandButton value = " Registrar " / >


40 </ h : panelGrid >
41 </ h : form >
42
43 <h : panelGroup rendered = " #{ cotacaoBean . cotacao . valor != null } " >
44 < h2 > Cotao registrada : </ h2 >
45 Valor : #{ cotacaoBean . cotacao . valor }
46 < br / >
47 Variao : #{ cotacaoBean . cotacao . variacao * 100}%
48 < br / >
49 Horrio : #{ cotacaoBean . cotacao . horario }
50 </ h : panelGroup >
51 </ h : body >
52 </ html >

Cdigo XHTML 10.10: registrar-cotacao.xhtml

Acesse a aplicao no endereo:


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.

Exerccio Complementar 10.3

Crie uma classe chamada Produto no pacote br.com.k19.modelo.

1 package br . com . k19 . modelo ;


2
3 public class Produto {
4 private String nome ;
5 private String codigo ;
6 private Integer tamanho ;
7 private Double volume ;
8
9 // GETTERS E SETTERS
10 }

Cdigo Java 10.7: Produto.java

Crie uma classe chamada ProdutoBean no pacote br.com.k19.controle.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . Produto ;
4 import javax . faces . bean . ManagedBean ;
5
6 @ManagedBean
7 public class ProdutoBean {
8 private Produto produto = new Produto () ;
9
10 // GETTER E SETTER
11 }

Cdigo Java 10.8: ProdutoBean.java

Crie uma pgina XHTML chamada cadastro-de-produtos.xhtml e implemente o formulrio.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3

www.facebook.com/k19treinamentos 297
R ESPOSTAS 298

4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 < h1 > Cadastro de Produtos </ h1 >
13 <h : form >
14 <h : panelGrid columns = " 2 " >
15 <h : outputLabel value = " Nome : " for = " nome " / >
16 <h : panelGroup >
17 <h : inputText value = " #{ produtoBean . produto . nome } " id = " nome " required = " true " >
18 <f : validateRegex pattern = " [a - zA - Z \ s ]+ " / >
19 </ h : inputText >
20 <h : message for = " nome " style = " color : red " / >
21 </ h: panelGroup >
22
23 <h : outputLabel value = " Cdigo : " for = " codigo " / >
24 <h : panelGroup >
25 <h : inputText value = " #{ produtoBean . produto . codigo } " id = " codigo " required = " true -
">
26 <f : validateRegex pattern = " [A - Z ][0 -9]+ " / >
27 <f : validateLength minimum = " 4 " maximum = " 10 " / >
28 </ h : inputText >
29 <h : message for = " codigo " style = " color : red " / >
30 </ h: panelGroup >
31
32 <h : outputLabel value = " Tamanho : " for = " tamanho " / >
33 <h : panelGroup >
34 <h : inputText value = " #{ produtoBean . produto . tamanho } " id = " tamanho " >
35 <f : validateRequired / >
36 <f : validateLongRange minimum = " 1 " maximum = " 32 " / >
37 </ h : inputText >
38 <h : message for = " tamanho " style = " color : red " / >
39 </ h: panelGroup >
40
41 <h : outputLabel value = " Volume : " for = " volume " / >
42 <h : panelGroup >
43 <h : inputText value = " #{ produtoBean . produto . volume } " id = " volume " >
44 <f : validateRequired / >
45 <f : validateDoubleRange minimum = " 0.1 " / >
46 </ h : inputText >
47 <h : message for = " volume " style = " color : red " / >
48 </ h: panelGroup >
49
50 <h : commandButton value = " Enviar " / >
51 </ h : panelGrid >
52 </ h : form >
53 </ h : body >
54 </ html >

Cdigo XHTML 10.22: cadastro-de-produtos.xhtml

Teste a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/cadastro-de-produtos.xhtml

Exerccio Complementar 10.4

Na pacote br.com.k19.modelo, crie uma classe chamada RIC.

1 package br . com . k19 . modelo ;


2
3 public class RIC {

298 www.k19.com.br
299 R ESPOSTAS

4 private String numeroDeIdentificacao ;


5 private String digitoVerificador ;
6
7 // GETTERS E SETTERS
8 }

Cdigo Java 10.20: RIC.java

Na pacote br.com.k19.converters, crie uma classe chamada ConversorDeRIC e implemente o


conversor.

1 package br . com . k19 . converters ;


2
3 import br . com . k19 . modelo . RIC ;
4 import java . util . regex . Pattern ;
5 import javax . faces . application . FacesMessage ;
6 import javax . faces . component . UIComponent ;
7 import javax . faces . context . FacesContext ;
8 import javax . faces . convert . Converter ;
9 import javax . faces . convert . ConverterException ;
10 import javax . faces . convert . FacesConverter ;
11
12 @FacesConverter ( forClass = RIC . class )
13 public class ConversorDeRIC implements Converter {
14
15 @Override
16 public Object getAsObject ( FacesContext context , UIComponent component ,
17 String value ) {
18
19 String ricString = value . trim () ;
20
21 if (! Pattern . matches ( " [0 -9]{10}[ -]?[0 -9] " , ricString ) ) {
22 FacesMessage mensagem = new FacesMessage ( " Nmero RIC invlido " ) ;
23 mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
24 throw new ConverterException ( mensagem ) ;
25 }
26
27 ricString = ricString . replaceAll ( " -" , " " ) ;
28
29 RIC ric = new RIC () ;
30 ric . setNumeroDeIdentificacao ( ricString . substring (0 , 10) ) ;
31 ric . setDigitoVerificador ( ricString . substring (10 , 11) ) ;
32
33 return ric ;
34 }
35
36 @Override
37 public String getAsString ( FacesContext context , UIComponent component ,
38 Object value ) {
39 RIC ric = ( RIC ) value ;
40 return ric . getNumeroDeIdentificacao () + " -" + ric . getDigitoVerificador () ;
41 }
42 }

Cdigo Java 10.21: ConversorDeRIC.java

Na pacote br.com.k19.controle, crie uma classe chamada RICBean e implemente o managed


bean que dar suporte ao seu formulrio.

1 package br . com . k19 . controle ;


2
3 import br . com . k19 . modelo . RIC ;
4 import javax . faces . bean . ManagedBean ;
5
6 @ManagedBean
7 public class RICBean {

www.facebook.com/k19treinamentos 299
R ESPOSTAS 300

8 private RIC ric ;


9
10 // GETTER E SETTER
11 }

Cdigo Java 10.22: RICBean.java

Crie uma pgina chamada ric.xhtml e implemente um formulrio que possua uma caixa de texto
associada propriedade ric do managed bean RICBean.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3
4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html " >
6 <h : head >
7 < title > K19 Treinamentos </ title >
8 </ h : head >
9
10 <h : body >
11 <h : form >
12 <h : outputLabel value = " RIC : " for = " campo - ric " / >
13 <h : inputText id = " campo - ric " value = " #{ rICBean . ric } " / >
14 <h : commandButton value = " Enviar " / >
15 </ h : form >
16
17 <h : message for = " campo - ric " style = " color : red " / >
18 </ h : body >
19 </ html >

Cdigo XHTML 10.26: ric.xhtml

Faa alguns testes acessando a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/ric.xhtml

Exerccio Complementar 10.5

Primeiro, crie um managed bean chamado ReservaBean que armazenar a data escolhida pelo usu-
rio. A classe dever ser adicionada ao pacote br.com.k19.controle.

1 package br . com . k19 . controle ;


2
3 import java . util . Date ;
4 import javax . faces . bean . ManagedBean ;
5
6 @ManagedBean
7 public class ReservaBean {
8
9 private Date data ;
10
11 // GETTER E SETTER
12 }

Cdigo Java 10.27: ReservaBean.java

Crie uma pgina chamada reserva.xhtml e implemente o formulrio para o usurio digitar a
data.

1 <! DOCTYPE html PUBLIC " -// W3C // DTD XHTML 1.0 Transitional // EN "
2 " http :// www . w3 . org / TR / xhtml1 / DTD / xhtml1 - transitional . dtd " >
3

300 www.k19.com.br
301 R ESPOSTAS

4 < html xmlns = " http :// www . w3 . org /1999/ xhtml "
5 xmlns : h = " http :// java . sun . com / jsf / html "
6 xmlns : f = " http :// java . sun . com / jsf / core " >
7 <h : head >
8 < title > K19 Treinamentos </ title >
9 </ h : head >
10
11 <h : body >
12 <h : outputText value = " Escolha uma data entre 01/05/2014 e 30/08/2014. " / >
13 <h : form >
14 <h : outputLabel value = " Data : ( dd / MM / yyyy ) " for = " campo - data " / >
15
16 <h : inputText id = " campo - data " value = " #{ reservaBean . data } " required = " true " >
17 <f : convertDateTime pattern = " dd / MM / yyyy " / >
18
19 <f : validator validatorId = " validators . ValidadorDeData " / >
20
21 <f : attribute name = " padraoDeData " value = " dd / MM / yyyy " / >
22 <f : attribute name = " inicio " value = " 01/05/2014 " / >
23 <f : attribute name = " fim " value = " 30/08/2014 " / >
24 </ h : inputText >
25
26 <h : commandButton value = " Enviar " / >
27 </ h : form >
28
29 <h : message for = " campo - data " style = " color : red " / >
30 </ h : body >
31 </ html >

Cdigo XHTML 10.30: reserva.xhtml

No pacote br.com.k19.validators, crie uma classe chamada ValidadorDeData para implementar


o validador.

1 package br . com . k19 . validators ;


2
3 import java . text . ParseException ;
4 import java . text . SimpleDateFormat ;
5 import java . util . Date ;
6 import javax . faces . application . FacesMessage ;
7 import javax . faces . component . UIComponent ;
8 import javax . faces . context . FacesContext ;
9 import javax . faces . validator . FacesValidator ;
10 import javax . faces . validator . Validator ;
11 import javax . faces . validator . ValidatorException ;
12
13 @FacesValidator ( " validators . ValidadorDeData " )
14 public class ValidadorDeData implements Validator {
15
16 @Override
17 public void validate ( FacesContext context , UIComponent component ,
18 Object value ) throws ValidatorException {
19
20 String padraoDeData = ( String ) component . getAttributes () . get ( " padraoDeData " ) ;
21 String inicio = ( String ) component . getAttributes () . get ( " inicio " ) ;
22 String fim = ( String ) component . getAttributes () . get ( " fim " ) ;
23
24 Date data = ( Date ) value ;
25 Date dataInicio ;
26 Date dataFim ;
27
28 try {
29 dataInicio = ( Date ) new SimpleDateFormat ( padraoDeData ) . parse ( inicio ) ;
30 dataFim = ( Date ) new SimpleDateFormat ( padraoDeData ) . parse ( fim ) ;
31 } catch ( ParseException e ) {
32 FacesMessage mensagem = new FacesMessage (
33 " Erro ao criar as datas de incio e fim do intervalo . " ) ;
34 mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;

www.facebook.com/k19treinamentos 301
R ESPOSTAS 302

35 throw new ValidatorException ( mensagem ) ;


36 }
37
38 if ( data . before ( dataInicio ) || data . after ( dataFim ) ) {
39 FacesMessage mensagem = new FacesMessage (
40 " A data escolhida precisa estar entre " + inicio + " e " + fim ) ;
41 mensagem . setSeverity ( FacesMessage . SEVERITY_ERROR ) ;
42 throw new ValidatorException ( mensagem ) ;
43 }
44 }
45 }

Cdigo Java 10.28: ValidadorDeData.java

Acesse a aplicao no endereo:


http://localhost:8080/K19-Conversao-e-Validacao/reserva.xhtml

Teste o formulrio submetendo-o com diversas datas diferentes, inclusive com datas nos extre-
mos 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 <f : convertDateTime pattern = " dd / MM / yyyy " timeZone = " GMT -3 " / >
3 ...

Cdigo XHTML 10.31: reserva.xhtml

Teste o formulrio novamente.

302 www.k19.com.br