Você está na página 1de 157

TREINAMENTOS

Desenvolvimento Web
com JSF2 e JPA2

Desenvolvimento Web com JSF 2 e JPA 2

15 de maro de 2011

www.k19.com.br

ii

Sumrio
1

Banco de dados
1.1 Bases de dados (Databases) .
1.2 Tabelas . . . . . . . . . . . .
1.3 Operaes Bsicas . . . . . .
1.4 Chaves Primria e Estrangeira
1.5 Consultas Avanadas . . . . .
1.6 Exerccios . . . . . . . . . . .

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

JDBC
2.1 Driver . . . . . . . . . . . . . . . . . . . . .
2.2 JDBC . . . . . . . . . . . . . . . . . . . . .
2.3 Instalando o Driver JDBC do MySQL Server
2.4 Criando uma conexo . . . . . . . . . . . . .
2.5 Inserindo registros . . . . . . . . . . . . . .
2.6 Exerccios . . . . . . . . . . . . . . . . . . .
2.7 SQL Injection . . . . . . . . . . . . . . . . .
2.8 Exerccios . . . . . . . . . . . . . . . . . . .
2.9 Listando registros . . . . . . . . . . . . . . .
2.10 Exerccios . . . . . . . . . . . . . . . . . . .
2.11 Fbrica de conexes (Factory) . . . . . . . .
2.12 Exerccios . . . . . . . . . . . . . . . . . . .

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

1
2
4
7
11
11
12

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

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

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

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

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

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

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

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

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

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

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

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

27
27
28
28
28
29
29
31
33
33
34
35
36

JPA 2 e Hibernate
3.1 Mltiplas sintaxes da linguagem SQL . . . . . . . . . . .
3.2 Orientao a Objetos VS Modelo Entidade Relacionamento
3.3 Ferramentas ORM . . . . . . . . . . . . . . . . . . . . .
3.4 O que JPA e Hibernate . . . . . . . . . . . . . . . . . .
3.5 Configurao . . . . . . . . . . . . . . . . . . . . . . . .
3.6 Mapeamento . . . . . . . . . . . . . . . . . . . . . . . .
3.7 Gerando o banco . . . . . . . . . . . . . . . . . . . . . .
3.8 Exerccios . . . . . . . . . . . . . . . . . . . . . . . . . .
3.9 Manipulando entidades . . . . . . . . . . . . . . . . . . .
3.9.1 Persistindo . . . . . . . . . . . . . . . . . . . . .
3.9.2 Buscando . . . . . . . . . . . . . . . . . . . . . .
3.9.3 Removendo . . . . . . . . . . . . . . . . . . . . .
3.9.4 Atualizando . . . . . . . . . . . . . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

37
37
37
37
38
38
39
40
41
43
43
43
44
44

iii

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

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

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

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

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

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

SUMRIO

SUMRIO

3.9.5 Listando .
3.9.6 Transaes
3.10 Exerccios . . . . .
3.11 Repository . . . . .
3.12 Exerccios . . . . .
4

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

Web Container
4.1 Necessidades de uma aplicao web .
4.2 Web Container . . . . . . . . . . . .
4.3 Especificao Java EE . . . . . . . .
4.4 Exerccios . . . . . . . . . . . . . . .
4.5 Aplicao Web Java . . . . . . . . . .
4.6 Exerccios . . . . . . . . . . . . . . .
4.7 Processando requisies . . . . . . .
4.8 Servlet . . . . . . . . . . . . . . . . .
4.8.1 Inserindo contedo na resposta
4.9 Exerccios . . . . . . . . . . . . . . .
4.10 JSP . . . . . . . . . . . . . . . . . .
4.11 Exerccios . . . . . . . . . . . . . . .
4.12 Frameworks . . . . . . . . . . . . . .
Viso Geral do JSF 2
5.1 Aplicao de exemplo . . . . . .
5.2 Managed Beans . . . . . . . . .
5.2.1 GeradorDeApostasBean
5.3 Facelets e Componentes Visuais
5.3.1 Tela de entrada . . . . .
5.3.2 Tela de Sada . . . . . .
5.4 Exerccios . . . . . . . . . . . .
Componentes Visuais
6.1 Formulrios . . .
6.2 Panel Grid . . . .
6.3 Panel Group . . .
6.4 Tabelas . . . . .
6.5 Namespaces . . .
6.6 Esqueleto HTML
6.7 Exerccios . . . .

.
.
.
.
.
.
.

.
.
.
.
.
.
.

Facelets
7.1 Templating . . . . .
7.2 Exerccios . . . . . .
7.3 Particionando as telas
7.4 Exerccios . . . . . .

www.k19.com.br

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

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

.
.
.
.
.
.
.

.
.
.
.
.
.
.

.
.
.
.

.
.
.
.
.

44
44
45
46
47

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

49
49
49
50
50
50
51
51
51
52
52
53
53
53

.
.
.
.
.
.
.

55
55
55
56
56
56
57
58

.
.
.
.
.
.
.

63
63
65
66
67
68
68
68

.
.
.
.

71
71
72
73
74
iv

SUMRIO
8

Navegao
8.1 Navegao Esttica Implcita .
8.2 Navegao Esttica Explcita .
8.3 Exerccios . . . . . . . . . . .
8.4 Navegao Dinmica Implcita
8.5 Navegao Dinmica Explcita
8.6 Exerccios . . . . . . . . . . .

SUMRIO

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

.
.
.
.
.
.

Managed Beans
9.1 Criando Managed Beans . . . . . . . . . . . . . . . .
9.2 Disponibilizando dados para as telas . . . . . . . . . .
9.3 Recebendo dados das telas . . . . . . . . . . . . . . .
9.4 Definindo o tratamento das aes . . . . . . . . . . . .
9.5 Expression Language . . . . . . . . . . . . . . . . . .
9.5.1 Nome dos Managed Beans . . . . . . . . . . .
9.5.2 Acessando as propriedades dos Managed Beans
9.6 Binding . . . . . . . . . . . . . . . . . . . . . . . . .
9.7 Escopo . . . . . . . . . . . . . . . . . . . . . . . . . .
9.7.1 Request . . . . . . . . . . . . . . . . . . . . .
9.7.2 Session . . . . . . . . . . . . . . . . . . . . .
9.7.3 Application . . . . . . . . . . . . . . . . . . .
9.7.4 View . . . . . . . . . . . . . . . . . . . . . .
9.8 Interdependncia e Injeo . . . . . . . . . . . . . . .
9.9 Exerccios . . . . . . . . . . . . . . . . . . . . . . . .

10 Converso e Validao
10.1 Converso . . . . . . . . . . . . . . . .
10.1.1 Converso Padro Implcita . .
10.1.2 Converso Padro Explcita . .
10.2 Mensagens de Erro . . . . . . . . . . .
10.2.1 h:message . . . . . . . . . . . .
10.2.2 h:messages . . . . . . . . . . .
10.2.3 Alterando as Mensagens de Erro
10.3 Exerccios . . . . . . . . . . . . . . . .
10.4 Validao . . . . . . . . . . . . . . . .
10.4.1 Validao Padro . . . . . . . .
10.4.2 Campo Obrigatrio (Required) .
10.4.3 f:validateLongRange . . . . . .
10.4.4 f:validateDoubleRange . . . . .
10.4.5 f:validateLength . . . . . . . .
10.4.6 f:validateRegex . . . . . . . . .
10.4.7 Bean Validation . . . . . . . . .
10.5 Exerccios . . . . . . . . . . . . . . . .
v

.
.
.
.
.
.

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

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

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

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

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

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

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

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

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

.
.
.
.
.
.

77
77
78
78
80
81
81

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

85
85
86
86
86
87
87
87
87
88
88
89
90
90
91
92

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

95
95
95
96
97
97
98
98
99
101
101
101
101
102
102
102
102
103

K19 Treinamentos

SUMRIO

SUMRIO

11 Eventos
11.1 Eventos de Aplicao (Application Events)
11.1.1 ActionEvent . . . . . . . . . . . .
11.1.2 ValueChangeEvent . . . . . . . . .
11.2 Eventos de Ciclo de Vida (Lifecycle Events)
11.3 Exerccios . . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

107
107
107
108
109
109

12 Ajax
12.1 Fazendo requisies AJAX . . . . . . . .
12.2 Recarregando alguns pedaos das telas .
12.3 Processando alguns pedaos das telas .
12.4 Palavras especiais . . . . . . . . . . . . .
12.5 Exerccios . . . . . . . . . . . . . . . . .

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

.
.
.
.
.

113
113
114
115
115
116

13 Projeto
13.1 Modelo . . . . . . . . . . . . . . . . . . . . . . .
13.2 Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.3 Persistncia - Mapeamento . . . . . . . . . . . . .
13.4 Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.5 Persistncia - Configurao . . . . . . . . . . . . .
13.6 Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.7 Persistncia - Open Session in View . . . . . . . .
13.7.1 Gerenciando as fbricas de Entity Managers
13.7.2 Filtros . . . . . . . . . . . . . . . . . . . .
13.7.3 Gerenciando os Entity Managers . . . . . .
13.8 Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.9 Persistncia - Repositrios . . . . . . . . . . . . .
13.10Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.11Apresentao - Template . . . . . . . . . . . . . .
13.12Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.13Cadastrando e Listando Selees . . . . . . . . . .
13.14Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.15Mensagens de Erro . . . . . . . . . . . . . . . . .
13.16Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.17Removendo Selees . . . . . . . . . . . . . . . .
13.18Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.19Otimizando o nmero de consultas . . . . . . . . .
13.20Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.21Cadastrando, Listando e Removendo Jogadores . .
13.22Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.23Removendo Selees com Jogadores . . . . . . . .
13.24Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.25Controle de Acesso . . . . . . . . . . . . . . . . .
13.26Exerccios . . . . . . . . . . . . . . . . . . . . . .
13.27Ordem dos filtros . . . . . . . . . . . . . . . . . .
13.28Exerccios . . . . . . . . . . . . . . . . . . . . . .

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

119
119
119
120
120
121
121
122
122
123
123
124
125
126
127
127
129
130
132
132
133
133
133
134
135
135
139
139
140
140
143
143

www.k19.com.br

.
.
.
.
.

vi

SUMRIO
13.29Controle de Erro
13.30Exerccios . . . .
13.31Enviando email .
13.32Exerccios . . . .

vii

SUMRIO
.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

.
.
.
.

144
144
146
147

K19 Treinamentos

SUMRIO

www.k19.com.br

SUMRIO

viii

Captulo 1
Banco de dados
O nosso objetivo desenvolver aplicaes em Java. Essas aplicaes necessitam armazenar
as informaes relacionadas ao seu domnio em algum lugar. Por exemplo, uma aplicao de
gerenciamento de uma livraria deve armazenar os dados dos livros que ela comercializa. Uma
forma de suprir essa necessidade seria armazenar essas informaes em arquivos. Contudo,
alguns fatores importantes nos levam a descartar tal opo.
A seguir, apresentamos as principais preocupaes a serem consideradas ao trabalhar com
dados:
Segurana: As informaes potencialmente confidenciais devem ser controladas de forma que
apenas usurios e sistemas autorizados tenham acesso a elas.
Integridade: Eventuais falhas de software ou hardware no devem corromper os dados.
Acesso: As funes de consulta e manipulao dos dados devem ser implementadas.
Concorrncia: Usualmente, diversos sistemas e usurios acessaro as informaes de forma
concorrente. Apesar disso, os dados no podem ser perdidos ou corrompidos.
Considerando todos esses aspectos, conclumos que seria necessria a utilizao de um
sistema complexo para manusear as informaes das nossas aplicaes.
Felizmente, tal tipo de sistema j existe e conhecido como Sistema Gerenciador de
Banco de Dados (SGBD).

Sistemas gerenciadores de banco de dados


No mercado, h diversas opes de sistemas gerenciadores de banco de dados. A seguir,
apresentamos os mais populares:
1

Banco de dados
Oracle
SQL Server
MySQL Server
PostgreSQL

MySQL Server
Neste treinamento, utilizaremos o MySQL Server, que mantido pela Oracle e vastamente
utilizado no mercado. O MySQL Server pode ser obtido a partir do site:
http://www.mysql.com.

MySQL Query Browser


Para interagir com o MySQL Server, utilizaremos um cliente com interface grfica chamado
de MySQL Query Browser.

1.1

Bases de dados (Databases)

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


sistemas ao mesmo tempo. Por exemplo, as informaes dos clientes de um banco, alm dos
produtos de uma loja virtual.
Caso os dados fossem mantidos sem nenhuma separao lgica, a organizao ficaria prejudicada. Alm disso, seria mais difcil implementar regras de segurana referentes ao acesso
dos dados. Tais regras criam restries quanto ao contedo acessvel por cada usurio. Determinado usurio, por exemplo, poderia ter permisso de acesso aos dados dos clientes do banco,
mas no s informaes dos produtos da loja virtual, ou vice-versa.
Ento, por questes de organizao e segurana, os dados devem ser armazenados separadamente no SGBD. Da surge o conceito de base de dados (database).
Uma base de dados um agrupamento lgico das informaes de um determinado domnio,
como, por exemplo, os dados da nossa livraria.

Criando uma base de dados no MySQL Server


Para criar uma base de dados no MySQL Server, utilizamos o comando CREATE DATABASE.
www.k19.com.br

Banco de dados

K19 Treinamentos

Banco de dados

Repare que alm da base de dados livraria h outras trs bases. Essas bases foram criadas
automaticamente pelo prprio MySQL Server para teste ou para guardar algumas configuraes.
Quando uma base de dados no mais necessria, ela pode ser removida atravs do comando DROP DATABASE.

1.2

Tabelas

Um servidor de banco de dados dividido em bases de dados com o intuito de separar


as informaes de sistemas diferentes. Nessa mesma linha de raciocnio, podemos dividir os
dados de uma base a fim de agrup-los segundo as suas correlaes. Essa separao feita
atravs de tabelas. Por exemplo, no sistema de um banco, interessante separar o saldo e o
limite de uma conta, do nome e CPF de um cliente. Ento, poderamos criar uma tabela para
os dados relacionados s contas e outra para os dados relacionados aos clientes.

nome
Jos
Maria

Cliente
idade cpf
27
31875638735
32
30045667856

numero
1
2

Conta
saldo
1000
2000

www.k19.com.br

limite
500
700
4

Banco de dados
Uma tabela formada por registros(linhas) e os registros so formados por campos(colunas).
Por exemplo, suponha 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.

K19 Treinamentos

Banco de dados

www.k19.com.br

Banco de dados

Se uma tabela no for mais desejada ela pode ser removida atravs do comando DROP
TABLE.

1.3

Operaes Bsicas

As operaes bsicas para manipular os dados das tabelas so: inserir, ler, alterar e remover.
Essas operaes so realizadas atravs da linguagem de consulta denominada SQL. Esta
linguagem oferece quatro comandos bsicos: INSERT, SELECT, UPDATE e DELETE.
Estes comandos so utilizados para inserir, ler, alterar e remover registros respectivamente.
7

K19 Treinamentos

Banco de dados

www.k19.com.br

Banco de dados

K19 Treinamentos

Banco de dados

www.k19.com.br

10

Banco de dados

1.4

Chaves Primria e Estrangeira

Suponha que os livros da nossa livraria so separados por editoras. Uma editora possui
nome e telefone. Para armazenar esses dados, uma nova tabela deve ser criada.
Nesse momento, teramos duas tabelas (Livro e Editora). Eventualmente, ser necessrio
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 a
qual ele pertence. 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 poderamos adicionar registros com editoras inexistentes, pois no h nenhum vnculo explcito entre as tabelas. Para solucionar estes 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
devem 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 deve ser
uma chave estrangeira associada ao campo id.
Uma chave estrangeira um conjunto de uma ou mais colunas de uma tabela que possuem
valores 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 obteramos uma mensagem de erro.

1.5

Consultas Avanadas

Com o conceito de chave estrangeira, podemos fazer consultas complexas envolvendo os


registros de duas ou mais tabelas. Por exemplo, descobrir todos os livros de uma determinada
editora.

11

K19 Treinamentos

Banco de dados

1.6

Exerccios

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

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

www.k19.com.br

12

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

4. Selecione a base de dados livraria como padro.


13

K19 Treinamentos

Banco de dados

5. Crie uma tabela chamada Editora conforme as figuras abaixo.

Altere o modo de criao da tabela para InnoDB, conforme mostrado na figura.


www.k19.com.br

14

Banco de dados

Crie os campos conforme a figura e no esquea de tornar todos os campos obrigatrios,


marcando a opo NOT NULL. Alm disso o campo id deve ser uma chave primria e
automaticamente incrementada.
15

K19 Treinamentos

Banco de dados

6. Crie uma tabela chamada Livro conforme as figuras abaixo:

Altere o modo de criao da tabela para InnoDB, conforme mostrado na figura.


www.k19.com.br

16

Banco de dados

Novamente, adicione os campos conforme a figura abaixo, lembrando de marcar a opo


NOT NULL. Alm disso o campo id deve ser uma chave primria e automaticamente
incrementada.
17

K19 Treinamentos

Banco de dados

Voc precisa tornar o campo editora_id em uma chave estrangeira. Selecione a aba
Foreign Keys e clique no boto com o smbolo de mais para adicionar uma chave estrangeira. Depois siga os procedimentos conforme mostrados na figura abaixo.
www.k19.com.br

18

Banco de dados

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


19

K19 Treinamentos

Banco de dados

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

www.k19.com.br

20

Banco de dados
9. Consulte os registros da tabela Editora, e em seguida consulte a tabela Livro. Veja exemplos logo abaixo:

21

K19 Treinamentos

Banco de dados
10. Altere alguns dos registros da tabela Livro. Veja o exemplo abaixo:

11. Altere alguns dos registros da tabela Editora. Veja o exemplo abaixo:
www.k19.com.br

22

Banco de dados

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

23

K19 Treinamentos

Banco de dados
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 de uma determinada editora. Veja um
exemplo na figura abaixo:
www.k19.com.br

24

Banco de dados

25

K19 Treinamentos

Banco de dados

www.k19.com.br

26

Captulo 2
JDBC
No captulo anterior, aprendemos que utilizar bancos de dados uma boa soluo para o
armazenamento dos dados de uma aplicao. Entretanto, voc deve ter percebido que a interface de utilizao do MySQL (e dos outros bancos de dados em geral) no muito amigvel. A
desvantagem deste tipo de interface, que ela exige que o usurio conhea a sintaxe da linguagem SQL para escrever as consultas. Alm disso, quando o volume de dados muito grande,
mais difcil visualizar os resultados.
Na prtica uma aplicao com interface simples desenvolvida para permitir que os usurios do sistema possam manipular os dados do banco, evitando desse modo que um usurio
necessite conhecer SQL. Por isso, precisamos fazer com que essa aplicao consiga se comunicar com o banco de dados utilizado no sistema.

2.1

Driver

Como a aplicao precisa conversar com o banco de dados, ela deve trocar mensagens
com o mesmo. O formato das mensagens precisa ser definido previamente. Por questes de
economia de espao, cada bit de uma mensagem tem um significado diferente. Resumidamente,
o protocolo de comunicao utilizado binrio.
Mensagens definidas com protocolos binrios so facilmente interpretadas por computadores. Por outro lado, so complexas para um ser humano compreender. Dessa forma, mais
trabalhoso e mais suscetvel a erro desenvolver uma aplicao que converse com um banco de
dados atravs de mensagens binrias.
Para resolver esse problema e facilitar o desenvolvimento de aplicaes que devem se comunicar com bancos de dados, as empresas que so proprietrias desses bancos oferecem os
drivers de conexo.
Os drivers de conexo atuam como tradutores de comandos escritos em uma determinada
linguagem de programao para comandos no protocolo do banco de dados. Do ponto de vista
do desenvolvedor da aplicao, no necessrio conhecer o complexo protocolo binrio do
banco.
Em alguns casos, o protocolo binrio de um determinado banco de dados fechado. Consequentemente, a nica maneira de se comunicar com o banco de dados atravs de um driver
de conexo.
27

JDBC

2.2

JDBC

Suponha que os proprietrios dos bancos de dados desenvolvessem os drivers de maneira


totalmente independente. Consequentemente, cada driver teria sua prpria interface, ou seja,
seu prprio conjunto de instrues. Dessa maneira, o desenvolvedor da aplicao precisa conhecer as instrues de cada um dos drivers dos respectivos bancos que ele for utilizar.
Para facilitar o trabalho do desenvolvedor da aplicao, foi criado o JDBC (Java Database
Connectivity). O JDBC uma API que generaliza a interface com os banco de dados. Assim,
quando uma empresa proprietria de um banco de dados pretende desenvolver um driver para
ser utilizado com a linguagem Java, ela segue a especificao JDBC com o intuito de incentivar
a adoo do driver.

2.3

Instalando o Driver JDBC do MySQL Server

O driver oficial JDBC desenvolvido para funcionar com o MySQL se chama MySQL Connector/J. necessrio fazer o download do driver na seguinte url:
http://www.mysql.com/downloads/connector/j/.
s descompactar o arquivo e depois incluir o jar com o driver no BUILD PATH da aplicao.

2.4

Criando uma conexo

Com o driver de conexo JDBC adicionado ao projeto, j possvel criar uma conexo com
o banco de dados correspondente. Abaixo, esto os passos necessrios para criar uma conexo.
Escolher o driver de conexo;
Definir a localizao do banco de dados;
Informar o nome da base de dados;
Ter um usurio e senha cadastrados no banco de dados.
As informaes sobre o driver, localizao e nome da base de dados so definidas no que
chamamos de url de conexo (ou string de conexo). O usurio e a senha, informamos no momento de criar uma conexo. Para criar esta conexo, utilizamos as classes D RIVER M ANAGER
(que instancia a conexo) e C ONNECTION (que armazena a nossa conexo), ambas presentes
no pacote JAVA . SQL.
1
2
3
4
5
6
7
8

String urlDeConexao = "jdbc:mysql://localhost/livraria";


String usuario = "root";
String senha = "";
try {
Connection conn = DriverManager.getConnection(urlDeConexao, usuario, senha);
} catch (SQLException e) {
e.printStackTrace();
}

www.k19.com.br

28

JDBC

2.5

Inserindo registros

Estabelecida a conexo com o banco de dados, j podemos executar comandos. Como


primeiro exemplo, iremos inserir registros em uma tabela. O primeiro passo para executar um
comando defini-lo em linguagem SQL.
1
2

string textoDoComando = "INSERT INTO Editora (nome, email)" +


"VALUES (K19, contato@k19.com.br);";

Em seguida, devemos pedir para uma conexo JDBC atravs do mtodo PREPARE S TATE criar o comando que queremos executar. Este mtodo devolve um objeto da interface
P REPARED S TATEMENT. O comando no executado na chamada do mtodo PREPARE S TA TEMENT () e sim posteriormente quando o mtodo EXECUTE () for utilizado.
MENT ()

1
2
3
4
5

// criando comando
PreparedStatement comando = conexao.prepareStatement(textoDoComando);
// executando o comando
comando.execute();
comando.close();

Podemos utilizar a mesma conexo para executar diversos comandos. Quando no desejamos executar mais comandos, devemos fechar a conexo atravs do mtodo CLOSE (). Fechar
as conexes que no so mais necessrias importante pois os SGBDs possuem um nmero
limitado de conexes abertas.
1

close.close();

2.6

Exerccios

1. Crie um projeto java no eclipse chamado JDBC.

2. Crie uma pasta chamada lib no projeto JDBC.

3. Entre na pasta K19-Arquivos/MySQL-Connector-JDBC da rea de Trabalho e copie


o arquivo MYSQL - CONNECTOR - JAVA -5.1.13- BIN . JAR para pasta lib do projeto JDBC.

4. Adicione o arquivo MYSQL - CONNECTOR - JAVA -5.1.1. JAR ao build path (veja figura).
29

K19 Treinamentos

JDBC

5. Crie uma nova classe, com o nome InsereEditora, e adicione o seguinte contedo ao
arquivo:
www.k19.com.br

30

JDBC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

import
import
import
import

java.sql.Connection;
java.sql.DriverManager;
java.sql.PreparedStatement;
java.util.Scanner;

public class InsereEditora {


public static void main(String[] args) {
String stringDeConexao = "jdbc:mysql://localhost:3306/livraria";
String usuario = "root";
String senha = "root";
Scanner entrada = new Scanner(System.in);
try {
System.out.println("Abrindo conexao...");
Connection conexao =
DriverManager.getConnection(stringDeConexao, usuario, senha);
System.out.println("Digite o nome da editora: ");
String nome = entrada.nextLine();
System.out.println("Digite o email da editora: ");
String email = entrada.nextLine();
String textoDoComando = "INSERT INTO Editora (nome, email) " +
"VALUES (" + nome + ", " + email + ")";
PreparedStatement comando = conexao.prepareStatement(textoDoComando);
System.out.println("Executando comando...");
comando.execute();
System.out.println("Fechando conexao...");
conexao.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

Rode e veja se o registro foi inserido com sucesso na base de dados.

6. (Opcional) Analogamente, ao exerccio anterior crie um programa para inserir livros.

2.7

SQL Injection

Apesar de funcional, a implementao da insero de registros feita anteriormente apresenta


uma falha grave. Os dados obtidos do usurio atravs do teclado no so tratados antes de serem
enviados para o banco de dados.
Esses dados podem conter algum carcter especial que altere o comportamento desejado da
consulta impedindo que algum registro seja inserido corretamente ou at abrindo uma brecha
para que um usurio mal intencionado execute alguma consulta SQL para utilizar de maneira
inadequada os dados da nossa aplicao.
31

K19 Treinamentos

JDBC

O problema de SQL Injection pode ser resolvido manualmente. Basta fazer escape dos
caracteres especiais, por exemplo: ponto-e-vrgula e apstrofo. No MySQL Server, os caracteres especiais devem ser precedidos pelo carcter \. Ento seria necessrio acrescentar \ em
todas as ocorrncias de caracteres especiais nos valores passados pelo usurio.
A desvantagem desse processo que, alm de trabalhoso, diferente para cada banco de
dados, pois o \ no padronizado e cada banco tem o seu prprio mtodo de escape de
caracteres especiais.
Para tornar mais prtica a comunicao com o banco de dados, o prprio driver faz o tratamento das sentenas SQL. Esse processo denominado sanitize.

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

// lendo a entrada feita pelo usuario


System.out.println("Digite o nome da editora: ");
String nome = entrada.nextLine();
System.out.println("Digite o email da editora: ");
String email = entrada.nextLine();
// texto do comando inclui parmetros
String textoDoComando = "INSERT INTO Editora (nome, email) " +
"VALUES (?, ?)";
// criao e adio de parmetros ao comando
PreparedStatement comando = conexao.prepareStatement(textoDoComando);
comando.setString(1, nome);
comando.setString(2, email);

Observe que a sentena SQL foi definida com parmetros atravs do carcter ?. Antes de
executar o comando, necessrio atribuir valores aos parmetros. Isso feito com o mtodo
SET S TRING , que recebe o ndice (posio) do parmetro na consulta e o valor correspondente.
De maneira similar, temos os mtodos SET I NT, SET D OUBLE, SET DATE, etc, variando conforme o tipo do campo que foi definido no banco.
Os mtodos acima mostrados, realizam a tarefa de sanitizar(limpar) os valores enviados
pelo usurio.
www.k19.com.br

32

JDBC

2.8

Exerccios

7. Tente causar um erro de SQL Injection na classe feita no exerccio de inserir editoras.
(Dica: tente entradas com aspas simples)
8. Altere o cdigo para eliminar o problema do SQL Injection. Voc deve deixar a classe
com o cdigo abaixo:

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

public class InsereEditora {


public static void main(String[] args) {
String stringDeConexao = "jdbc:mysql://localhost:3306/livraria";
String usuario = "root";
String senha = "root";
Scanner entrada = new Scanner(System.in);
try {
System.out.println("Abrindo conexao...");
Connection conexao = DriverManager.getConnection(stringDeConexao, usuario, senha);
System.out.println("Digite o nome da editora: ");
String nome = entrada.nextLine();
System.out.println("Digite o email da editora: ");
String email = entrada.nextLine();
String textoDoComando = "INSERT INTO Editora (nome, email) " +
"VALUES (?, ?)";
PreparedStatement comando = conexao.prepareStatement(textoDoComando);
comando.setString(1, nome);
comando.setString(2, email);
System.out.println("Executando comando...");
comando.execute();
System.out.println("Fechando conexao...");
conexao.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

9. Agora tente causar novamente o problema de SQL Injection ao inserir novas editoras.

2.9

Listando registros

O processo para executar um comando de consulta bem parecido com o processo de inserir
registros.
33

K19 Treinamentos

JDBC
1
2
3
4
5
6

String textoDoComando = "SELECT * FROM Editora;";


PreparedStatement comando = conexao.prepareStatement(textoDoComando);
System.out.println("Executando comando...");
ResultSet resultado = comando.executeQuery();

A diferena que para executar um comando de consulta necessrio utilizar o mtodo


EXECUTE Q UERY () ao invs do EXECUTE (). Esse mtodo devolve um objeto da interface
JAVA . SQL .R ESULT S ET , que responsvel por armazenar os resultados da consulta.
Os dados contidos no R ESULT S ET podem ser acessados atravs de mtodos, como o GET STRING , GET I NT , GET D OUBLE, etc, de acordo com o tipo do campo. Esses mtodos recebem
como parmetro uma string referente ao nome da coluna correspondente.
1
2
3

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

O cdigo acima mostra como os campos do primeiro registro da consulta so recuperados.


Agora, para recuperar os outros registros necessrio avanar o R ESULT S ET atravs do mtodo
NEXT .
1
2
3
4
5
6
7
8
9

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


String nome1 = resultado.getString("nome"),
String email1 = resultado.getString("email");
resultado.next();
int id2 = resultado.getInt("id"),
String nome2 = resultado.getString("nome"),
String email2 = resultado.getString("email");

O prprio mtodo NEXT devolve um valor booleano para indicar se o R ESULT S ET conseguiu avanar para o prximo registro. Quando esse mtodo devolver FALSE significa que no
h mais registros para serem consultados.
1
2
3
4
5

while(resultado.next()) {
int id = resultado.getInt("id"),
String nome = resultado.getString("nome"),
String email = resultado.getString("email");
}

2.10

Exerccios

10. Insira algumas editoras utilizando a classe I NSERE E DITORA que voc criou nos exerccios acima.
11. Adicione uma nova classe ao projeto chamada ListaEditoras. O objetivo listar as
editoras que foram salvas no banco. Adicione o seguinte cdigo esta classe.
www.k19.com.br

34

JDBC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

import
import
import
import

java.sql.Connection;
java.sql.DriverManager;
java.sql.PreparedStatement;
java.sql.ResultSet;

public class ListaEditoras {


public static void main(String[] args) {
String stringDeConexao = "jdbc:mysql://localhost:3306/livraria";
String usuario = "root";
String senha = "root";
try {
System.out.println("Abrindo conexao...");
Connection conexao =
DriverManager.getConnection(stringDeConexao, usuario, senha);
String textoDoComando = "SELECT * FROM Editora;";
PreparedStatement comando = conexao.prepareStatement(textoDoComando);
System.out.println("Executando comando...");
ResultSet resultado = comando.executeQuery();
System.out.println("Resultados encontrados: \n");
while (resultado.next()) {
System.out.printf("%d : %s - %s\n",
resultado.getInt("id"),
resultado.getString("nome"),
resultado.getString("email"));
}
System.out.println("\nFechando conexao...");
conexao.close();
}
catch (Exception e) {
e.printStackTrace();
}
}
}

2.11

Fbrica de conexes (Factory)

Voc deve ter percebido que em diversos pontos diferentes da nossa aplicao precisamos
de uma conexo JDBC. Se a url de conexo for definida em cada um desses pontos teremos
um problema de manuteno. Imagine que o driver do banco seja atualizado ou que o ip do
SGBD seja alterado. Teramos que alterar o cdigo da nossa aplicao em muitos lugares, mais
precisamente, em cada ocorrncia da url de conexo. A probabilidade de algum ponto no ser
corrigido grande.
Para diminuir o trabalho de manuteno, ns poderamos criar uma classe responsvel pela
criao e distribuio de conexes. Nessa e somente nessa classe estaria definida a url de
conexo. Dessa forma, qualquer alterao no modo em que nos conectamos base de dados,
s acarreta mudanas nesta classe.
35

K19 Treinamentos

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

public class FabricaDeConexao {


public static Connection criaConexao() {
String stringDeConexao = "jdbc:mysql://localhost:3306/livraria";
String usuario = "root";
String senha = "root";
Connection conexao = null;
try {
conexao = DriverManager.getConnection(stringDeConexao, usuario, senha);
} catch (SQLException e) {
e.printStackTrace();
}
return conexao;
}
}

Agora podemos obter uma nova conexo apenas chamando FABRICA D E C ONEXAO .C RIAC ONEXAO ().
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.

2.12

Exerccios

12. Adicione uma nova classe chamada FABRICA D E C ONEXAO e adicione o seguinte cdigo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class FabricaDeConexao {
public static Connection CriaConexao() {
String stringDeConexao = "jdbc:mysql://localhost:3306/livraria";
String usuario = "root";
String senha = "root";
Connection conexao = null;
try {
conexao = DriverManager.getConnection(stringDeConexao, usuario, senha);
} catch (SQLException e) {
e.printStackTrace();
}
return conexao;
}
}

13. Altere as classes I NSERE E DITORA e L ISTA E DITORAS para que elas utilizem a fbrica
de conexo. Execute-as novamente.
14. (Opcional) Implemente um teste que remove uma editora pelo id.
15. (Opcional) Implemente um teste que altera os dados de uma editora pelo id.

www.k19.com.br

36

Captulo 3
JPA 2 e Hibernate
3.1

Mltiplas sintaxes da linguagem SQL

No captulo anterior, voc aprendeu a utilizar a especificao JDBC para fazer uma aplicao Java interagir com um banco de dados. Essa interao realizada atravs de consultas
escritas em SQL. Uma desvantagem dessa abordagem, que a sintaxe da linguagem SQL, apesar de parecida, pode variar conforme o banco de dados que est sendo utilizado. Desse modo,
os desenvolvedores teriam que aprender as diferenas entres as sintaxes do SQL correspondentes aos banco de dados que ele utilizar.
Seria bom se, ao invs de programar direcionado a um determinado banco de dados, pudssemos programar de uma maneira mais genrica, voltado uma interface ou especificao,
assim poderamos escrever o cdigo independente de SQL.

3.2

Orientao a Objetos VS Modelo Entidade Relacionamento

Outro problema na comunicao entre uma aplicao Java e um banco de dados o conflito
de paradigmas. O banco de dados organizado seguindo o modelo entidade relacionamento,
enquanto as aplicaes Java, geralmente, utilizam o paradigma orientado a objetos.
A transio de dados entre o modelo entidade relacionamento e o modelo orientado a objetos no simples. Para realizar essa transio, necessrio definir um mapeamento entre
os conceitos desses dois paradigmas. Por exemplo, classes podem ser mapeadas para tabelas,
objetos para registros, atributos para campos e referncia entre objetos para chaves estrangeiras.

3.3

Ferramentas ORM

Para facilitar a comunicao entre aplicaes Java que seguem o modelo orientado a objetos e os banco de dados que seguem o modelo entidade relacionamento, podemos utilizar
ferramentas que automatizam a transio de dados entre as aplicaes e os diferente bancos de
dados e que so conhecidas como ferramentas de ORM (Object Relational Mapper).
Outra consequncia, ao utilizar uma ferramenta de ORM, que no necessrio escrever
consultas em SQL, pois a prpria ferramenta gera as consultas de acordo com a sintaxe da
37

JPA 2 e Hibernate
linguagem SQL correspondente ao banco que est sendo utilizado.
A principal ferramenta ORM para Java utilizada no mercado de TI o Hibernate. Mas,
existem outras que possuem o mesmo objetivo.

3.4

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 complexidade do desenvolvimento. Atualmente, essa especificao est na sua segunda
verso.
Ela especfica um conjunto de classes e mtodos que as ferramentas de ORM devem implementar. Veja que a JPA apenas uma especificao, ela no implementa nenhum cdigo.
Para isso, utilizamos alguma das diversas implementaes da JPA. Neste curso, utilizaremos o
Hibernate como implementao de JPA. As outras implementaes de JPA mais conhecidas
so: TopLink, EclipseLink e OpenJPA. Optamos por utilizar o Hibernate por ele ser o mais
antigo e mais utilizado atualmente.
Caso voc queira utilizar outro framework ORM, poder aplicar os conceitos aqui aprendidos justamente por que eles seguem a mesma especificao. Assim podemos programar voltado
especificao 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 aplicao permaneceria o mesmo.

3.5

Configurao

Antes de comear a utilizar o Hibernate, necessrio baixar no site oficial o bundle que
inclui os jars do hibernate e todas as suas dependncias. Neste curso, utilizaremos a verso
3.5.1. A url do site oficial do Hibernate esta:
(http://www.hibernate.org/)
Para configurar o Hibernate em uma aplicao, devemos criar um arquivo chamado persistence.xml. O contedo desse arquivo possura 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 PERSIS TENCE . XML :
www.k19.com.br

38

JPA 2 e Hibernate
1
2
3
4
5
6
7
8
9
10

<?xml version="1.0" encoding="UTF-8"?>


<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="K19" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="usuario"/>
<property name="javax.persistence.jdbc.password" value="senha"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/k19"/>
</properties>
</persistence-unit>

11
12
13
14
15
16
17
18
19

</persistence>

A propriedade hibernate.dialect permite que a aplicao escolha qual sintaxe de SQL que
deve ser utilizada pelo Hibernate.

3.6

Mapeamento

Um dos principais objetivos dos frameworks ORM estabelecer o mapeamento entre os


conceitos do modelo orientado a objetos e os conceitos do modelo entidade relacionamento.
Este mapeamento pode ser definido atravs de xml ou de maneira mais prtica com anotaes
Java. Quando utilizamos anotaes, evitamos a criao de extensos arquivos em xml.
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 que deve aparecer antes do nome de uma classe.
E deve ser definida em todas as classes que tero objetos persistidos no banco de dados.
As classes anotadas com @E NTITY so mapeadas para tabelas. Por conveno, as tabelas possuem os mesmos nomes das classes. Mas, podemos alterar esse comportamento
utilizando a anotao @TABLE.
Os atributos declarados em uma classe anotada com @E NTITY so mapeados para colunas na tabela correspondente classe. Outra vez, por conveno, as colunas possuem
os mesmos nomes dos atributos. E novamente, podemos alterar esse padro utilizando a
anotao @C OLUMN.
@Id Utilizada para indicar qual atributo de uma classe anotada com @E NTITY ser mapeado
para a chave primria da tabela correspondente classe. Geralmente o atributo anotado
com @I D do tipo L ONG.
@GeneratedValue Geralmente vem acompanhado da anotao @I D. Serve para indicar que
o atributo gerado pelo banco, no momento em que um novo registro inserido.
39

K19 Treinamentos

JPA 2 e Hibernate
@Table Utilizada para alterar o nome padro da tabela. Ela recebe o parmetro name para
indicar qual nome que deve ser utilizado na tabela. Veja o exemplo:
1
2
3
4

@Table(name="Publisher")
@Entity
public class Editora {
// ...

@Column Utilizado para alterar o nome da coluna que ser utilizado na tabela. Caso voc
esteja utilizando um banco de dados legado, no qual os nomes das colunas j foram
definidos, voc pode mudar atravs dessa anotao. Alm disso, podemos estabelecer
certas restries, como determinar se o campo pode ou no ser nulo.
1
2
3
4

@Entity
public class Editora {
@Column(name="publisher_name",nullable=false)
private String nome;

@Transient Serve para indicar um atributo que no deve ser persistido, ou seja, os atributos
anotados com @T RANSIENT no so mapeados para colunas.
@Lob Utilizado para atributos que armazenam textos muito grandes, ou arquivos binrios
contendo imagens ou sons que sero persistidos no banco de dados. O tipo do atributo
deve ser S TRING, B YTE [], BYTE [] ou JAVA . SQL .B LOB.
@Temporal Utilizado para atributos do tipo C ALENDAR ou DATE. Por padro, tanto data
quanto hora so armazenados no banco de dados. Mas, com a anotao @T EMPORAL,
podemos mandar persistir somente a data ou sement a hora.
1
2
3
4
5

3.7

@Entity
public class Livro {
@Temporal(TemporalType.DATE)
private Calendar publicacao;
// ...

Gerando o banco

Uma das vantagens de 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 mtodo da classe P ERSISTENCE, o CREATE E NTITY M A NAGER FACTORY ( STRING ENTITY U NIT ). O parmetro ENTITY U NIT permite escolher, pelo
nome, uma unidade de persistncia definida no PERSISTENCE . XML.
A poltica de criao das tabelas pode ser alterada configurando a propriedade HIBER NATE . HBM 2 DDL . AUTO no arquivo PERSISTENCE . XML . Podemos, por exemplo, fazer com
www.k19.com.br

40

JPA 2 e Hibernate
que o Hibernate sempre sobrescreva as tabelas existentes, basta configurar a propriedade
BERNATE . HBM 2 DDL . AUTO com o valor CREATE - DROP .
1

HI -

<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 HIBER NATE . HBM 2 DDL . AUTO deve ser UPDATE .
1

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

3.8

Exerccios

1. Crie um projeto no eclipse chamado JPA2-Hibernate e feche o projeto JDBC para no


gerar confuso na hora de manipular os arquivos.
2. Crie uma pasta chamada lib dentro do projeto JPA2-Hibernate.
3. Entre na pasta K19-Arquivos/Hibernate da rea de Trabalho e copie os jars do Hibernate para a pasta lib do projeto JPA2-Hibernate.
4. Entre na pasta K19-Arquivos/MySQL-Connector-JDBC da rea de Trabalho e copie
o arquivo MYSQL - CONNECTOR - JAVA -5.1.13. BIN . JAR para pasta lib do projeto JPA2Hibernate.
5. Entre na pasta K19-Arquivos/SLF4J da rea de Trabalho e copie os jars para pasta lib
do projeto JPA2-Hibernate.
6. Entre na pasta K19-Arquivos/Log4J da rea de Trabalho e copie o arquivo
1.2.16. JAR para pasta lib do projeto JPA2-Hibernate.

LOG 4 J -

7. Adicione os jars da pasta lib ao build path do projeto JPA2-Hibernate.


8. Crie uma pasta chamada META-INF na pasta src no projeto JPA2-Hibernate.
9. Crie o arquivo de configuraes persistence.xml na pasta META-INF.
41

K19 Treinamentos

JPA 2 e Hibernate
1
2
3
4
5
6
7
8
9
10

<?xml version="1.0" encoding="UTF-8"?>


<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="livraria" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
<property name="hibernate.hbm2ddl.auto" value="create"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="root"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/livraria"/>
</properties>
</persistence-unit>

11
12
13
14
15
16
17
18
19

</persistence>

10. Crie uma classe para modelar as editoras da nossa livraria e acrescente as anotaes necessrias para fazer o mapeamento. Obs: As anotaes devem ser importadas do pacote
JAVAX . PERSISTENCE .
1
2
3
4
5
6
7
8
9
10
11

@Entity
public class Editora {
@Id @GeneratedValue
private Long id;
private String nome;
private String email;
// GETTERS AND SETTERS
}

11. Apague a tabela Livro e depois a Editora.


12. Configure o Log4J criando um arquivo chamado log4j.properties na pasta src do projeto
JPA2-Hibernate.

log4j.rootCategory=INFO, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%r [%t] %-5p %c - %m%n

13. Gere as tabelas atravs da classe P ERSISTENCE. Para isso, crie uma classe com mtodo
MAIN . Obs: As classes devem ser importadas do pacote JAVAX . PERSISTENCE .
www.k19.com.br

42

JPA 2 e Hibernate
1
2
3
4
5
6
7
8

public class GeraTabelas {


public static void main(String[] args) {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("livraria");
factory.close()
}
}

Atravs do MySQL Query Browser verifique se a tabela E DITORA foi criada corretamente.

3.9

Manipulando entidades

Para manipular as entidades da nossa aplicao, devemos utilizar um E NTITY M ANAGER


que obtido atravs de uma E NTITY M ANAGER FACTORY.
1
2
3
4

EntityManagerFactory factory =
Persistence.createEntityManagerFactory("K19");
EntityManager manager = factory.createEntityManager();

3.9.1

Persistindo

Para armazenar as informaes de um objeto no banco de dados basta utilizar o mtodo


PERSIST () do E NTITY M ANAGER .
1
2
3
4
5

Editora novaEditora = new Editora();


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

3.9.2

Buscando

Para obter um objeto que contenha informaes do banco de dados basta utilizar o mtodo
ou o GET R EFERENCE () do E NTITY M ANAGER.

FIND ()
1
2

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


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

A diferena entre os dois mtodos bsicos de busca FIND () e GET R EFERENCE () que
o primeiro recupera os dados desejados imediatamente j o segundo posterga at a primeira
chamada de um mtodo GET do objeto.
43

K19 Treinamentos

JPA 2 e Hibernate

3.9.3

Removendo

Para remover um registro correspondente a um objeto basta utilizar o mtodo


do E NTITY M ANAGER.
1
2

REMOVE ()

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


manager.remove(editora1);

3.9.4

Atualizando

Para alterar os dados de um registro correspondente a um objeto basta utilizar os prprios


mtodos setters desse objeto.
1
2

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


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

3.9.5

Listando

Para obter uma listagem com todos os objetos referentes aos registros de uma tabela, devemos utilizar a linguagem de consulta do JPA, a JPQL que muito parecida com a linguagem
SQL. A vantagem do JPQL em relao ao SQL que a sintaxe a mesma para bancos de dados
diferentes.
1
2

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


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

3.9.6

Transaes

As modificaes realizadas nos objetos administrados por um E NTITY M ANAGER 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 E NTITY M ANAGER que administra os objetos que desejamos sincronizar.
Para abrir uma transao utilizamos o mtodo BEGIN ().
1

manager.getTransaction().begin();

Com a transao aberta podemos sincronizar os dados com o banco atravs do mtodo
ou COMMIT ().

FLUSH ()
1
2
3
4
5

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


editora.setNome("K19 - Livros e Publicaes");
manager.getTransaction().begin();
manager.flush();

www.k19.com.br

44

JPA 2 e Hibernate
1
2
3
4
5

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


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

3.10

Exerccios

14. No arquivo de configuraes PERSISTENCE . XML, altere o valor da propriedade HIBER NATE . HBM 2 DDL . AUTO para UPDATE . Assim as tabelas no sero recriadas a cada execuo e sim apenas atualizadas.

15. Crie um teste para inserir editoras no banco de dados.

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

public class InsereEditoraComJPA {


public static void main(String[] args) {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("livraria");
EntityManager manager = factory.createEntityManager();
Editora novaEditora = new Editora();
Scanner entrada = new Scanner(System.in);
System.out.println("Digite o nome da editora: ");
novaEditora.setNome(entrada.nextLine());
System.out.println("Digite o email da editora: ");
novaEditora.setEmail(entrada.nextLine());
manager.persist(novaEditora);
manager.getTransaction().begin();
manager.getTransaction().commit();
factory.close();
}
}

16. Crie um teste para listar as editoras inseridas no banco de dados.


45

K19 Treinamentos

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

public class ListaEditorasComJPA {


public static void main(String[] args) {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("livraria");
EntityManager manager = factory.createEntityManager();
Query query = manager.createQuery("SELECT e FROM Editora e");
List<Editora> editoras = query.getResultList();
for(Editora e : editoras) {
System.out.println("EDITORA: " + e.getNome() + " - " + e.getEmail());
}
}
}

3.11

Repository

A interface E NTITY M ANAGER 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
E NTITY M ANAGER pode gerar dificuldades na manuteno e no entendimento do sistema.
Para melhorar a organizao das nossas aplicaes, diminuindo o custo de manuteno e
aumentando a legibilidade do cdigo, podemos aplicar o padro Repository do DDD(Domain
Driven Design).
Conceitualmente, um repositrio representa o conjunto de todos os objetos de um determinado tipo. Ele deve oferecer mtodos para recuperar e para adicionar elementos.
Os repositrios podem trabalhar com objetos prontos na memria ou reconstru-los com
dados obtidos de um banco de dados. O acesso ao banco de dados pode ser realizado atravs
de ferramenta ORM como o Hibernate.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

class EditoraRepository {
private EntityManager manager;
public EditoraRepository(EntityManager manager) {
this.manager = manager;
}
public void adiciona(Editora e) {
this.manager.persist(e);
}
public Editora busca(Long id) {
return this.manager.find(Editora.class, id);
}
public List<Editora> buscaTodas() {
Query query = this.manager.createQuery("SELECT e FROM Editora e");
return query.getResultList();
}
}

www.k19.com.br

46

JPA 2 e Hibernate
1
2
3
4
5
6
7

EntityManagerFactory factory =

Persistence.createEntityManagerFactory("K12");

EntityManager manager = factory.createEntityManager();


EditoraRepository editoraRepository = new EditoraRepository(manager);
List<Editora> editoras = editoraRepository.buscaTodas();

3.12

Exerccios

17. Implemente um repositrio de editoras criando uma nova classe no projeto JPA2-Hibernate.

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

class EditoraRepository {
private EntityManager manager;
public EditoraRepository(EntityManager manager) {
this.manager = manager;
}
public void adiciona(Editora e) {
this.manager.persist(e);
}
public Editora busca(Long id) {
this.manager.find(Editora.class, id);
}
public List<Editora> buscaTodas() {
Query query = this.manager.createQuery("SELECT e FROM Editora e");
return query.getResultList();
}
}

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

K19 Treinamentos

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

public class InsereEditoraComJPA {


public static void main(String[] args) {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("livraria");
EntityManager manager = factory.createEntityManager();
EditoraRepository editoraRepository = new EditoraRepository(manager);
Editora novaEditora = new Editora();
Scanner entrada = new Scanner(System.in);
System.out.println("Digite o nome da editora: ");
novaEditora.setNome(entrada.nextLine());
System.out.println("Digite o email da editora: ");
novaEditora.setEmail(entrada.nextLine());
editoraRepository.adiciona(novaEditora);
manager.getTransaction().begin();
manager.getTransaction().commit();
factory.close();
}
}

19. (Opcional) Altere a classe ListaEditorasComJPA para que ela utilize o repositrio de
editoras.

www.k19.com.br

48

Captulo 4
Web Container
4.1

Necessidades de uma aplicao web

As aplicaes web so acessadas pelos navegadores (browsers). A comunicao entre os


navegadores e as aplicaes web realizada atravs de requisies e respostas definidas pelo
protocolo HTTP. Portando, ao desenvolver uma aplicao web, devemos estar preparados para
receber requisies HTTP e enviar respostas HTTP.
Alm disso, na grande maioria dos casos, as aplicaes web devem ser acessadas por diversos usurios simultaneamente. Dessa forma, o desenvolvedor web precisa saber como permitir
o acesso simultneo.
Outra necessidade das aplicaes web gerar contedo dinmico. Por exemplo, quando
um usurio de uma aplicao de email acessa a sua caixa de entrada, ele deseja ver a listagem
atualizada dos seus emails. Portanto, fundamental que a listagem dos emails seja gerada no
momento da requisio do usurio. O desenvolvedor web precisa utilizar algum mecanismo
eficiente que permita que o contedo que os usurios requisitam seja gerado dinamicamente.
Trabalhar diretamente com as requisies e repostas HTTP e criar um mecanismo eficiente
para permitir o acesso simultneo e para gerar contedo dinmico no so tarefas simples. Na
verdade, extremamente trabalhoso implementar essas caractersticas. Por isso, a plataforma
Java oferece uma soluo para diminuir o trabalho no desenvolvimento de aplicaes web.

4.2

Web Container

Uma aplicao web Java deve ser implantada em um Web Container para obter os recursos
fundamentais que as aplicaes web necessitam. Um Web Container responsvel pelo envio e
recebimento de mensagens HTTP, permite que as aplicaes implantadas nele sejam acessadas
simultaneamente por mltiplos usurios de uma maneira eficiente e oferece mecanismos para
que as aplicaes gerem contedo dinamicamente.
Os dois Web Containers mais importantes do mercado so: Tomcat e Jetty. Tambm
podemos utilizar um servidor de aplicao Java EE como o JBoss, Glassfish ou WebSphere
pois eles possuem um Web Container internamente.
49

Web Container

4.3

Especificao Java EE

Como comum na plataforma Java, para padronizar a interface dos recursos oferecidos
pelos Web Containers, especificaes foram definidas. Essas especificaes fazem parte do
conjunto de especificaes do Java EE. O Java EE uma especificao que agrupa diversas
outras especificaes.
Apesar das especificaes, os Web Containers possuem algumas diferenas nas configuraes que devem ser realizadas pelos desenvolvedores. Dessa forma, no h 100% portabilidade
entre os Web Containers. Contudo, a maior parte das configuraes e do modelo de programao padronizado. Sendo assim, se voc conhece bem um dos Web Container tambm conhece
bastante dos outros.

4.4

Exerccios

1. Na rea de Trabalho, entre na pasta K19-Arquivos e copie glassfish-3.0.1-with-hibernate.zip


para o seu Desktop. Descompacte este arquivo na prpria rea de Trabalho.
2. Ainda na rea de Trabalho, entre na pasta glassfishv3/glassfish/bin e execute o script
startserv para executar o glassfish.
3. Verifique se o glassfish est executando atravs de um navegador acessando a url:
http://localhost:8080.
4. Pare o glassfish executando o script stopserv que est na mesma pasta do script startserv.
5. No eclipse, abra a view servers e clique com o boto direito no corpo dela. Escolha a
opo new e configure o glassfish.
6. Execute o glassfish pela view servers e verifique se ele est funcionando acessando atravs de um navegador a url:
http://localhost:8080.
7. Pare o glassfish pela view servers.

4.5

Aplicao Web Java

Para que uma aplicao Web Java possa ser implantada em um Web Container, a estrutura
de pastas precisa seguir algumas regras.
 K19-App/ pasta raiz pode ter qualquer nome
 WEB-INF/

 classes/
 lib/
 web.xml

www.k19.com.br

50

Web Container
A pasta K19-App raiz da nossa aplicao, o nome dessa pasta pode ser definido pelo
desenvolvedor. A pasta WEB-INF deve ser criada dentro da pasta raiz de todas as aplicaes
Web Java, o contedo dessa pasta no pode ser acessado diretamente pelos usurios. A pasta
classes deve ser criada dentro da pasta WEB-INF, o cdigo compilado das aplicaes Web Java
deve ser salvo nessa pasta. A pasta lib deve ser criada dentro da pasta WEB-INF, todos os
jars das bibliotecas que sero utilizadas devem ser colocados nessa pasta. O arquivo web.xml
contm configuraes do Web Container e deve ser criado na pasta WEB-INF. Os arquivos
dentro da pasta raiz da aplicao mas fora da pasta WEB-INF podem ser acessados diretamente
pelos usurios atravs de um navegador.
As IDEs j criam toda a estrutura de pastas exigidas pelos Web Containers. Ento, na
prtica, no temos o trabalho de criar esses diretrios manualmente.

4.6

Exerccios

8. Crie um projeto no eclipse do tipo Dynamic Web Project chamado App-Web-Java


selecionando na ltima tela a opo Generate web.xml deployment descriptor.
9. Execute o projeto no glassfish clicando com o boto direito no nome do projeto e escolhendo a opo Run on Server dentro de Run As.
10. Verifique o funcionamento da nossa aplicao acessando a url:
http://localhost:8080/K19-App/ atravs de um navegador.

4.7

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 da nossa aplicao deve ser gerado. H duas
maneiras fundamentais de gerar contedo dinmico: programando uma Servlet ou um JSP.
Na verdade, os JSPs so traduzidos para Servlets automaticamente pelos Web Containers.
Ento, escrever um JSP apenas uma maneira diferente de escrever uma Servlet.

4.8

Servlet

Para criar uma Servlet, podemos seguir os seguintes passos bsicos:


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 de Servlet 3.0. Antes essa configurao
era realizada atravs do arquivo web.xml.
51

K19 Treinamentos

Web Container
1
2
3
4
5
6
7
8
9

@WebServlet("/OlaMundo")
public class OlaMundo extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// Lgica para processar as regras de negcio e gerar contedo
}
}

Quando um usurio fizer uma requisio para url definida atravs da anotao @W EB S ER VLET, o mtodo service() ser executado. Esse mtodo recebe dois parmetros: o primeiro
uma referncia para um objeto da classe HttpServletRequest que guarda todos os dados da
requisio HTTP realizada pelo navegador do usurio; o segundo uma referncia para um
objeto da classe HttpServletResponse que permite que a resposta HTTP que ser enviada para
o navegador do usurio seja construda pela aplicao.

4.8.1

Inserindo contedo na resposta

Para inserir contedo na resposta HTTP que ser enviada para o navegador do usurio,
devemos utilizar o mtodo getWriter(). Em geral, o contedo inserido na resposta HTTP
texto HTML.
1
2
3
4
5
6
7
8
9
10

@WebServlet("/OlaMundo")
public class OlaMundo extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("<html><body><h1>Ol Mundo</h1></body></html>");
}
}

4.9

Exerccios

11. Crie um pacote chamado servlets no projeto K19-App.


12. Crie uma classe chamada OlaMundo no pacote servlets da seguinte forma:
1
2
3
4
5
6
7
8
9
10

@WebServlet("/OlaMundo")
public class OlaMundo extends HttpServlet{
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.println("<html><body><h1>Ol Mundo</h1></body></html>");
}
}

www.k19.com.br

52

Web Container
13. Verifique o funcionamento da Servlet acessando atravs de um navegador a url:
http://localhost:8080/K19-App/OlaMundo

4.10

JSP

Outra maneira de criar uma Servlet escrever um JSP. Lembrando que os JSPs so traduzidos para Servlets automaticamente pelos Web Containers.
Para criar um JSP basta adicionar um arquivo .jsp.
1
2
3
4
5
6
7
8
9

<!-- olaMundo.jsp -->


<html>
<body>
<!-- scriptlet -->
<% java.util.Random geradorDeNumeros = new java.util.Random(); %>
<!-- expression -->
<%= geradorDeNumeros.nextInt(100) %>
</body>
</html>

Um arquivo JSP pode conter texto HTML e cdigo Java. O cdigo Java pode aparecer em
diversos lugares. Por exemplo, dentro de scriptlets ou expressions.

4.11

Exerccios

14. Crie um arquivo JSP chamado olaMundo.jsp na pasta WebContent com o seguinte
contedo.
1
2
3
4
5
6
7
8
9

<!-- olaMundo.jsp -->


<html>
<body>
<!-- scriptlet -->
<% java.util.Random geradorDeNumeros = new java.util.Random(); %>
<!-- expression -->
<%= geradorDeNumeros.nextInt(100) %>
</body>
</html>

15. Verifique o funcionamento do JSP acessando atravs de um navegador a url:


http://localhost:8080/K19-App/olaMundo.jsp

4.12

Frameworks

Hoje em dia, improvvel que uma empresa decida comear um projeto utilizando diretamente Servlets e JSPs pois a produtividade pequena e a manuteno difcil. Por isso
bibliotecas que definem um modelo de programao baseado no padro MVC so utilizadas
nos projetos. Essas bibliotecas so os chamados Frameworks web. Eis uma lista dos principais Frameworks web para aplicaes web Java:
53

K19 Treinamentos

Web Container
JSF
Struts 1.x
Struts 2.x
Spring MVC
Nos prximos captulos mostraremos o funcionamento e explicaremos os conceitos relacionados ao framework JSF.

www.k19.com.br

54

Captulo 5
Viso Geral do JSF 2
O JSF 2 oferece muitos recursos para o desenvolvimento de uma aplicao web Java. Cada
um desses recursos por si s j so suficientemente grandes e podem ser abordados em separado.
Porm, no primeiro contato com JSF 2, interessante ter uma viso geral dos recursos
principais e do relacionamento entre eles sem se aprofundar em muito nos detalhes individuais
de cada recurso.
Portanto, neste captulo, mostraremos de forma sucinta e direta o funcionamento e os conceitos principais do JSF 2. Nos prximos captulos, discutiremos de maneira mais detalhada as
diversas partes do JSF 2.

5.1

Aplicao de exemplo

Inspirados na sorte de um dos nossos alunos que ganhou na Loto Mania utilizando um
programa que ele fez baseado em algumas dicas que o instrutor Rafael Cosentino deu a ele
para gerar nmeros aleatrios em Java, vamos montar uma pequena aplicao em JSF 2 que
gera apostas de loteria.

5.2

Managed Beans

Os Managed Beans so objetos utilizados nas aplicaes JSF e possuem trs responsabilidades principais:
1. Receber os dados enviados pelos usurios atravs das telas da aplicao.
2. Executar as lgicas para tratar as requisies dos usurios.
3. Disponibilizar os dados que devem ser apresentados nas telas da aplicao.
Para definir o funcionamento de um Managed Bean no JSF 2, devemos seguir os seguintes
passos:
1. Criar uma classe com a anotao @ManagedBean.
55

Viso Geral do JSF 2


2. Definir atributos com os correspondentes getters e setters para poder receber dados das
telas ou enviar dados para as telas.
3. Definir mtodos para implementar as lgicas de tratamento das possveis requisies dos
usurios.

5.2.1

GeradorDeApostasBean

Na aplicao que gera apostas de loteria, devemos criar um Managed Bean para receber
alguns parmetros que devem ser definidos pelos usurios para gerar as apostas corretamente.
1
2
3
4
5
6
7
8
9
10

@ManagedBean
public class GeradorDeApostasBean {
private int quantidadeDeNumeros;
private int tamanhoDaAposta;
private int quantidadeDeApostas;
// getters e setters
}

Devemos acrescentar no G ERADOR D E A POSTAS B EAN um mtodo para implementar a lgica de gerar as apostas. Este mtodo deve devolver no final o nome da tela que apresentar
as apostas geradas para os usurios.
1
2
3
4

public String geraApostas() {


// Aqui deve ser implementa a lgica para gerar as apostas
return "lista-de-apostas";
}

Por fim, devemos adicionar um atributo no G ERADOR D E A POSTAS B EAN para disponibilizar as apostas geradas para a tela que ir apresent-las aos usurios.
1
2
3

private List<List<Integer>> apostas;


// getters e setters

5.3

Facelets e Componentes Visuais

As telas das aplicaes JSF 2 podem ser definidas atravs de arquivos xhtml. Esses arquivos
so processados pela engine do Facelets que faz parte do JSF 2. Os componentes visuais que
formam as telas da aplicao so inseridos atravs de tags xhtml.

5.3.1

Tela de entrada

Na nossa aplicao de gerar apostas, devemos definir uma tela para os usurios passarem
os parmetros necessrios para que as apostas sejam geradas.
www.k19.com.br

56

Viso Geral do JSF 2

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Gerador de Apostas</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid>
<h:outputLabel value="Quantidade total de nmeros:"/>
<h:inputText value="#{geradorDeApostasBean.quantidadeDeNumeros}"/>
<h:outputLabel value="Quantidade de nmeros por aposta:"/>
<h:inputText value="#{geradorDeApostasBean.tamanhoDaAposta}"/>
<h:outputLabel value="Quantidade de apostas:"/>
<h:inputText value="#{geradorDeApostasBean.quantidadeDeApostas}"/>
<h:commandButton action="#{geradorDeApostasBean.geraApostas}"
value="Gerar"/>
</h:panelGrid>
</h:form>
</h:body>
</html>

5.3.2

Tela de Sada

Na tela de sada, devemos apresentar aos usurios uma listagem das apostas que foram
criadas pelo G ERADOR D E A POSTAS B EAN.
57

K19 Treinamentos

Viso Geral do JSF 2

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Gerador de Apostas</title>
</h:head>
<h:body>
<ui:repeat var="aposta" value="#{geradorDeApostasBean.apostas}"
varStatus="status">
<h:outputText value="Aposta #{status.index + 1}: "/>
<h:outputText value="#{aposta}"/>
<br/>
</ui:repeat>
</h:body>
</html>

5.4

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado K19-Loteria. Siga as imagens
abaixo para configurar corretamente o projeto.
www.k19.com.br

58

Viso Geral do JSF 2

59

K19 Treinamentos

Viso Geral do JSF 2

www.k19.com.br

60

Viso Geral do JSF 2


2. Na pasta src do projeto K19-Loteria crie um pacote chamado managedbeans.

3. No pacote managedbeans crie uma classe chamada GeradorDeApostasBean com o


seguinte contedo.

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

@ManagedBean
public class GeradorDeApostasBean {
private int quantidadeDeNumeros;
private int tamanhoDaAposta;
private int quantidadeDeApostas;
private List<List<Integer>> apostas;
public String geraApostas() {
// Prepara uma lista com todos os nmeros
ArrayList<Integer> numeros = new ArrayList<Integer>();
for (int j = 1; j <= this.quantidadeDeNumeros; j++) {
numeros.add(j);
}
// Cria uma sublista da lista de nmeros
List<Integer> subList = numeros.subList(0, this.tamanhoDaAposta);
// Lista de apostas vazia
this.apostas = new ArrayList<List<Integer>>();
// Gera as apostas
for (int i = 0; i < this.quantidadeDeApostas; i++) {
Collections.shuffle(numeros);
List<Integer> aposta = new ArrayList<Integer>(subList);
this.apostas.add(aposta);
}
return "lista-de-apostas";
}
// GETTERS AND SETTERS
}

4. Na pasta WebContent, crie um arquivo chamado formulario.xhtml e monte a tela de


entrada do gerador de apostas.
61

K19 Treinamentos

Viso Geral do JSF 2


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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Gerador de Apostas</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid>
<h:outputLabel value="Quantidade total de nmeros:"/>
<h:inputText value="#{geradorDeApostasBean.quantidadeDeNumeros}"/>
<h:outputLabel value="Quantidade de nmeros por aposta:"/>
<h:inputText value="#{geradorDeApostasBean.tamanhoDaAposta}"/>
<h:outputLabel value="Quantidade de apostas:"/>
<h:inputText value="#{geradorDeApostasBean.quantidadeDeApostas}"/>
<h:commandButton action="#{geradorDeApostasBean.geraApostas}"
value="Gerar"/>
</h:panelGrid>
</h:form>
</h:body>
</html>

5. Na pasta WebContent, crie um arquivo chamado lista-de-apostas.xhtml para apresentar


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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>Gerador de Apostas</title>
</h:head>
<h:body>
<ui:repeat var="aposta" value="#{geradorDeApostasBean.apostas}"
varStatus="status">
<h:outputText value="Aposta #{status.index + 1}: "/>
<h:outputText value="#{aposta}"/>
<br/>
</ui:repeat>
</h:body>
</html>

6. Preencha o formulrio e clique no boto de gerar apostas para verifique o funcionamento


da nossa aplicao. Acesse a url:
http://localhost:8080/K19-Loteria/formulario.xhtml

www.k19.com.br

62

Captulo 6
Componentes Visuais
A arquitetura de componentes visuais do JSF permite que novos componentes alm dos que
esto definidos na especificao sejam desenvolvidos por terceiros. Isso permitiu que bibliotecas de componentes extremamente ricos visualmente fossem desenvolvidas. Inclusive, em
geral, essas bibliotecas utilizam recursos como o AJAX para melhorar a interatividade com o
usurio. A mais famosa dessas bibliotecas a RichFaces cujo site oficial pode ser visitado
atravs da url:
(http://www.jboss.org/richfaces).
Porm, no devemos deixar nossos olhos nos enganarem. Os componentes visuais do JSF
vo alm da questo visual. Esses componentes podem ser reaproveitados em diversos pontos
da mesma aplicao ou em aplicaes diferentes mostrando de forma concreta o poder da
Orientao a Objetos e o desenvolvimento Orientado a Componentes.
Alm disso, a arquitetura do JSF permite que outros tipos de componentes sejam conectados aos componentes visuais. Por exemplo, podemos conectar componentes validadores aos
componentes visuais para que os dados vindos dos usurios sejam verificados de acordo com
alguma regra.
Neste captulo apresentaremos os principais componentes visuais definidos pela especificao do JSF.

6.1

Formulrios

Os formulrios so necessrios em todas as telas que precisam receber dados dos usurios.
O componente visual h:form cria formulrios.
63

Componentes Visuais

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

<h:form>
<h:outputLabel value="Nome: " for="input-nome"/>
<h:inputText id="input-nome"/>
<br/>
<h:outputLabel value="Sobre: " for="input-sobre"/>
<h:inputTextarea id="input-sobre"/>
<br/>
<h:outputLabel value="Sexo: "/>
<h:selectOneRadio>
<f:selectItem itemLabel="Masculino" itemValue="M"/>
<f:selectItem itemLabel="Feminino" itemValue="F"/>
</h:selectOneRadio>
<h:outputLabel value="Pas: "/>
<h:selectOneMenu>
<f:selectItem itemLabel="Argertina" itemValue="ar"/>
<f:selectItem itemLabel="Brasil" itemValue="br"/>
<f:selectItem itemLabel="Espanha" itemValue="es"/>
</h:selectOneMenu>
<br/>
<h:outputLabel value="Escolha uma senha: " for="input-senha"/>
<h:inputSecret id="input-senha"/>
<br/>
<h:outputLabel value="Li e estou de acordo com os termos de uso."
for="checkbox-termo"/>
<h:selectBooleanCheckbox id="checkbox-termo" value="aceito"/>
<br/>
<h:commandButton value="Cadastrar"/>
</h:form>

Na linha 2, utilizamos o componente visual h:outputLabel para criar um rtulo para o


campo no qual deve ser digitado o nome da pessoa que se cadastra. Observe que o atributo for
conecta o rtulo ao id do campo do nome. Dessa forma, se o usurio clicar no rtulo o cursor
de digitao aparecer nesse campo.
Na linha 3, utilizamos o componente visual h:inputText para criar o campo do nome.
Definimos o atributo id para que o campo pudesse ser conectado ao rtulo loga acima.
www.k19.com.br

64

Componentes Visuais
Na linha 9, para criar um campo para texto maiores, utilizamos o componente h:inputTextarea.
O funcionamento dele muito semelhante ao do h:inputText. A diferena bsica que a rea
de digitao do h:inputTextarea maior.
Na linha 13, aplicamos o componente h:selecOneRadio para criar um radio button que
permite o usurio escolher o sexo (masculino e feminino). As opes do radio button so
definidas pelo componente f:selectItem utilizado nas linhas 14 e 15.
Na linha 19, criamos um combo box para que o usurio escolha qual o pas de origem da
pessoa que ser cadastrada. Assim como no radio button, as opes do combo box so definidas
com o componente f:selectItem.
Na linha 28, utilizamos o componente h:inputSecret para criar um campo de texto que no
mostra na tela o valor que j foi digitado. Esse componente til para senhas.
Na linha 34, inserimos na tela um check box para saber se o usurio aceita ou no os termos
de cadastro. O componente utilizado para isso foi o h:selectBooleanCheckbox.
Por fim, na linha 38, acrescentamos um boto para o usurio confirmar o cadastro.

6.2

Panel Grid

O componente h:panelGrid utilizado para organizar outros componentes em tabelas de


uma forma prtica. Basicamente, para utilizar este componente, devemos definir quantas colunas queremos e ele automaticamente distribui os componentes em um nmero suficiente de
linhas.

65

K19 Treinamentos

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

<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="Nome: " for="input-nome"/>
<h:inputText id="input-nome"/>
<h:outputLabel value="Sobre: " for="input-sobre"/>
<h:inputTextarea id="input-sobre"/>
<h:outputLabel value="Sexo: "/>
<h:selectOneRadio>
<f:selectItem itemLabel="Masculino" itemValue="M"/>
<f:selectItem itemLabel="Feminino" itemValue="F"/>
</h:selectOneRadio>
<h:outputLabel value="Pas: "/>
<h:selectOneMenu>
<f:selectItem itemLabel="Argertina" itemValue="ar"/>
<f:selectItem itemLabel="Brasil" itemValue="br"/>
<f:selectItem itemLabel="Espanha" itemValue="es"/>
</h:selectOneMenu>
<h:outputLabel value="Escolha uma senha: " for="input-senha"/>
<h:inputSecret id="input-senha"/>
<h:outputLabel value="Li e estou de acordo com os termos de uso."
for="checkbox-termo"/>
<h:selectBooleanCheckbox id="checkbox-termo" value="aceito"/>
<h:commandButton value="Cadastrar"/>
</h:panelGrid>
</h:form>

6.3

Panel Group

Em certas situaes no conseguimos colocar dois ou mais componentes em um determinado local. Por exemplo, em uma clula de um panel Grid. Nesses casos, devemos aplicar o
componente h:panelGroup. A ideia inserir dois ou mais componentes em um panel Group e
depois inserir o panel Group no lugar que s aceita um componente.

www.k19.com.br

66

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

<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="Nome: " for="input-nome"/>
<h:inputText id="input-nome"/>
<h:outputLabel value="Sobre: " for="input-sobre"/>
<h:inputTextarea id="input-sobre"/>
<h:outputLabel value="Sexo: "/>
<h:selectOneRadio>
<f:selectItem itemLabel="Masculino" itemValue="M"/>
<f:selectItem itemLabel="Feminino" itemValue="F"/>
</h:selectOneRadio>
<h:outputLabel value="Pas: "/>
<h:selectOneMenu>
<f:selectItem itemLabel="Argertina" itemValue="ar"/>
<f:selectItem itemLabel="Brasil" itemValue="br"/>
<f:selectItem itemLabel="Espanha" itemValue="es"/>
</h:selectOneMenu>
<h:outputLabel value="Escolha uma senha: " for="input-senha"/>
<h:inputSecret id="input-senha"/>
<h:panelGroup>
<h:outputLabel value="Li e estou de acordo com os termos de uso."
for="checkbox-termo"/>
<h:selectBooleanCheckbox id="checkbox-termo" value="aceito"/>
</h:panelGroup>
<h:commandButton value="Cadastrar"/>
</h:panelGrid>
</h:form>

6.4

Tabelas

Podemos criar tabelas utilizando o componente h:dataTable com dados de alguma coleo. Basicamente, a diferena dos Data Tables e dos Panel Grids que os Data Tables iteram
diretamente nos tames de colees.

1
2
3
4
5
6
7
8

<h:dataTable value="#{geradorDeApostasBean.apostas}" var="aposta" border="1">


<h:column>
<f:facet name="header">
<h:outputText value="Apostas"></h:outputText>
</f:facet>
<h:outputText value="#{aposta}"></h:outputText>
</h:column>
</h:dataTable

Na linha 2, o componente h:column utilizado para adicionar uma coluna na tabela defi67

K19 Treinamentos

Componentes Visuais
nida com o h:dataTable.
Na linha 3, aplicamos o componente f:facet para adicionar um cabealho na coluna correspondente.

6.5

Namespaces

Para poder aplicar as tags que definem as telas das aplicaes JSF, precisamos adicionar os
namespaces correspondentes s bibliotecas de tags que desejamos utilizar.
1
2
3
4
5
6
7
8

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<!-- Contedo Aqui -->
</html>

Os dois principais namespaces so: http://java.sun.com/jsf/html e http://java.sun.com/jsf/core.


O primeiro o namespace da biblioteca de tags do JSF que geram contedo HTML especificamente. O segundo corresponde a biblioteca de tags do JSF que no est atrelada a um tipo de
visualizao, ou seja, so tags mais genricas.
Outro namespace importante o http://java.sun.com/jsf/facelets que contm tags que nos
ajudam a reaproveitar o cdigo das telas. Veremos em outro captulo o funcionamento das tags
desse namespace.

6.6

Esqueleto HTML

Um documento HTML possui um esqueleto constitudo por algumas tags principais. Para
refletir essa estrutura devemos inserir algumas tags nos documentos XHTML que definem as
telas JSF.
1
2
3
4
5
6
7
8
9
10

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
</h:head>
<h:body>
</h:body>
</html>

6.7

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado ComponentesVisuais seguindo


os passos vistos no exerccio do captulo 5.
www.k19.com.br

68

Componentes Visuais
2. Adicione um arquivo na pasta WebContent do projeto ComponentesVisuais para criar
uma tela utilizando os principais componentes de formulrios. Este arquivo deve se
chamar formulario.xhtml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Cadastro de Usurio</title>
</h:head>
<h:body>
<h:form>
<h:outputLabel value="Nome: " for="input-nome"/>
<h:inputText id="input-nome"/>
<h:outputLabel value="Sobre: " for="input-sobre"/>
<h:inputTextarea id="input-sobre"/>
<h:outputLabel value="Sexo: "/>
<h:selectOneRadio>
<f:selectItem itemLabel="Masculino" itemValue="M"/>
<f:selectItem itemLabel="Feminino" itemValue="F"/>
</h:selectOneRadio>
<h:outputLabel value="Pas: "/>
<h:selectOneMenu>
<f:selectItem itemLabel="Argertina" itemValue="ar"/>
<f:selectItem itemLabel="Brasil" itemValue="br"/>
<f:selectItem itemLabel="Espanha" itemValue="es"/>
</h:selectOneMenu>
<h:outputLabel value="Escolha uma senha: " for="input-senha"/>
<h:inputSecret id="input-senha"/>
<h:outputLabel value="Li e concordo." for="checkbox-termo"/>
<h:selectBooleanCheckbox id="checkbox-termo" value="aceito"/>
<h:commandButton value="Cadastrar"/>
</h:form>
</h:body>
</html>

Acesse a url adequada para visualizar o formulrio.


3. Utilize o componente h:panelGrid para alinhar melhor os itens do formulrio criado no
exerccio anterior.
1
2
3
4
5
6
7

<h:form>
<h:panelGrid columns="2">
<!-- CONTEDO DO FORMULRIO -->
</h:panelGrid>
</h:form>

Verifique o resultado atravs de um navegador.


69

K19 Treinamentos

Componentes Visuais
4. Utilize o componente h:panelGroup para agrupar dois ou mais componentes em uma
clula do Panel Grid criado no exerccio anterior.
5. Na pasta src crie um pacote chamado managedbeans. Nesse pacote, adicione uma classe
com o seguinte contedo para modelar um simples Managed Bean que gera palavras.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

@ManagedBean
public class PalavrasBean {
private List<String> palavras = new ArrayList<String>();
public PalavraBean() {
this.palavras.add("K19 Treinamentos");
this.palavras.add("Rafael Cosentino");
this.palavras.add("Alexandre Macedo");
this.palavras.add("Jonas Hirata");
}

public List<String> getPalavras() {


return this.palavras;
}
public void setPalavras(List<String> palavras) {
this.palavras = palavras;
}
}

6. Crie uma tela aplicando o componente h:dataTable para apresentar as palavras geradas
pelo Managed Bean do exerccio anterior.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Palavras apenas palavras</title>
</h:head>
<h:body>
<h:dataTable value="#{palavrasBean.palavras}" var="palavra" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="Palavras"></h:outputText>
</f:facet>
<h:outputText value="#{palavra}"></h:outputText>
</h:column>
</h:dataTable
</h:body>
</html>

Veja a tabela acessando a url correspondente.

www.k19.com.br

70

Captulo 7
Facelets
Certamente, voc j ouviu algum falar da importncia da reutilizao no desenvolvimento
de software. Nesse contexto, os objetivos do reaproveitamento de software so: diminuir o
tempo e o custo para desenvolver e facilitar a manuteno tambm diminuindo gastos e tempo.
Levando a ideia do reaproveitamento adiante, algumas pessoas desenvolveram um projeto
chamado Facelets que tem como principal objetivo facilitar todo o processo de desenvolvimento e manuteno das telas de uma aplicao JSF. O Facelets j faz parte do JSF 2 sendo a
engine padro dessa tecnologia para a definio das telas das aplicaes web.

7.1

Templating

A reutilizao do cdigo das telas realizada principalmente pelo uso de templates. A ideia
identificar um padro em um determinado conjunto de telas de uma aplicao JSF e defini-lo
atravs de um esqueleto (template) que possua trechos dinmicos que possam ser preenchidos
posteriormente.
A criao de um template simples, basta criar um arquivo xhtml adicionando todos os
componentes visuais que so fixos e devem aparecer em um determinado conjunto de telas.
Para os trechos dinmicos, devemos aplicar o componente ui:insert criando um espao que
pode ser preenchido depois.
71

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>K19 Treinamentos</title>
</h:head>
<h:body>
<div id="header">
<img src="k19-logo.png" />
<hr />
</div>
<ui:insert name="conteudo"> Espao para o contedo da tela </ui:insert>
<div id="footer" style="text-align: center">
<hr />
&copy; 2010 K19. Todos os direitos reservados.
</div>
</h:body>
</html>

Na linha 16, o atributo name do componente ui:insert utilizado para identificar o espao
que ser preenchido depois.
Aps escrever o template, devemos criar as telas que o utilizaro. Essas telas so definidas
tambm atravs de arquivos xhtml. Para indicar que desejamos utilizar um template, devemos aplicar o componente ui:composition. Para preencher um espao deixado no template,
devemos inserir o componente ui:define no cdigo.
1
2
3
4
5
6
7
8
9
10

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h:outputText value="Contedo da pgina que utiliza o template.xhtml"/>
</ui:define>
<ui:composition>
</html>

7.2

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado Facelets seguindo os passos
vistos no exerccio do captulo 5.

2. Crie um template na pasta WebContent chamado template.xhtml. Copie o arquivo


k19-logo.png da pasta K19-Arquivos/imagens que est na rea de Trabalho para pasta
WebContent do projeto Facelets.
www.k19.com.br

72

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
<title>K19 Treinamentos</title>
</h:head>
<h:body>
<div id="header">
<img src="k19-logo.png" />
<hr />
</div>
<ui:insert name="conteudo"> Espao para o contedo da tela </ui:insert>
<div id="footer" style="text-align: center">
<hr />
&copy; 2010 K19. Todos os direitos reservados.
</div>
</h:body>
</html>

3. Monte uma tela que usa o template criado no exerccio anterior. O nome do arquivo deve
ser teste-template.xhtml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h:form>
<h:outputLabel value="Nome: " for="campo-nome"/>
<h:inputText id="campo-nome"/>
<h:commandButton value="Enviar"/>
</h:form>
</ui:define>
</ui:composition>
</html>

Verifique o resultado acessando a url:


http://localhost:8080/Facelets/teste-template.xhtml

7.3

Particionando as telas

Com o intuito de organizar melhor o cdigo das telas ou definir pedaos de telas que
possam ser reaproveitados, podemos dividir o contedo de uma tela ou de um template em
vrios arquivos atravs do componente ui:include.
O recurso de separar uma tela ou um template em vrios arquivos se torna mais interessante
e til quando temos a possibilidade de passar dados do arquivo principal para os secundrios.
Essa passagem de dados realizada atravs do componente ui:param.
73

K19 Treinamentos

Facelets
Por exemplo, estamos desenvolvendo uma aplicao e desejamos colocar o nome do usurio
e um link para fazer logoff no canto superior direito sempre que algum estiver logado ou um
link para a pgina de login caso contrrio.
Veja o fragmento que teramos que acrescentar nos arquivos principais:
1
2
3
4
5
6
7
8
9
10
11

<div id="header">
<c:if test="#{usuarioBean.logado}">
<ui:include src="usuario-logado.xhtml">
<ui:param name="usuario" value="#{usuarioBean.usuario}"/>
</ui:include>
</c:if>
<c:if test="#{!usuarioBean.logado}">
<ui:include src="usuario-nao-logado.xhtml"/>
</c:if>
</div>

Veja os fragmentos que teramos que acrescentar nos arquivos secundrios:


1
2

<h:outputText value="Ol #{usuario.nome}"/>


<h:commandButton action="usuarioBean.logout" value="Log out"/>

1
2
3
4
5

<h:outputLabel value="Usurio: " for="campo-usuario"/>


<h:inputText id="campo-usuario"/>
<h:outputLabel value="Senha: " for="campo-senha"/>
<h:inputSecret id="campo-senha"/>
<h:commandButton action="usuarioBean.login" value="Log in"/>

7.4

Exerccios

4. Vamos implementar uma listagem de instrutores no nosso projeto Facelets. O primeiro


passo criar uma classe para modelar os instrutores. Crie um pacote chamado model no
projeto Facelets e adicione nele uma classe chamada Instrutor com seguinte cdigo:

1
2
3
4
5
6

public class Instrutor {


private String nome;
private String dataDeNascimento;
// GETTERS AND SETTERS
}

5. Faa um Managed Bean que fornea uma lista de instrutores para uma tela de listagem
de instrutores. Crie um pacote chamado managedbeans no projeto Facelets e adicione
nele uma classe chamada InstrutorBean com seguinte cdigo:
www.k19.com.br

74

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

@ManagedBean
public class InstrutorBean {
private List<Instrutor> instrutores = new ArrayList<Instrutor>();
public InstrutorBean() {
Instrutor rafael = new Instrutor();
rafael.setNome("Rafael Cosentino");
rafael.setDataDeNascimento("30/10/1984");
Instrutor marcelo = new Instrutor();
marcelo.setNome("Marcelo Martins");
marcelo.setDataDeNascimento("02/04/1985");
this.instrutores.add(rafael);
this.instrutores.add(marcelo);
}
public List<Instrutor> getInstrutores() {
return instrutores;
}
public void setInstrutores(List<Instrutor> instrutores) {
this.instrutores = instrutores;
}
}

6. Crie uma tela parcial para mostrar os dados de apenas um instrutor dentro de um item
de uma lista HTML. O arquivo deve ser adicionado na pasta WebContent do projeto
Facelets e se chamar instrutor-info.xhtml.

1
2
3
4
5
6
7
8
9
10

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<li>
<h:outputText value="Nome: #{instrutor.nome}"/>
<br/>
<h:outputText value="Data Nascimento: #{instrutor.dataDeNascimento}"/>
</li>
</html>

7. Faa a tela principal da listagem de instrutores. Crie um arquivo na pasta WebContent


do projeto Facelets e como o nome listagem-de-instrutores.xhtml e com o seguinte
cdigo.
75

K19 Treinamentos

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

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<ul>
<ui:repeat var="instrutor" value="#{instrutorBean.instrutores}">
<ui:include src="instrutor-info.xhtml">
<ui:param name="instrutor" value="#{instrutor}"/>
</ui:include>
</ui:repeat>
</ul>
</ui:define>
</ui:composition>
</html>

Veja o resultado acessando a url:


http://localhost:8080/Facelets/listagem-de-instrutores.xhtml

www.k19.com.br

76

Captulo 8
Navegao
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.

8.1

Navegao Esttica Implcita

Na navegao esttica implcita, quando o usurio clica em algum boto ou link, um sinal (outcome) fixo definido no prprio boto ou link enviado para o JSF. Este sinal uma
string que ser utilizada pelo tratador de navegao do JSF para definir a prxima tela que ser
apresentada ao usurio.
Nas navegaes implcitas, os nomes dos arquivos que definem as telas de resposta so
montados com as strings dos outcomes. Por exemplo, se o usurio clica em um boto ou link
de uma tela definida por um arquivo chamado pagina1.xhtml que envia o outcome pagina2
ento ele ser redirecionado para a tela definida pelo arquivo pagina2.xhtml dentro do mesmo
diretrio que est o arquivo pagina1.xhtml.
Veja como seria o cdigo da pagina1.xhtml e pagina2.xhtml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Pgina 1</title>
</h:head>
<h:body>
<h1>K19 Pgina 1</h1>
<h:form>
<h:commandButton value="Pgina 2" action="pagina2"/>
</h:form>
</h:body>
</html>

77

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Pgina 2</title>
</h:head>
<h:body>
<h1>K19 Pgina 2</h1>
<h:form>
<h:commandLink action="pagina1">
<h:outputText value="Pgina 1"/>
</h:commandLink>
</h:form>
</h:body>
</html>

8.2

Navegao Esttica Explcita

Na navegao implcita, os outcomes so os nomes dos arquivos que definem as telas. Para
ter a liberdade de definir os nomes dos arquivos independentemente dos outcomes, podemos
utilizar a navegao explcita. Porm, nesse tipo de navegao, devemos acrescentar algumas
linhas no arquivo de configuraes do JSF, o faces-config.xml.
1
2
3
4
5
6
7
8

<navigation-rule>
<from-view-id>pagina1.xhtml</from-view-id>
<navigation-case>
<from-outcome>proxima</from-outcome>
<to-view-id>pagina2.xhtml</to-view-id>
</navigation-case>
</navigation-rule>

O cdigo acima define que quando a tela do arquivo pagina1.xhtml emitir o sinal(outcome)
proxima a transio deve ser realizada para a tela do arquivo pagina2.xhtml. Na tela do
arquivo pagina1.xhtml, basta acrescentar um boto ou link que emita o sinal next.
1

<h:commandButton value="Prxima tela" action="proxima"/>

8.3

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado Navegacao seguindo os passos
vistos no exerccio do captulo 5.
2. Na pasta WebContent do projeto Navegacao, crie um arquivo chamado pagina1.xhtml
com o seguinte cdigo:
www.k19.com.br

78

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Pgina 1</title>
</h:head>
<h:body>
<h1>K19 Pgina 1</h1>
<h:form>
<h:commandButton value="Pgina 2" action="pagina2"/>
</h:form>
</h:body>
</html>

3. Novamente, na pasta WebContent do projeto Navegacao, crie um arquivo chamado


pagina2.xhtml com o seguinte cdigo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Pgina 2</title>
</h:head>
<h:body>
<h1>K19 Pgina 2</h1>
<h:form>
<h:commandLink action="pagina1">
<h:outputText value="Pgina 1"/>
</h:commandLink>
</h:form>
</h:body>
</html>

4. Navegue atravs dos links e botes da url:


http://localhost:8080/Navegacao/pagina1.xhtml
5. Configure uma navegao explcita no arquivo faces-config.xml.
1
2
3
4
5
6
7
8

<navigation-rule>
<from-view-id>pagina1.xhtml</from-view-id>
<navigation-case>
<from-outcome>proxima</from-outcome>
<to-view-id>pagina2.xhtml</to-view-id>
</navigation-case>
</navigation-rule>

6. Adicione um boto na tela do arquivo pagina1.xhtml que emita o sinal proxima


abaixo do outro boto.
79

K19 Treinamentos

Navegao
1

<h:commandButton value="Prxima tela" action="proxima"/>

7. Navegue atravs dos links e botes da url:


http://localhost:8080/Navegacao/pagina1.xhtml

8.4

Navegao Dinmica Implcita

Na maioria dos casos, no queremos fixar nas telas os outcomes que elas podem enviar para
o JSF. Normalmente, a escolha dos outcomes so realizadas dentro dos Managed Beans.
Na navegao dinmica, quando um usurio clica em um boto ou link, um Managed Bean
chamado para escolher um outcome e enviar para o JSF. Para isso, associamos os botes ou
os links a mtodos dos Managed Beans.
O arquivo cara-ou-coroa.xhtml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Cara ou Coroa</title>
</h:head>
<h:body>
<h1>K19 Cara ou Coroa</h1>
<h:form>
<h:commandButton value="Lanar Moeda" action="#{managedBean.proxima}"/>
</h:form>
</h:body>
</html>

Nos Managed Beans, temos que definir a lgica de escolha dos outcomes.
1
2
3
4
5
6
7
8
9
10
11

@javax.faces.bean.ManagedBean
public class ManagedBean {
public String proxima(){
if(Math.random() < 0.5){
return "cara";
} else {
return "coroa";
}
}
}

Os Managed Beans devem devolver uma string com o outcome escolhido. Se o outcome
devolvido pelo Managed Bean no estiver configurado no faces-config.xml o tratador de navegao do JSF assumir a navegao implcita, ou seja, o valor devolvido o nome do arquivo
que ser processado para gerar a tela de resposta.
O arquivo cara.xhtml:
www.k19.com.br

80

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Cara ou Coroa</title>
</h:head>
<h:body>
<h1>Deu Cara!</h1>
<h:form>
<h:commandButton value="voltar" action="cara-ou-coroa"/>
</h:form>
</h:body>
</html>

O arquivo coroa.xhtml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Cara ou Coroa</title>
</h:head>
<h:body>
<h1>Deu Coroa!</h1>
<h:form>
<h:commandButton value="voltar" action="cara-ou-coroa"/>
</h:form>
</h:body>
</html>

8.5

Navegao Dinmica Explcita

Para implementar a navegao dinmica explcita, basta seguir os passos da navegao


dinmica implcita e acrescentar as regras de navegao no arquivo de configuraes do JSF.

8.6

Exerccios

8. Implemente um Managed Bean de forma aleatria escolha entre dois outcomes. Crie um
pacote chamado managedbeans no projeto Navegacao e adicione uma classe chamada
ManagedBean
81

K19 Treinamentos

Navegao
1
2
3
4
5
6
7
8
9
10
11

@javax.faces.bean.ManagedBean
public class ManagedBean {
public String proxima(){
if(Math.random() < 0.5){
return "cara";
} else {
return "coroa";
}
}
}

9. Crie uma tela principal com um boto que chama o Managed Bean do exerccio anterior
para escolher o outcome que deve ser emitido para o JSF. Para isso, faa um arquivo
chamado cara-ou-coroa.xhtml na pasta WebContent do projeto Navegacao.

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Cara ou Coroa</title>
</h:head>
<h:body>
<h1>K19 Cara ou Coroa</h1>
<h:form>
<h:commandButton value="Lanar Moeda" action="#{managedBean.proxima}"/>
</h:form>
</h:body>
</html>

10. Crie os arquivos de sada.


O arquivo cara.xhtml:

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Cara ou Coroa</title>
</h:head>
<h:body>
<h1>Deu Cara!</h1>
<h:form>
<h:commandButton value="voltar" action="cara-ou-coroa"/>
</h:form>
</h:body>
</html>

O arquivo coroa.xhtml:
www.k19.com.br

82

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>K19 Cara ou Coroa</title>
</h:head>
<h:body>
<h1>Deu Coroa!</h1>
<h:form>
<h:commandButton value="voltar" action="cara-ou-coroa"/>
</h:form>
</h:body>
</html>

11. Navegue atravs dos links e botes da url:


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

83

K19 Treinamentos

Navegao

www.k19.com.br

84

Captulo 9
Managed Beans
Atravs das telas de uma aplicao, os usurios podem basicamente: enviar dados para o
sistema; visualizar informaes da aplicao; e disparar aes ou eventos. S que as telas no
realizam todas essas tarefas sozinhas. Nas aplicaes web JSF, h objetos que oferecem todo o
suporte que as telas necessitam. Esses objetos so chamados de Managed Beans.
As responsabilidades principais dos Managed Beans so:
1. Fornecer dados que sero apresentados aos usurios nas telas
2. Receber os dados enviados pelos usurios atravs das telas
3. Processar o tratamentos das aes e eventos disparados pelos usurios.

9.1

Criando Managed Beans

Para criar um Managed Bean, devemos escrever uma classe Java simples sem nenhum vnculo direto com classes ou interfaces do JSF. Dizemos, que as classes que implementam os
Managed Beans so POJOs (Plain Old Java Object). A simplicidade a maior vantagem de
utilizar POJOs.
As classes dos Managed Beans precisam ser registradas no JSF. Na verso 2 do JSF, o
registro feito atravs da anotao @ManagedBean.
1
2
3
4
5
6

package managedbeans;
@ManagedBean
class MeuManagedBean {
}

Antes do JSF 2, o registro dos Managed Beans era realizado somente atravs do arquivo de
configuraes do JSF, o faces-config.xml.
1
2
3
4
5

<managed-bean>
<managed-bean-name>meuManagedBean</managed-bean-name>
<managed-bean-class>managedbeans.MeuManagedBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

85

Managed Beans
As duas possibilidades, anotao ou xml, esto disponveis no JSF 2.

9.2

Disponibilizando dados para as telas

Basta criar mtodos getters nas classes dos Managed Beans para disponibilizar dados para
as telas.
1
2
3
4
5
6
7
8
9
10

package managedbeans;
@ManagedBean
class MeuManagedBean {
private String informacao;
public String getInformacao() {
return this.informacao;
}
}

9.3

Recebendo dados das telas

Basta criar mtodos setters nas classes dos Managed Beans para receber dados das telas.
1
2
3
4
5
6
7
8
9
10

package managedbeans;
@ManagedBean
class MeuManagedBean {
private String informacao;
public void setInformacao(Strign informacao) {
this.informacao = informacao;
}
}

9.4

Definindo o tratamento das 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.
1
2
3
4
5
6

@ManagedBean
class MeuManagedBean {
public void logica() {
// implemetao
}
}

Esses mtodos podem ser VOID quando desejamos manter os usurios na mesma tela ou
devolver S TRING quando desejamos realizar uma navegao entre telas.
www.k19.com.br

86

Managed Beans

9.5

Expression Language

De alguma forma as telas precisam referenciar os Managed Beans com os quais elas desejam interagir. H uma linguagem no JSF que podemos utilizar no cdigo das telas que
apropriada para realizar a interao entre as pginas e os Managed Beans. Essa linguagem
chamada de Expression Language. Dentro do cdigo de uma tela, delimitamos os trechos
escritos em Expression Language atravs dos smbolos #{ }.

9.5.1

Nome dos Managed Beans

Todo Managed Bean possui um nome nico que utilizado para acess-lo dentro dos trechos escritos com Expression Language. Quando utilizamos a anotao @ManagedBean, por
padro, o JSF assume que o nome do Managed Bean o nome da classe com a primeira letra
minscula. Porm podemos alterar o nome acrescentado um argumento na anotao.
1
2
3
4

@ManagedBean(name="teste")
class ManagedBean {
}

9.5.2

Acessando as propriedades dos Managed Beans

As propriedades dos Managed Beans so acessadas tanto para leitura quanto para escrita da
maneira mais natural possvel, pelo nome. Suponha o seguinte Managed Bean:
1
2
3
4
5
6
7
8
9
10
11
12

@ManagedBean(name="teste")
class ManagedBean {
private String informacao;
public String getInformacao() {
return this.informacao;
}
public void setInformacao(String informacao) {
this.informacao = informacao;
}
}

A propriedade
Language:
1

INFORMACAO

deve ser acessada da seguinte forma utilizando Expression

#{teste.informacao}

9.6

Binding

Os componentes que esto nas telas podem ser ligados aos Managed Beans. Normalmente, essa ligao estabelecida atravs de algum atributo das tags dos componentes. Por
87

K19 Treinamentos

Managed Beans
exemplo, suponha que queremos ligar um campo de texto a uma propriedade de um Managed
Bean, o cdigo seria mais ou menos assim:
1

<h:inputText value="#{teste.informacao}"/>

O atributo VALUE do H : INPUT T EXT cria o vnculo entre o input e a propriedade INFORMA do Managed Bean TESTE. Dessa forma, quando o usurio preencher algum valor nesse
campo, esse dado ser armazenado no atributo INFORMACAO atravs do mtodo SET I NFOR MACAO ().
Outro exemplo, suponha que desejamos associar um mtodo do nosso Managed Bean a um
boto de uma tela qualquer. O cdigo seria mais ou menos assim:
CAO

1
2
3
4
5
6

@ManagedBean
class MeuManagedBean {
public void logica() {
// implemetao
}
}

<h:commandButton action="#{meuManagedBean.logica}" value="Executar"/>

9.7

Escopo

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.

9.7.1

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. Ou seja, os dados no so mantidos de uma requisio para outra.
O JSF utiliza o escopo Request como padro. Dessa forma, se o desenvolvedor no definir
nenhum escopo para um determinado Managed Bean o escopo Request ser adotado automaticamente.
Mesmo sendo o padro, podemos deixar explcito a escolha do escopo Request atravs da
anotao @RequestScoped ou da tag managed-bean-scope.
www.k19.com.br

88

Managed Beans
1
2
3
4
5
6
7

package managedbeans;

1
2
3
4
5

<managed-bean>
<managed-bean-name>meuManagedBean</managed-bean-name>
<managed-bean-class>managedbeans.MeuManagedBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

@ManagedBean
@RequestScoped
class MeuManagedBean {
}

Antes do JSF 2, havia somente a opo da configurao atravs de xml.

9.7.2

Session

Certas informaes devem ser mantidas entre as requisies de um determinado usurio


em um determinado navegador. Por exemplo, suponha uma aplicao que utiliza a ideia de
carrinho de compras. Um usurio faz diversas requisies para escolher os produtos e coloclos no seu carrinho. Durante todo esse tempo, a aplicao deve manter a informao de quais
produtos j foram escolhidos por este usurio.
Da surge o escopo Session. Cada usurio possui um espao na memria do servidor que
chamado de Session, ou seja, existe uma Session para cada usurio. Tecnicamente, possvel
existir duas ou mais Sessions de um mesmo usurio, por exemplo, se ele estiver utilizando dois
navegadores. As instncias dos Managed Beans configurados com o escopo Session so criadas
quando necessrias durante o processamento de uma requisio e armazenadas na Session do
usurio que fez a requisio.
Essas instncias so eliminadas basicamente em duas situaes: a prpria aplicao decide
por algum motivo especfico apagar a Session de um usurio (por exemplo, o usurio fez logout)
ou o Web Container decide apagar a Session de um usurio pois este no faz requisies a
muito tempo. Esse tempo pode ser configurado com o Web Container.
Para escolher o escopo Session, devemos utilizar a anotao @SessionScoped ou a tag
managed-bean-scope.
1
2
3
4
5
6
7

package managedbeans;

1
2
3
4
5

<managed-bean>
<managed-bean-name>meuManagedBean</managed-bean-name>
<managed-bean-class>managedbeans.MeuManagedBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

@ManagedBean
@SessionScoped
class MeuManagedBean {
}

89

K19 Treinamentos

Managed Beans
Antes do JSF 2, havia somente a opo da configurao atravs de xml.
Temos que tomar um cuidado maior ao utilizar o escopo Session pois podemos acabar
sobrecarregando o servidor. Portanto, a dica evitar utilizar o escopo Session quando possvel.
Para no consumir excessivamente os recursos de memria do servidor, o escopo Requeste
mais apropriado.

9.7.3

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.
Os dados dessas instncias podem ser utilizados nas telas de todos os usurios durante toda
a execuo da aplicao.
Analogamente, para escolher o escopo Application, devemos utilizar a anotao @ApplicationScoped ou a tag managed-bean-scope.
1
2
3
4
5
6
7

package managedbeans;

1
2
3
4
5

<managed-bean>
<managed-bean-name>meuManagedBean</managed-bean-name>
<managed-bean-class>managedbeans.MeuManagedBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>

@ManagedBean
@ApplicationScoped
class MeuManagedBean {
}

Antes do JSF 2, havia somente a opo da configurao atravs de xml.

9.7.4

View

O escopo View foi adicionado no JSF 2. A ideia manter determinados dados enquanto o
usurio no mudar de tela. As instncia dos Managed Beans em escopo View so eliminadas
somente quando h uma navegao entre telas.
Analogamente, para escolher o escopo View, devemos utilizar a anotao @ViewScoped
ou a tag managed-bean-scope.
1
2
3
4
5
6
7

package managedbeans;
@ManagedBean
@ViewScoped
class MeuManagedBean {
}

www.k19.com.br

90

Managed Beans
1
2
3
4
5

<managed-bean>
<managed-bean-name>meuManagedBean</managed-bean-name>
<managed-bean-class>managedbeans.MeuManagedBean</managed-bean-class>
<managed-bean-scope>view</managed-bean-scope>
</managed-bean>

Antes do JSF 2, havia somente a opo da configurao atravs de xml.

9.8

Interdependncia e Injeo

Instncias de Managed Beans podem conversar entre si para dividir o processamento das
requisies dos usurios de acordo a especialidade de cada uma delas. Para que duas instncias
conversem, uma deve possuir a referncia da outra.
Como a criao e eliminao das instncias dos Managed Beans so responsabilidade do
JSF, ele o mais indicado para administrar as referncias entre as instncias do Managed Beans.
Basicamente, o que o desenvolvedor deve fazer indicar ao JSF quais instncias devem ser
conectadas atravs de referncias.
Como exemplo, suponha dois Managed Beans:
1
2
3
4

@ManagedBean
class PrimeiroManagedBean {

1
2
3
4

@ManagedBean
class SegundoManagedBean {

Suponha tambm que o primeiro precisa chamar o segundo para resolver algum problema.
Do ponto de vista da Orientao a Objetos, bastaria declarar um atributo na classe do primeiro
Managed Bean relacionando-o ao segundo.
1
2
3
4

@ManagedBean
class PrimeiroManagedBean {
private SegundoManagedBean segundoManagedBean;
}

Porm, como o JSF que vai administrar as ligaes entre os objetos, devemos indicar
atravs de anotaes ou de xml o vnculo dos dois Managed Beans.
1
2
3
4
5

@ManagedBean
class PrimeiroManagedBean {
@ManagedProperty(value="#{segundoManagedBean}")
private SegundoManagedBean segundoManagedBean;
}

91

K19 Treinamentos

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

<managed-bean>
<managed-bean-name>primeiroManagedBean</managed-bean-name>
<managed-bean-class>managedbeans.PrimeiroManagedBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>segundoManagedBean</property-name>
<value>#{segundoManagedBean}</value>
</managed-property>
</managed-bean>
<managed-bean>
<managed-bean-name>segundoManagedBean</managed-bean-name>
<managed-bean-class>managedbeans.SegundoManagedBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

Quando as instncias dos Managed Beans so criadas pelo JSF ele resolve todas as dependncias conectando os objetos.

9.9

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado ManagedBean seguindo os


passos vistos no exerccio do captulo 5.

2. Na pasta src, faa um pacote chamado managedbeans.

3. No pacote managedbeans, adicione a seguinte classe:

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

package managedbeans;
@ManagedBean(name="impostometro")
public class ImpostometroBean {
private double total;
private double valor;
public void adicionaImposto() {
this.total += this.valor;
}
// GETTERS AND SETTERS
}

4. Crie uma tela com o suporte do Managed Bean impostometro. O arquivo da tela deve
se chamar impostometro.xhtml.
www.k19.com.br

92

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Impostometro</title>
</h:head>
<h:body>
<h1>Impostometro</h1>
<h:form>
<h:panelGrid>
<h:outputText value="Total: #{impostometro.total}" />
<h:outputLabel value="Digite o imposto a ser adicionado: "
for="campo-imposto" />
<h:inputText id="campo-imposto" value="#{impostometro.valor}" />
<h:commandButton value="Adicionar"
action="#{impostometro.adicionaImposto}" />
</h:panelGrid>
</h:form>
</h:body>
</html>

Adicione alguns valores atravs do formulrio. Observe que o total no acumula os


valores adicionados em requisies anteriores. Por qu?

5. Altere o escopo do impostometro para Session. Teste novamente.

1
2
3

@ManagedBean(name="impostometro")
@SessionScoped
public class ImpostometroBean {

6. Crie um Managed Bean para guardar os valores de algumas taxas.

1
2
3
4
5
6
7
8
9

package managedbeans;
@ManagedBean(name="taxas")
public class TaxasBean {
private double selic = 3.5;
// GETTERS AND SETTERS
}

7. Faa um Managed Bean que calcula juros baseado na taxa selic. Para isso, ele deve ser
relacionado com o Managed Bean do exerccio anterior.
93

K19 Treinamentos

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

package managedbeans;
@ManagedBean(name="calculadora")
public class CalculadoraBean {
@ManagedProperty(value="#{taxas}")
private TaxasBean taxas;
private double montante;
private double juros;
public void calculaJuros() {
this.juros = this.montante * this.taxas.getSelic() / 100;
}
// GETTERS AND SETTERS
}

8. Construa uma tela que utilize os Managed Beans criados nos exerccios anteriores.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Calculadora de Imposto</title>
</h:head>
<h:body>
<h1>Calculadora de Imposto</h1>
<h:form>
<h:panelGrid>
<h:outputText value="Selic: #{taxas.selic}" />
<h:outputText value="Juros: #{calculadora.juros}" />
<h:outputLabel value="Digite um montante: " />
<h:inputText value="#{calculadora.montante}" />
<h:commandButton value="Calcular"
action="#{calculadora.calculaJuros}" />
</h:panelGrid>
</h:form>
</h:body>
</html>

www.k19.com.br

94

Captulo 10
Converso e Validao
10.1

Converso

Quando um usurio preenche um formulrio, os valores escolhidos so enviados para uma


aplicao. De acordo com o HTTP, protocolo de comunicao utilizado entre os navegadores e
as aplicaes web, esses dados no possuem tipagem. Eles so tratados como texto puro. Dessa
forma, quando uma aplicao recebe valores preenchidos em formulrios HTML, ela precisa
realizar a converso dos dados que deseja tratar de forma especfica.
Por exemplo, suponha 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 chegam para as aplicaes 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 para os usurios. Novamente, os dados devem ser convertidos antes de
enviados para os navegadores.
Felizmente, o JSF oferece um mecanismo automatizado de converso de dados. Veremos a
seguir o funcionamento desse mecanismo.

10.1.1

Converso Padro Implcita

Para os tipos fundamentais da linguagem Java, o JSF define conversores padres e os aplica
de maneira implcita, ou seja, no precisamos fazer nada para o processo de converso acontecer. Os tipos fundamentais do Java so:
BigDecimal
BigInteger
Boolean
Byte
Character
95

Converso e Validao
Double
Float
Integer
Long
Short

1
2
3
4
5
6
7

@ManagedBean
public class MeuManagedBean {

1
2

<!-- O valor digitado nesse campo ser convertido para double -->
<h:inputText value="#{meuManagedBean.numero}" />

private double numero;


// GETTERS AND SETTERS
}

10.1.2

Converso Padro Explcita

Em alguns casos, os conversores padres aplicados implicitamente nos tipos fundamentais


do Java no so suficientes. Por exemplo, para trabalhar com valores monetrios precisamos de
outros conversores. Por isso, o JSF define dois outros conversores padres para serem aplicados
de maneira explcita.
f:convertNumber
A tag f:convertNumber permite que converses mais sofisticadas sejam feitas em valores
numricos.
Estipulando duas casas decimais no mnimo:
1
2
3

<h:outputText value="#{managedbean.valor}" >


<f:convertNumber minFractionDigits="2" />
</h:outputText>

Defindo a formatao atravs de expresso regular:


1
2
3

<h:outputText value="#{managedbean.valor}" >


<f:convertNumber pattern="#0.000" />
</h:outputText>

www.k19.com.br

96

Converso e Validao

Apresentando os dados em porcentagem:


1
2
3

<h:outputText value="#{managedbean.valor}" >


<f:convertNumber type="percent" />
</h:outputText>

Utilizando o smbolo do Real para valores monetrios:


1
2
3

<h:outputText value="#{managedbean.valor}" >


<f:convertNumber currencySymbol="R$" type="currency" />
</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.
1
2
3

<h:outputText value="#{managedbean.date}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:outputText>

10.2

Mensagens de Erro

Eventualmente, as informaes preenchidas pelos usurios em formulrios no so adequadas impedindo a converso dos dados. Nesses casos, geralmente, desejamos apresentar para os
usurios mensagens relacionadas aos erros no preenchimento das informaes.

10.2.1

h:message

Para adicionar nas telas erros relacionados a um determinado campo, devemos utilizar a
componente h:message. Primeiro, temos que definir um id para o campo desejado. Depois,
97

K19 Treinamentos

Converso e Validao
associar o h:message a esse id.
1
2
3
4
5
6
7

@ManagedBean
public class MeuManagedBean {

1
2

<h:inputText value="#{meuManagedBean.numero}" id="campo-numero"/>


<h:message for="campo-numero"/>

private double numero;


// GETTERS AND SETTERS
}

10.2.2

h:messages

A tag h:message permite que os erros dos diversos campos de um formulrio sejam colocados um a um na tela. Inclusive, podemos colocar as mensagens de erro de campo em lugares
diferentes na pgina que ser apresentada ao usurio.
Em alguns casos, simplesmente, queremos colocar todos os erros de todos os campos de
um formulrio juntos na tela. Para isso, devemos aplicar a tag h:messages.
1

<h:messages/>

10.2.3

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

98

Converso e Validao
Essas mensagens esto definidas em ingls. Normalmente, queremos personalizar essas
mensagens. Para isso, devemos seguir dois passos:

1. Criar um arquivo de mensagens.


2. Registrar o arquivo de mensagens.

Criando um Arquivo de Mensagens


Um arquivo de mensagens um conjunto de chaves e valores. Sendo que cada chave se
refere a um tipo de erro e est associada a um valor que o texto que ser apresentado nas telas
atravs das tags h:message ou h:messages.
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.

Os arquivos de mensagens devem possuir o sufixo properties.

Registrando um Arquivo de Mensagens


Suponha que voc tenha criado um arquivo de mensagem chamado Messages.properties
num pacote chamado resources. Para registr-lo, voc deve acrescentar uma configurao no
arquivo faces-config.xml.
1
2
3

<application>
<message-bundle>resources.Messages</message-bundle>
</application>

10.3

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado ConversaoValidacao seguindo


os passos vistos no exerccio do captulo 5.
2. Acrescente um pacote na pasta src chamado managedbean e adicione a seguinte classe
nesse pacote:
99

K19 Treinamentos

Converso e Validao
1
2
3
4
5
6
7
8
9
10
11

@ManagedBean
public class FuncionarioBean {
private double salario;
private int codigo;
private Date aniversario;
// GETTERS AND SETTERS
}

3. Crie uma tela para cadastrar funcionrios. Adicione um arquivo na pasta WebContent
chamado cadastro.xhtml.

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Cadastro de Funcionrio</title>
</h:head>
<h:body>
<h1>Cadastro de Funcionrio</h1>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel value="Salrio: R$ " for="campo-salario"/>
<h:inputText id="campo-salario" value="#{funcionarioBean.salario}">
<!-- Sistema numrico do Brasil -->
<f:convertNumber locale="pt_BR"/>
</h:inputText>
<h:message for="campo-salario"/>
<h:outputLabel value="Cdigo: " for="campo-codigo"/>
<h:inputText id="campo-codigo" value="#{funcionarioBean.codigo}"/>
<h:message for="campo-codigo"/>
<h:outputLabel value="Data: (dd/MM/yyyy)" for="campo-aniversario"/>
<h:inputText id="campo-aniversario"
value="#{funcionarioBean.aniversario}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:inputText>
<h:message for="campo-aniversario"/>
<h:commandButton value="Cadastrar"/>
</h:panelGrid>
<h:messages/>
</h:form>
</h:body>
</html>

Preencha o formulrio vrias vezes com valores errados e observe os erros.


4. Faa um pacote chamado resources na pasta src e adicione um arquivo de mensagens
nesse pacote chamado Messages.properties com o seguinte contedo.
www.k19.com.br

100

Converso e Validao
1
2
3
4
5
6

javax.faces.converter.NumberConverter.NUMBER=O valor {0} no adequado.


javax.faces.converter.NumberConverter.NUMBER_detail={0} no nmero ou inadequado.
javax.faces.converter.IntegerConverter.INTEGER=O valor {0} no adequado.
javax.faces.converter.IntegerConverter.INTEGER_detail={0} no um nmero inteiro.
javax.faces.converter.DateTimeConverter.DATE=A data {0} no est correta.
javax.faces.converter.DateTimeConverter.DATE_detail= {0} no parece uma data.

5. Adicione a configurao necessria no faces-config.xml para utilizar o arquivo de mensagens criado no exerccio anterior.
1
2
3

<application>
<message-bundle>resources.Messages</message-bundle>
</application>

Observao: a tag <application> deve ser colocada dentro de faces-config.


6. Preencha o formulrio vrias vezes com valores errados e observe as novas mensagens.

10.4

Validao

Muitas vezes, apenas a converso de dados no suficiente para verificar se uma informao
preenchida em um formulrio por um usurio est correta. Por exemplo, suponha um campo
para os usurios digitarem uma idade. Como visto anteriormente, o valor digitado ser tratado
como texto at chegar na aplicao e l poder ser convertido para INT. Essa converso no
verifica se o nmero obtido negativo. Porm, nesse caso, no seria correto obter nmeros
negativos pois a idade de uma pessoa sempre positiva. Dessa forma, depois da converso dos
dados, mais uma etapa deve ser realizada para validar as informaes.

10.4.1

Validao Padro

O JSF tambm define validadores padres para serem aplicados nos dados obtidos dos
usurios. A seguir veremos a aplicao desses validadores:

10.4.2

Campo Obrigatrio (Required)

A validao mais comum de todas a de verificar se um determinado campo no deixou de


ser preenchido. Podemos aplicar essa validao utilizando o atributo required dos inputs.
1
2

<h:inputText value="#{managedbean.nome}" id="campo-nome" required="true"/>


<h:message for="campo-nome"/>

10.4.3

f:validateLongRange

O validador f:validateLongRange utilizado para verificar se um valor numrico inteiro


pertence a um determinado intervalo de nmeros.
101

K19 Treinamentos

Converso e Validao
1
2
3
4

<h:inputText value="#{managedbean.idade}" id="campo-idade">


<f:validateLongRange minimum="10" maximum="130" />
</h:inputText>
<h:message for="campo-idade"/>

10.4.4

f:validateDoubleRange

O validador f:validateDoubleRange utilizado para verificar se um valor numrico real


pertence a um determinado intervalo de nmeros.
1
2
3
4

<h:inputText value="#{managedbean.preco}" id="campo-preco">


<f:validateDoubleRange minimum="20.57" maximum="200.56" />
</h:inputText>
<h:message for="campo-preco"/>

10.4.5

f:validateLength

O validador f:validateLength utilizado para verificar se uma string possui uma quantidade mnima ou mxima de letras.
1
2
3
4

<h:inputText value="#{managedbean.nome}" id="campo-nome">


<f:validateLength minimum = "6" maximum = "20"/>
</h:inputText>
<h:message for="campo-nome"/>

10.4.6

f:validateRegex

O validador f:validateRegex utilizado para verificar se um texto respeita uma determinada


expresso regular.
1
2
3
4

<h:inputText value="#{managedbean.nome}" id="campo-nome">


<f:validateRegex pattern="[a-zA-Z]{6,20}"/>
</h:inputText>
<h:message for="campo-nome"/>

10.4.7

Bean Validation

Uma nova abordagem para definir as validaes foi adicionada no JSF2. A ideia declarar as regras de validao nas classes de modelo ao invs de inser-las nas telas. A grande
vantagem das validaes definidas nas classes de 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 de
modelo.
www.k19.com.br

102

Converso e Validao
1
2
3
4
5
6

public class Funcionario {


@NotNull
private String nome;
...
}

@NotNull: o valor no pode ser nulo.

@Min: define um valor mnimo.

@Max: define um valor mximo.

@Size: define um valor mnimo e mximo.

@Pattern: aplica uma expresso regular na validao.

Podemos acrescentar mensagens de erro atravs das anotaes.


1
2
3
4
5

public class Funcionario {


@NotNull(message="O nome no pode ser nulo")
private String nome;
...
}

10.5

Exerccios

7. No projeto ConversaoValidacao, crie uma tela para cadastrar produtos de uma loja virtual. O arquivo que voc criar deve se chamar cadastra-produto.xhtml.
103

K19 Treinamentos

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Cadastro de Produto</title>
</h:head>
<h:body>
<h:form>
<h:panelGrid columns="3">
<h:outputLabel value="Nome: " for="produto-nome"/>
<h:inputText id="produto-nome"
required="true"
value="#{produtoBean.produto.nome}"/>
<h:message for="produto-nome" />
<h:outputLabel value="Preo: " for="produto-preco"/>
<h:inputText id="produto-preco"
required="true"
value="#{produtoBean.produto.preco}">
<f:validateDoubleRange minimum="0" />
</h:inputText>
<h:message for="produto-preco" />
<h:commandButton value="Cadastrar" />
</h:panelGrid>
</h:form>
</h:body>
</html>

8. Crie a classe de modelo para definir os produtos. Adicione essa classe dentro de um
pacote chamado model.

1
2
3
4
5
6

public class Produto {


private String nome;
private double preco;
// GETTERS AND SETTERS
}

9. Depois, implemente o Managed Bean que dar suporte tela de cadastro de produtos.
Faa a classe ProdutoBean dentro do pacote managedbeans.

1
2
3
4
5
6

@ManagedBean
public class ProdutoBean {
private Produto produto = new Produto();
// GETTERS AND SETTERS
}

10. Teste o formulrio preenchendo diversos valores e observe as mensagens de erro.


www.k19.com.br

104

Converso e Validao
11. Retire a validao realizada com a tag f:validateDoubleRange. Acrescente uma validao com as anotaes da especificao de Bean Validation na classe P RODUTO.
1
2
3
4
5
6
7
8

public class Produto {


private String nome;
@Min(value = 0)
private double preco;
// GETTERS AND SETTERS
}

12. Teste novamente o formulrio.


13. (Opcional) Altere as mensagens de erros do formulrio de cadastro de produto.

105

K19 Treinamentos

Converso e Validao

www.k19.com.br

106

Captulo 11
Eventos
Normalmente, as pessoas preferem utilizar aplicaes que ofeream maior grau de interatividade. Consequentemente, as empresas buscam sistemas mais interativos para controlar os
seus negcios e serem utilizados pelos seus funcionrios.
A interatividade de uma aplicao est diretamente relacionada a sua capacidade de percepo e reao. O nvel mais alto de interatividade aconteceria se uma aplicao pudesse perceber
e reagir aos pensamentos dos usurios.
O JSF no oferece esse nvel de interao, na verdade, nenhuma tecnologia oferece. Mas,
veremos que ele oferece um mecanismo bem sofisticado para aumentar a interatividade com os
usurios. Esse mecanismo baseado na ideia de eventos. No JSF, h duas categorias fundamentais de eventos: eventos de aplicao e eventos de ciclo de vida.
Os eventos de aplicao correspondem s aes dos usurios que so pertinentes s aplicaes. Por exemplo, um usurio pressiona um boto ou altera o valor de preenchido em um
campo de um formulrio.
Os eventos de ciclo de vida correspondem s transies entre as diversas etapas do processamento de uma requisio ou s transies entre os estados dos componentes do JSF ou da
prpria aplicao.

11.1

Eventos de Aplicao (Application Events)

Como dito anteriormente, os eventos de aplicao correspondem s aes dos usurios que
interessam para as aplicaes. O JSF suporta dois tipos de eventos de aplicao: ActionEvent
e ValueChangeEvent.

11.1.1

ActionEvent

Os ActionEvents so gerados por botes ou links quando esses so pressionados pelos


usurios. O tratamento dos ActionEvents pode ser definido por mtodos dentro dos Managed
Beans. Esses mtodos so classificados em dois tipos: Action Method ou Action Listener
Method. Um Action Method deve ser utilizado quando desejamos efetuar uma navegao
(mudar de tela) aps o tratamento do evento. Caso contrrio, devemos utilizar um Action
Listener Method.
107

Eventos
Action Method
Um Action Method deve devolver uma String que ser utilizada como outcome para processar uma navegao. Veja um exemplo de Action Method.
1

<h:commandButton value="Salva" action="#{produtoBean.salva}" />

1
2
3
4

public String salva() {


// implementao
return "lista-produtos";
}

No h:commandButton definimos qual o Action Method que queremos associar ao boto


atravs do atributo action.
Action Listener Method
Um Action Listener Method precisa ser void e aceita um ActionEvent como argumento.
Um ActionEvent contem informaes sobre o evento disparado.
1

<h:commandButton value="Salva" actionListener="#{produtoBean.salva}" />

1
2
3

public void salva(ActionEvent event) {


// implementao
}

No h:commandButton definimos qual o Action Listener Method que queremos associar


ao boto atravs do atributo actionListener.

11.1.2

ValueChangeEvent

Os ValueChangeEvent so gerados quando os usurios modificam o valor preenchido em


um campo de um formulrio. O tratamento desse tipo de evento pode ser realizado por mtodos
de um Managed Bean. Esses mtodos so chamados de Value Change Listeners.
Um Value Change Listener precisa ser void e aceita um ValueChangeEvent como argumento. Um ValueChangeEvent contem informaes sobre o evento disparado.
1
2

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


<h:inputText valueChangeListener="#{produtoBean.mudaPrecoListener}"/>

1
2
3

public void mudaPrecoListener(ValueChangeEvent event) {


// implementao
}

www.k19.com.br

108

Eventos
No h:inputText definimos qual o Value Change Listener queremos associar ao campo
atravs do atributo valueChangeListener.

11.2

Eventos de Ciclo de Vida (Lifecycle Events)

Os eventos de ciclo de vida so utilizados quando desejamos executar procedimentos antes


ou depois de uma determinada etapa do processamento de uma requisio ou a cada mudana de
estado de um componente do JSF e da prpria aplicao. Vamos discutir a respeito dos Phase
Events que correspondem s transies entre as etapas do processamento das requisies.
Um Phase Event tratado por um Phase Listener. Como o prprio JSF dispara automaticamente os Phase Events, devemos apenas criar um Phase Listener e registr-lo.
Para criar um Phase Listener, devemos escrever uma classe que implemente a interface
PhaseListener.
1
2
3
4
5
6
7
8
9
10
11
12
13

package listeners;
public class MeuPhaseListener implements PhaseListener {
public void beforePhase(PhaseEvent pe) {
// implementao
}
public void afterPhase(PhaseEvent pe) {
// implementao
}
public PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
}

O mtodo getPhaseID() associa o listener a determinadas fases do processamento de uma


requisio. Os mtodos beforePhase() e afterPhase() so executados respectivamente antes e
depois das fases associadas ao listener.
Para registrar o nosso Phase Listener devemos acrescentar algumas configuraes no facesconfig.xml.
1
2
3

<lifecycle>
<phase-listener>listeners.MeuPhaseListener</phase-listener>
</lifecycle>

11.3

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado Eventos seguindo os passos
vistos no exerccio do captulo 5.
2. Vamos montar um formulrio de estados e cidades. Para isso, crie um pacote chamado
model e adicione a seguinte classe para representar os estados.
109

K19 Treinamentos

Eventos
1
2
3
4
5
6
7
8
9
10
11

package model;
public class Estado {
private String nome;
private String sigla;
private List<String> cidades = new ArrayList<String>();
// GETTERS AND SETTERS
}

3. Depois, crie um pacote managedbeans e adicione um Managed Bean para manipular os


estados.

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

package managedbeans;
@ManagedBean
@SessionScoped
public class LocalidadeBean {
private String cidade;
private String siglaEstado;
private Estado estado = new Estado();
private List<Estado> estados = new ArrayList<Estado>();
public LocalidadeBean() {
Estado sp = new Estado();
sp.setSigla("SP");
sp.setNome("So Paulo");
sp.getCidades().add("So Paulo");
sp.getCidades().add("Campinas");
Estado rj = new Estado();
rj.setSigla("RJ");
rj.setNome("Rio de Janeiro");
rj.getCidades().add("Rio de Janeiro");
rj.getCidades().add("Niteri");
this.estados.add(sp);
this.estados.add(rj);
}
public void mudaEstado(ValueChangeEvent vce) {
this.siglaEstado = vce.getNewValue().toString();
for(Estado e : this.estados){
if(e.getSigla().equals(this.siglaEstado)){
this.estado = e;
}
}
}
// GETTERS AND SETTERS
}

4. Faa a tela de busca de estados e cidade. Adicione um arquivo chamado busca-localidade.xhtml


na pasta WebContent.
www.k19.com.br

110

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

111

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Busca Localidade</title>
</h:head>
<h:body>
<h1>Busca Localidade</h1>
<h:form>
<h:outputLabel value="Estado: " for="campo-estado" />
<h:selectOneMenu
id="campo-estado"
value="#{localidadeBean.siglaEstado}"
valueChangeListener="#{localidadeBean.mudaEstado}"
onchange="this.form.submit();">
<f:selectItems
value="#{localidadeBean.estados}"
var="e"
itemLabel="#{e.nome}"
itemValue="#{e.sigla}" />
</h:selectOneMenu>
<h:outputLabel value="Cidade: " for="campo-cidade" />
<h:selectOneMenu
id="campo-cidade"
value="#{localidadeBean.cidade}">
<f:selectItems
value="#{localidadeBean.estado.cidades}" />
</h:selectOneMenu>
</h:form>
</h:body>
</html>

K19 Treinamentos

Eventos

www.k19.com.br

112

Captulo 12
Ajax
Quando as aplicaes possuem telas complexas com grande quantidade de contedo, no
interessante recarregar uma pgina inteira s para modificar um pequeno pedao da tela pois
isso deixar os usurios insatisfeitos.
Novamente, com o intuito de melhorar a interatividade entre as aplicaes e os usurios,
podemos aplicar o conceito do AJAX (Asynchronous Javascript And XML). Aplicando a ideia
do AJAX obtemos duas capacidades muito uteis: a primeira poder fazer requisies sem
recarregar as pginas completamente e sim a parte delas que nos interessa; a segunda poder
realizar requisies sem pausar a navegao dos usurios.
Por exemplo, suponha uma pgina de listagem de fotos que possua paginao. Quando o
usurio pressiona o link para a prxima pgina, no necessrio recarregar todo o contedo da
tela, podemos recarregar apenas os itens na listagem.
Outro exemplo, suponha uma aplicao de Instant Message (gtalk, msn, ...). A listagem de
contatos pode ser atualizada frequentemente sem os usurios pedirem e sem que eles tenham
que para a navegao para essa atualizao.
A verso 2 do JSF, diferentemente das anteriores, oferece suporte nativo a AJAX. Veremos
como utilizar esse suporte.

12.1

Fazendo requisies AJAX

As requisies AJAX so realizadas quando determinados eventos definidos pela linguagem Javascript ocorrem. Esses eventos esto fortemente relacionados aos componentes visuais
colocados nas telas. Precisamos indicar para o JSF quais componentes e eventos devem disparar requisies para o servidor. Para fazer isso, devemos utilizar a tag f:ajax (principal tag do
suporte nativo do JSF para aplicar o conceito do AJAX).
1
2
3

<h:inputText>
<f:ajax/>
</h:inputText>

No exemplo acima, uma requisio AJAX ser disparada quando o valor do campo for
modificado. Isso porque a tag f:ajax assume o evento padro do componente associado a ela.
O componente h:inputText utiliza por padro o evento onchange.
113

Ajax
Por outra lado, podemos explicitar o evento que deve disparar as requisies AJAX deixando o cdigo mais claro atravs do atributo event. Devemos tomar cuidado pois nem todos
os eventos so aceitos por todos os componentes.
1
2
3

<h:inputText>
<f:ajax event="keyup"/>
</h:inputText>

Quando temos vrios componentes para os quais desejamos oferecer o suporte do AJAX,
podemos agrup-los atravs da tag f:ajax.
1
2
3
4
5

<f:ajax>
<h:inputText/>
<h:inputSecret/>
<h:commandButton value="OK"/>
<f:ajax>

Novamente, se no escolhermos explicitamente o evento que vai disparar as requisies


o JSF assumir o padro de cada componente. O padro dos componentes h:inputText e
h:inputSecret onchange. O padro do componente h:commandButton onclick.
Mas, podemos explicitar o evento que deve disparar as requisies AJAX para um determinado grupo de componentes da mesma forma que fizemos anteriormente.
1
2
3
4
5

<f:ajax event="mouseout">
<h:inputText/>
<h:inputSecret/>
<h:commandButton value="OK"/>
<f:ajax>

12.2

Recarregando alguns pedaos das telas

Aps realizar uma requisio AJAX, podemos pedir para o JSF redesenhar alguns pedaos da tela que est sendo mostrada para o usurio. Por exemplo, suponha uma listagem
paginada de produtos, quando o usurio clica no boto que requisita atravs de AJAX a prxima
pgina e a resposta chega, podemos mandar o JSF redesenhar a listagem e apenas a listagem
com os dados que acabaram de chegar.
A tag f:ajax atravs do atributo render permite escolher os ids dos componentes que devem
ser recarregados aps uma requisio AJAX.
1
2
3
4

<h:commandButton value="Gera Nmero">


<f:ajax event="click" render="numero"/>
<h:commandButton/>
<h:outputText id="numero" value="managedBean.numero"/>

Podemos redesenhar vrios componentes, basta passar uma listagem de ids no valor do
atributo render.
www.k19.com.br

114

Ajax
1
2
3
4
5

<h:commandButton value="Gera Nmeros">


<f:ajax event="click" render="numero1 numero2"/>
<h:commandButton/>
<h:outputText id="numero1" value="managedBean.numero1"/>
<h:outputText id="numero2" value="managedBean.numero2"/>

12.3

Processando alguns pedaos das telas

Quando uma requisio AJAX feita, podemos determinar quais componentes da tela devem ser avaliados pelo JSF. Por exemplo, quando enviamos um formulrio, provavelmente, s
necessrio avaliar os componentes que esto no prprio formulrio.
Podemos definir quais componentes devem ser avaliados pelo JSF atravs do atributo execute passando uma lista de ids. Quando escolhemos um componente para ser avaliados os
componentes dentro dele tambm sero.
1
2
3
4
5
6
7
8
9
10

<h:form id="formulario">
<h:inputText/>
<h:inputSecret/>
<h:commandButton value="Entrar">
<f:ajax event="click" render="message" execute="formulario"/>
<h:commandButton/>
</h:form>
<h:outputText id="message" value="#{loginBean.message}"/>

12.4

Palavras especiais

Como podemos passar uma lista de componentes para os atributos render e execute, o JSF
criou palavras chaves associadas a grupos especiais de componente. Dessa forma, podemos
trabalhar sem a necessidade de definir ids em alguns casos.
@all : refere-se a todos os componentes da tela.
@nome : 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
requisio AJAX.
Podemos alterar o cdigo do formulrio anterior para utilizar a palavra especial @form no
lugar do id do formulrio.
115

K19 Treinamentos

Ajax
1
2
3
4
5
6
7
8
9
10

<h:form>
<h:inputText/>
<h:inputSecret/>
<h:commandButton value="Entrar">
<f:ajax event="click" render="message" execute="@form"/>
<h:commandButton/>
</h:form>
<h:outputText id="message" value="#{loginBean.message}"/>

12.5

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado Ajax seguindo os passos vistos
no exerccio do captulo 5.
2. Vamos montar um formulrio de cadastro de automveis. Para isso, crie um pacote
chamado model e adicione a seguinte classe para representar os automveis.
1
2
3
4
5
6
7
8
9
10

package model;
public class Automovel {
private String nome;
private String marca;
// GETTERS AND SETTERS
}

3. Depois, crie um pacote managedbeans e adicione um Managed Bean para manipular os


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

package managedbeans;
@ManagedBean
@SessionScoped
public class AutomovelBean {
private Automovel automovel = new Automovel();
private List<Automovel> automoveis = new ArrayList<Automovel>();
public void adiciona(){
this.automoveis.add(this.automovel);
this.automovel = new Automovel();
}
// GETTERS AND SETTERS
}

4. Faa a tela de listagem e cadastro de automveis. Adicione um arquivo chamado listacadastro-automovel.xhtml na pasta WebContent.
www.k19.com.br

116

Ajax
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

117

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:head>
<title>Automveis</title>
</h:head>
<h:body>
<h1>Novo Automvel</h1>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel
value="Nome: "
for="campo-nome" />
<h:inputText
id="campo-nome"
value="#{automovelBean.automovel.nome}" />
<h:outputLabel
value="Marca: "
for="campo-marca" />
<h:inputText
id="campo-marca"
value="#{automovelBean.automovel.marca}" />
<h:commandButton
value="Cadastrar">
<f:ajax
event="click"
render="lista"
execute="@form"
listener="#{automovelBean.adiciona}"/>
</h:commandButton>
</h:panelGrid>
<h1>Lista de Automveis</h1>
<h:dataTable
id="lista"
value="#{automovelBean.automoveis}"
var="automovel">
<h:column>
<f:facet name="header">
<h:outputText value="Nome" />
</f:facet>
#{automovel.nome}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Marca" />
</f:facet>
#{automovel.marca}
</h:column>
</h:dataTable>
</h:form>
</h:body>
</html>

K19 Treinamentos

Ajax

www.k19.com.br

118

Captulo 13
Projeto
Nos captulos anteriores, vimos isoladamente recursos do JSF e do JPA. Agora, vamos
mostrar em detalhes como esses recursos trabalham juntos e solidificar os conhecimentos obtidos. Alm disso, mostraremos alguns padres e conceitos relacionados ao desenvolvimento de
aplicaes web.
Como exemplo de aplicao desenvolveremos uma aplicao de cadastro de jogadores e
selees de futebol.

13.1

Modelo

Por onde comear o desenvolvimento de uma aplicao? Essa uma questo recorrente.
Um timo ponto de partida desenvolver as entidades principais da aplicao. No nosso caso,
vamos nos restringir s entidades Selecao e Jogador. Devemos estabelecer um relacionamento
entre essas entidades j que um jogador atua em uma seleo.

13.2

Exerccios

1. Crie um projeto do tipo Dynamic Web Project chamado K19-CopaDoMundo seguindo


os passos vistos no exerccio do captulo 5.
2. Faa um pacote chamado modelo e adicione as duas classes principais da nossa aplicao.

1
2
3
4
5
6
7
8

public class Selecao {


private String pais;
private String tecnico;
// GETTERS AND SETTERS
}

119

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

public class Jogador {


private String nome;
private String posicao;
private Calendar nascimento = new GregorianCalendar();
private double altura;
private Selecao selecao;

// GETTERS AND SETTERS


}

13.3

Persistncia - Mapeamento

Depois de definir algumas entidades podemos comear o processo de implementao da


persistncia da nossa aplicao. Vamos aplicar os recursos do JPA que aprendemos nos primeiros captulos. Inicialmente, vamos definir o mapeamento das nossas entidades atravs das
anotaes adequadas.

13.4

Exerccios

3. Adicione as anotaes do JPA nas classes de modelo.

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

@Entity
public class Selecao {
@Id @GeneratedValue
private Long id;
private String pais;
private String tecnico;
// GETTERS AND SETTERS
}

www.k19.com.br

120

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

@Entity
public class Jogador {
@Id @GeneratedValue
private Long id;
private String nome;
private String posicao;
private Calendar nascimento = new GregorianCalendar();
private double altura;
@ManyToOne
private Selecao selecao;

// GETTERS AND SETTERS


}

A anotao @ManyToOne utilizada para indicar a cardinalidade do relacionamento


entre jogadores e selees.

13.5

Persistncia - Configurao

Assim como nos captulos anteriores, implantaremos a nossa aplicao no Glassfish que
um servidor de aplicao Java EE. Os servidores de aplicao Java EE j possuem uma
implementao de JPA. Dessa forma, as aplicaes no precisam se preocupar em obter um
provedor de JPA.
Por outro lado, geralmente, os servidores de aplicao no so distribudos com os principais drivers JDBC que normalmente as aplicao desejam utilizar. Portanto, devemos adicionar
o driver JDBC que desejamos utilizar nas bibliotecas do Glassfish.
Depois disso, devemos configurar as propriedades do JPA atravs do arquivo persistence.xml.

13.6

Exerccios

4. Entre na pasta K19-Arquivos/MySQL-Connector-JDBC da rea de Trabalho e copie o


arquivo MYSQL - CONNECTOR - JAVA -5.1.13- BIN . JAR para pasta glassfishv3/glassfish/lib
tambm da sua rea de Trabalho.

5. Adicione uma pasta chamada META-INF na pasta src do projeto K19-CopaDoMundo.

6. Configure o JPA adicionando o arquivo persistence.xml na pasta META-INF.


121

K19 Treinamentos

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

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
version="1.0">
<persistence-unit name="copadomundo" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
<property name="hibernate.hbm2ddl.auto" value="update" />
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/copadomundo" />
</properties>
</persistence-unit>
</persistence>

7. Abra um terminal; entre no cliente do MySQL Server; apague se existir a base de dados
copadomundo; e crie uma base de dados nova chamada copadomundo.
Para entrar no MySQL Server:
mysql -u root -p
Para apagar uma base de dados:
DROP DATABASE copadomundo;
Para criar uma base de dados:
CREATE DATABASE copadomundo;

13.7

Persistncia - Open Session in View

13.7.1

Gerenciando as fbricas de Entity Managers

Quando trabalhamos com JPA, devemos nos preocupar com a criao e destruio das fbricas de entity manager. Ao criar uma fbrica de Entity Manager, todas as configuraes e
anotaes so processadas e armazenadas na memria. De fato, s necessrio realizar esse
processo uma vez para cada execuo. Alm disso, como esse procedimento pode consumir
significativamente os recursos da mquina ento realiz-lo duas ou mais vezes na mesma execuo seria apenas desperdcio.
No contexto de uma aplicao web implementada com JSF, podemos criar uma fbrica de
entity manager exatamente antes da primeira requisio servlet do JSF e destru-la exatamente
antes do encerramento da aplicao. Dessa forma, conseguiremos garantir a existncia da
fbrica durante todo o perodo no qual a aplicao receber requisies.
www.k19.com.br

122

Projeto

13.7.2

Filtros

Para implementar essa abordagem, podemos criar um filtro no Web Container associado
servlet do JSF. Dessa forma, antes da primeira requisio a essa servlet ele ser iniciado e
imediatamente antes da aplicao encerrar ele ser desativado.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

@WebFilter(servletNames={"Faces Servlet"})
public class JPAFilter implements Filter {
private EntityManagerFactory factory;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.factory = Persistence.createEntityManagerFactory("copadomundo");
}
@Override
public void destroy() {
this.factory.close();
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// por enquanto vazio
}
}

Um filtro registrado no Web Container atravs da anotao @WebFilter. Atravs dessa


anotao definimos qual servlet est associada ao nosso filtro pelo nome da servlet.
O mtodo INIT () chamado para inicializar o filtro imediatamente antes da primeira requisio ser enviada para a servlet do JSF. Criamos a fbrica de entity manager nesse mtodo.
O mtodo DESTROY () chamado para desativar o filtro imediatamente antes do encerramento da aplicao. Fechamos a fbrica de entity manager nesse mtodo.

13.7.3

Gerenciando os Entity Managers

Provavelmente, a estratgia de gerenciamento de Entity Managers mais simples de entender


e manter adotar o padro a Open Session in View. A ideia associar o tempo de vida de um
Entity Manager durao do processamento de uma requisio. Ou seja, quando uma requisio realizada, criamos um Entity Manager para ser utilizado no tratamento dessa requisio,
quando esse processamento terminar, fechamos o Entity Manager.
Para implementar o padro Open Session in View, podemos utilizar o mesmo filtro que
gerencia a criao e o fechamento das fbricas de Entity Manager pois as requisies passam
por esse filtro antes de chegar at a servlet do JSF. Alm disso, antes da resposta ser enviada ao
usurio, a execuo passa pelo filtro novamente.
Na chegada de uma requisio, devemos criar um Entity Manager e adicion-lo na requisio para que ele possa ser acessado pela aplicao durante o processamento dessa requisio.
Imediatamente, antes da resposta ser enviada, devemos abrir e confirmar uma transao no Entity Manager para que as alteraes decorrentes ao processamento da requisio sejam refletidas
no banco de dados.
123

K19 Treinamentos

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

@WebFilter(servletNames={"Faces Servlet"})
public class JPAFilter implements Filter {
private EntityManagerFactory factory;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
EntityManager entityManager = this.factory.createEntityManager();
request.setAttribute("entityManager", entityManager);
chain.doFilter(request, response);
try {
entityManager.getTransaction().begin();
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
} finally {
entityManager.close();
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.factory = Persistence.createEntityManagerFactory("copadomundo");
}
@Override
public void destroy() {
this.factory.close();
}
}

13.8

Exerccios

8. Faa um pacote chamado filtros e adicione nele uma classe chamada JPAFilter.
www.k19.com.br

124

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

@WebFilter(servletNames={"Faces Servlet"})
public class JPAFilter implements Filter {
private EntityManagerFactory factory;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
EntityManager entityManager = this.factory.createEntityManager();
request.setAttribute("entityManager", entityManager);
chain.doFilter(request, response);
try {
entityManager.getTransaction().begin();
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
} finally {
entityManager.close();
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.factory = Persistence.createEntityManagerFactory("copadomundo");
}
@Override
public void destroy() {
this.factory.close();
}
}

13.9

Persistncia - Repositrios

Vamos deixar os repositrios para acessar as entidades da nossa aplicao preparados. Os


repositrios precisam de Entity Managers para realizar as operaes de persistncia. Ento,
cada repositrio ter um construtor para receber um Entity Manager como parmetro.
Como o padro Open Session in View foi adotado na nossa aplicao, o gerenciamento das
transaes no uma tarefa dos repositrios. Mas, o funcionamento deles ainda afetado pelo
controle de transaes.
Se um usurio faz uma requisio para cadastrar uma seleo ela s existir no banco de
dados quando o processamento voltar para o filtro que gerencia as transaes. Nesse momento,
a tela de resposta j teria sido montada pelo Facelets com os dados do banco de dados sem a
nova seleo. Em outras palavras, o usurio veria uma listagem sem a seleo que ele acabou
de cadastrar.
Para resolver este problema, o repositrio de selees pode enviar a nova seleo imediatamente para o banco de dados bem antes da montagem da tela de resposta. Dessa forma,
essa tela de listagem de selees mostrar inclusive a nova seleo. A implementao desse
repositrio deve utilizar o mtodo flush() que envia imediatamente para o banco de dados as
alteraes realizadas dentro da transao corrente sem confirm-las (a confirmao s ocorre
na chamada do mtodo commit()).
125

K19 Treinamentos

Projeto
Para que esse processo funcione, devemos alterar o nosso filtro de gerenciamento transacional para que ele abra uma transao na chegada de uma nova requisio. Caso contrrio, o
mtodo flush() no funcionar no repositrio de selees.
Os outros repositrios podem adotar a mesma estratgia para garantir que os usurios vejam
dados atualizados.

13.10

Exerccios

9. Faa um pacote chamado repositorios e adicione nele uma classe chamada SelecaoRepository.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

public class SelecaoRepository {


private EntityManager entityManager;
public SelecaoRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void adiciona(Selecao selecao) {
this.entityManager.persist(selecao);
this.entityManager.flush();
}
public List<Selecao> getSelecoes() {
Query query = this.entityManager
.createQuery("select s from Selecao as s");
return query.getResultList();
}
}

10. Analogamente crie um repositrio de jogadores.


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

public class JogadorRepository {


private EntityManager entityManager;
public JogadorRepository(EntityManager entityManager) {
this.entityManager = entityManager;
}
public void adiciona(Jogador jogador) {
this.entityManager.persist(jogador);
this.entityManager.flush();
}
public List<Jogador> getJogadores() {
Query query = this.entityManager
.createQuery("select j from Jogador as j");
return query.getResultList();
}
}

11. Altere o filtro de gerenciamento de transaes. Abra uma transao na chegada de uma
requisio. Veja como deve ficar o mtodo doFilter().
www.k19.com.br

126

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

EntityManager entityManager = this.factory.createEntityManager();


request.setAttribute("entityManager", entityManager);
entityManager.getTransaction().begin();
chain.doFilter(request, response);
try {
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
} finally {
entityManager.close();
}

13.11

Apresentao - Template

Vamos definir um template para as telas da nossa aplicao utilizando os recursos do Facelets. Aplicaremos algumas regras CSS para melhorar a parte visual das telas.

13.12

Exerccios

12. Na pasta WebContent, crie um arquivo com algumas regras CSS chamado style.css.
127

K19 Treinamentos

Projeto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

.logo{
vertical-align: middle;
}
.botao {
background-color: #064D83;
margin: 0 0 0 20px;
color: white;
text-decoration: none;
font-size: 20px;
line-height: 20px;
padding: 5px;
vertical-align: middle;
}
.botao:hover{
background-color: #cccccc;
color: #666666;
}
.formulario fieldset{
float: left;
margin: 0 0 20px 0;
border: 1px solid #333333;
}
.formulario fieldset legend{
color: #064D83;
font-weight: bold;
}
.botao-formulario{
background-color: #064D83;
color: #ffffff;
padding: 5px;
vertical-align: middle;
border: none;
}
.mensagem-erro{
color: #ff0000;
}
.titulo {
color: #064D83;
clear: both;
}
.tabela{
border: 1px solid #064D83;
border-collapse: collapse;
}
.tabela tr th{
background-color: #064D83;
color: #ffffff;
}
.tabela tr th,
.tabela tr td{
border: 1px solid #064D83;
padding: 2px 5px;
}

13. Copie o arquivo k19-logo.png da pasta K19-Arquivos da sua rea de Trabalho para a
pasta WebContent.
www.k19.com.br

128

Projeto
14. Agora implemente um template utilizando Facelets. Crie um arquivo chamado template.xhtml na pasta WebContent.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Copa do Mundo</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
</h:head>
<h:body>
<div id="header">
<img class="logo" src="k19-logo.png" />
<h:outputLink styleClass="botao" value="selecoes.xhtml">Selecoes</h:outputLink>
<h:outputLink styleClass="botao" value="jogadores.xhtml">Jogadores</h:outputLink>
<hr/>
</div>
<ui:insert name="conteudo"> Espao para o contedo da tela </ui:insert>
<div id="footer" style="text-align: center">
<hr />
&copy; 2010 K19. Todos os direitos reservados.
</div>
</h:body>
</html>

15. Adicione duas telas, uma para selees e outra para jogadores. Essas duas telas devem
utilizar o template criado no exerccio anterior. Os arquivos devem se chamar: selecoes.xhtml e jogadores.xhtml e ambos devem possuir o seguinte contedo.
1
2
3
4
5
6
7
8
9

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="template.xhtml">
</ui:composition>
</html>

16. Acesse as duas telas criadas anteriormente.

13.13

Cadastrando e Listando Selees

Na tela de selees, vamos adicionar um formulrio para cadastrar novas selees e uma tabela para apresentar as j cadastradas. Aplicaremos regras de validao especficas para garantir
que nenhum dado incorreto seja armazenado no banco de dados. Alm disso, utilizaremos os
recursos nativos do JSF 2 para aplicar as tcnicas de AJAX.
129

K19 Treinamentos

Projeto

13.14

Exerccios

17. Para garantir uma melhor legibilidade da nossa aplicao, criaremos uma tela parcial
com os campos e o boto referentes ao cadastramento de selees. Adicione o arquivo
cadastro-selecao.xhtml na pasta WebContent com o seguinte contedo.

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

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<fieldset>
<legend>Nova Seleo</legend>
<h:panelGrid columns="3">
<h:outputLabel value="Pas: " for="selecao-pais" />
<h:inputText
id="selecao-pais"
required="true"
value="#{selecaoBean.selecao.pais}">
<f:validateLength minimum="3" />
</h:inputText>
<h:message for="selecao-pais" styleClass="mensagem-erro" />
<h:outputLabel value="Tcnico: " for="selecao-tecnico" />
<h:inputText
id="selecao-tecnico"
required="true"
value="#{selecaoBean.selecao.tecnico}">
<f:validateLength minimum="6" />
</h:inputText>
<h:message for="selecao-tecnico" styleClass="mensagem-erro" />
<h:commandButton value="Cadastrar" styleClass="botao-formulario">
<f:ajax
event="click"
execute="@form"
listener="#{selecaoBean.adiciona}"
render="@form" />
</h:commandButton>
</h:panelGrid>
</fieldset>
</html>

18. Analogamente ao exerccio anterior, vamos criar uma tela parcial para apresentar as selees dentro de uma tabela. Adicione o arquivo listagem-selecoes.xhtml na pasta WebContent com o seguinte contedo.
www.k19.com.br

130

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

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h3 class="titulo">Listagem de Selees</h3>
<h:dataTable
id="tabela"
value="#{selecaoBean.selecoes}"
var="selecao"
styleClass="tabela">
<h:column>
<f:facet name="header">
<h:outputText value="Id" />
</f:facet>
#{selecao.id}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Pas" />
</f:facet>
#{selecao.pais}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Tcnico" />
</f:facet>
#{selecao.tecnico}
</h:column>
</h:dataTable>
</html>

19. O prximo passo montar a tela principal de selees agrupando as telas parciais criadas
anteriormente. Veja como deve ficar o arquivo selecoes.xhtml.

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

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h:form styleClass="formulario">
<ui:include src="/cadastro-selecao.xhtml"/>
<ui:include src="/listagem-selecoes.xhtml"/>
</h:form>
</ui:define>
</ui:composition>
</html>

20. Implemente um Managed Bean para dar suporte s funcionalidades da tela de selees.
Adicione um pacote chamado managedbeans.
131

K19 Treinamentos

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

@ManagedBean
public class SelecaoBean {
@ManagedProperty(value = "#{entityManager}")
private EntityManager entityManager;
private Selecao selecao = new Selecao();
public void adiciona() {
SelecaoRepository repository = new SelecaoRepository(this.entityManager);
repository.adiciona(this.selecao);
this.selecao = new Selecao();
}
public List<Selecao> getSelecoes() {
SelecaoRepository repository = new SelecaoRepository(this.entityManager);
return repository.getSelecoes();
}
// GETTERS AND SETTERS
}

OBS: O Filtro que implementa o padro Open Session in View armazena os Entity Managers em escopo de requisio. Dessa forma podemos injet-los nos Managed Beans com
o mesmo escopo atravs da anotao @ManagedProperty. Por outro lado, os Managed Beans com escopos maiores devem utilizar o seguinte cdigo para acessar os Entity
Managers.

1
2

ELContext elContext = FacesContext.getCurrentInstance().getELContext();


EntityManager entityManager = (EntityManager) FacesContext.getCurrentInstance().getApplication().getELResolver().getValue(elContext, null, "entityManager");

13.15

Mensagens de Erro

Vamos personalizar as mensagens de erro criando um arquivo de mensagens em portugus.


Devemos registrar esse arquivo no faces-config.xml.

13.16

Exerccios

21. Crie um pacote na pasta src chamado resources. Adicione nesse pacote um arquivo
chamadao Messages.properties com o seguinte contedo:

1
2

javax.faces.component.UIInput.REQUIRED = Campo obrigatrio


javax.faces.validator.LengthValidator.MINIMUM = O nmero mnimo de caracteres "{0}".

22. Adicione o seguinte trecho no arquivo faces-config.xml:


www.k19.com.br

132

Projeto
1
2
3

<application>
<message-bundle>resources.Messages</message-bundle>
</application>

13.17

Removendo Selees

Vamos acrescentar a funcionalidade de remover selees utilizando o suporte de AJAX do


JSF 2.

13.18

Exerccios

23. Acrescente uma coluna na tabela que apresenta das selees alterando o arquivo listagemselecoes.xhtml.
1
2
3
4
5
6
7
8
9
10
11

<h:column>
<f:facet name="header">
<h:outputText value="Remover" />
</f:facet>
<f:ajax
event="click"
render="@form"
listener="#{selecaoBean.remove(selecao)}">
<h:commandLink>Remover</h:commandLink>
</f:ajax>
</h:column>

24. Implemente um mtodo para remover selees no repositrio de selees, SelecaoRepository.


1
2
3
4

public void remove(Selecao selecao) {


this.entityManager.remove(selecao);
this.entityManager.flush();
}

25. Adicione um mtodo para remover selees no Managed Bean SelecaoBean.


1
2
3
4

public void remove(Selecao selecao) {


SelecaoRepository repository = new SelecaoRepository(this.entityManager);
repository.remove(selecao);
}

13.19

Otimizando o nmero de consultas

Os getters dos Managed Beans so chamados diversas vezes pelo JSF durante o processamento de uma requisio. Por exemplo, o mtodo getSelecoes() da classe SelecaoBean
133

K19 Treinamentos

Projeto
chamado cerca de nove vezes durante o processamento da requisio pgina principal de selees. Esse mtodo chama o getSelecoes() do repositrio que por sua vez faz uma consulta no
banco de dados, ou seja, so realizadas cerca de nove consultas iguais para gerar a tela principal
de selees.
Podemos diminuir o nmero de consultas fazendo os Managed Beans armazenarem o resultado de uma consulta para utiliz-lo o maior nmero possvel de vezes. Apenas devemos
tomar cuidado para no manter informaes desatualizadas nos Managed Beans. Por exemplo, quando uma seleo for adicionada ou removida devemos descartar qualquer resultado
armazenado no Managed Bean SelecaoBean.

13.20

Exerccios

26. Imprima uma mensagem no mtodo getSelecoes() do Managed Bean SelecaoBean para
verificar a quantidade de vezes que ele chamado quando o usurio acessa a url:

http://localhost:8080/K19-CopaDoMundo/selecoes.xhtml.

1
2
3
4
5

public List<Selecao> getSelecoes() {


System.out.println("CHAMANDO O REPOSITORIO");
SelecaoRepository repository = new SelecaoRepository(this.entityManager);
return repository.getSelecoes();
}

27. Verifique quantas vezes a mensagem impressa no console do eclipse acessando a url:

http://localhost:8080/K19-CopaDoMundo/selecoes.xhtml

28. Altere a classe SelecaoBean para esse Managed Bean guardar os resultados das consultas
feitas nos repositrios.
www.k19.com.br

134

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

@ManagedBean
public class SelecaoBean {
@ManagedProperty(value = "#{entityManager}")
private EntityManager entityManager;
private Selecao selecao = new Selecao();
private List<Selecao> selecoes;
public void adiciona() {
SelecaoRepository repository = new SelecaoRepository(this.entityManager);
repository.adiciona(this.selecao);
this.selecao = new Selecao();
this.selecoes = null;
}
public void remove(Selecao selecao) {
SelecaoRepository repository = new SelecaoRepository(this.entityManager);
repository.remove(selecao);
this.selecoes = null;
}
public List<Selecao> getSelecoes() {
if (this.selecoes == null) {
System.out.println("CHAMANDO O REPOSITORIO");
SelecaoRepository repository = new SelecaoRepository(
this.entityManager);
this.selecoes = repository.getSelecoes();
}
return this.selecoes;
}
// GETTERS AND SETTERS
}

29. Verifique quantas vezes a mensagem impressa acessando novamente a url:


http://localhost:8080/K19-CopaDoMundo/selecoes.xhtml

13.21

Cadastrando, Listando e Removendo Jogadores

Na tela de jogadores, vamos adicionar um formulrio para cadastrar novos jogadores e


uma tabela para apresentar os j cadastrados. Aplicaremos regras de validao especficas
para garantir que nenhum dado incorreto seja armazenado no banco de dados. Alm disso,
utilizaremos os recursos nativos do JSF 2 para aplicar as tcnicas de AJAX.

13.22

Exerccios

30. Para garantir uma melhor legibilidade da nossa aplicao, criaremos uma tela parcial
com os campos e o boto referentes ao cadastramento de jogadores. Adicione o arquivo
cadastro-jogador.xhtml na pasta WebContent com o seguinte contedo.
135

K19 Treinamentos

Projeto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<fieldset>
<legend>Novo Jogador</legend>
<h:panelGrid columns="3">
<h:outputLabel value="Nome: " for="jogador-nome" />
<h:inputText
id="jogador-nome"
required="true"
value="#{jogadorBean.jogador.nome}">
<f:validateLength minimum="6" />
</h:inputText>
<h:message for="jogador-nome" styleClass="mensagem-erro" />
<h:outputLabel value="Posio: " for="jogador-posicao" />
<h:inputText
id="jogador-posicao"
required="true"
value="#{jogadorBean.jogador.posicao}">
</h:inputText>
<h:message for="jogador-posicao" styleClass="mensagem-erro" />
<h:outputLabel value="Data de Nascimento: " for="jogador-nascimento" />
<h:inputText
id="jogador-nascimento"
required="true"
value="#{jogadorBean.jogador.nascimento.time}">
<f:convertDateTime pattern="dd/MM/yyyy" />
</h:inputText>
<h:message for="jogador-nascimento" styleClass="mensagem-erro" />
<h:outputLabel value="Altura (m): " for="jogador-altura" />
<h:inputText
id="jogador-altura"
required="true"
value="#{jogadorBean.jogador.altura}">
</h:inputText>
<h:message for="jogador-altura" styleClass="mensagem-erro" />
<h:outputLabel value="Seleo: " for="jogador-selecao" />
<h:selectOneMenu id="jogador-selecao" value="#{jogadorBean.selecaoID}">
<f:selectItems
value="#{selecaoBean.selecoes}"
var="selecao"
itemLabel="#{selecao.pais}"
itemValue="#{selecao.id}" />
</h:selectOneMenu>
<h:message for="jogador-selecao" styleClass="mensagem-erro" />
<h:commandButton value="Cadastrar" styleClass="botao-formulario">
<f:ajax
event="click"
execute="@form"
listener="#{jogadorBean.adiciona}"
render="@form" />
</h:commandButton>
</h:panelGrid>
</fieldset>
</html>

31. Analogamente ao exerccio anterior, vamos criar uma tela parcial para apresentar os jogadores dentro de uma tabela. Adicione o arquivo listagem-jogadores.xhtml na pasta
WebContent com o seguinte contedo.
www.k19.com.br

136

Projeto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69

137

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h3 class="titulo">Listagem de Jogadores</h3>
<h:dataTable
id="tabela"
value="#{jogadorBean.jogadores}"
var="jogador"
styleClass="tabela">
<h:column>
<f:facet name="header">
<h:outputText value="Id" />
</f:facet>
#{jogador.id}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Nome" />
</f:facet>
#{jogador.nome}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Posio" />
</f:facet>
#{jogador.posicao}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Nascimento" />
</f:facet>
<h:outputText value="#{jogador.posicao}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Altura" />
</f:facet>
#{jogador.altura}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Seleo" />
</f:facet>
#{jogador.selecao.pais}
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Remover" />
</f:facet>
<f:ajax
event="click"
render="@form"
listener="#{jogadorBean.remove(jogador)}">
<h:commandLink>Remover</h:commandLink>
</f:ajax>
</h:column>
</h:dataTable>
</html>

K19 Treinamentos

Projeto
32. O prximo passo montar a tela principal de jogadores agrupando as telas parciais criadas anteriormente. Veja como deve ficar o arquivo jogadores.xhtml.

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

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h:form styleClass="formulario">
<ui:include src="/cadastro-jogador.xhtml"/>
<ui:include src="/listagem-jogadores.xhtml"/>
</h:form>
</ui:define>
</ui:composition>
</html>

33. Implemente um mtodo para remover jogadores no repositrio de jogadores, JogadorRepository.

1
2
3
4

public void remove(Jogador jogador) {


this.entityManager.remove(jogador);
this.entityManager.flush();
}

34. Adicione um mtodo no repositrio de selees para buscar por id.

1
2
3

public Selecao procura(Lond id) {


return this.entityManager.find(Selecao.class, id);
}

35. Crie um Managed Bean para trabalhar com a tela de jogadores.


www.k19.com.br

138

Projeto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

@ManagedBean
public class JogadorBean {
@ManagedProperty(value = "#{entityManager}")
private EntityManager entityManager;
private Jogador jogador = new Jogador();
private Long selecaoID;
private List<Jogador> jogadores;
public void adiciona() {
SelecaoRepository selecaoRepository =
new SelecaoRepository(this.entityManager);
Selecao selecao = selecaoRepository.procura(this.selecaoID);
this.jogador.setSelecao(selecao);
JogadorRepository jogadorRepository =
new JogadorRepository(this.entityManager);
jogadorRepository.adiciona(this.jogador);
this.jogador = new Jogador();
this.jogadores = null;
}
public void remove(Jogador jogador) {
JogadorRepository repository = new JogadorRepository(this.entityManager);
repository.remove(jogador);
this.jogadores = null;
}
public List<Jogador> getJogadores() {
if (this.jogadores == null) {
System.out.println("CHAMANDO O REPOSITORIO");
JogadorRepository repository = new JogadorRepository(
this.entityManager);
this.jogadores = repository.getJogadores();
}
return this.jogadores;
}
// GETTERS AND SETTERS
}

13.23

Removendo Selees com Jogadores

Se uma seleo possui jogadores ela no poder ser removida pois teramos dados inconsistentes no banco de dados. Em outras palavras, teramos jogadores vinculados com selees
que j teriam sido removidas. Nesse caso, uma possibilidade informar ao usurio que ele s
pode remover selees sem jogadores. Outra possibilidade remover a seleo e os jogadores
quando o usurio clicar no link para remover uma seleo. Na verdade, a maneira de proceder
depende das regras da aplicao. Vamos supor que a regra da nossa aplicao remover tanto a
seleo quanto os jogadores. Devemos alterar o repositrio de selees para aplicar essa regra.

13.24

Exerccios

36. Tente remover pela interface web uma seleo que possua jogadores.
139

K19 Treinamentos

Projeto
37. Altere a classe SelecaoRepository para que na remoo de selees os jogadores correspondentes tambm sejam removidos. A modificao deve ser feita no mtodo remove().

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

public void remove(Selecao selecao) {


this.entityManager.remove(selecao);
Query query = this.entityManager
.createQuery("select j from Jogador as j where j.selecao = :selecao");
query.setParameter("selecao", selecao);
List<Jogador> jogadores = query.getResultList();
for (Jogador jogador : jogadores) {
this.entityManager.remove(jogador);
}
this.entityManager.flush();
}

13.25

Controle de Acesso

Na maioria dos casos, as aplicaes devem controlar o acesso dos usurios. Vamos implementar um mecanismo de autenticao na nossa aplicao utilizando filtro. As requisies
feitas pelos usurios passaro por esse filtro antes de chegar ao controle do JSF. A funo do
filtro verificar se o usurio est logado ou no. Se estiver logado o filtro autoriza o acesso.
Caso contrrio, o filtro redirecionar o usurio para a tela de login.

13.26

Exerccios

38. Adicione no pacote filtros a seguinte classe:


www.k19.com.br

140

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

@WebFilter(servletNames = { "Faces Servlet" })


public class LoginFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
if (session.getAttribute("autenticado") != null
|| req.getRequestURI().endsWith("login.xhtml")) {
chain.doFilter(request, response);
} else {
HttpServletResponse res = (HttpServletResponse) response;
res.sendRedirect("login.xhtml");
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}

39. Crie a tela de login adicionando um arquivo chamado login.xhtml na pasta WebContent.

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

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h:form styleClass="formulario">
<h:outputLabel value="Usurio: " for="usuario"/>
<h:inputText id="usuario" value="#{loginBean.usuario}" />
<h:outputLabel value="Senha: " for="senha"/>
<h:inputSecret id="senha" value="#{loginBean.senha}"/>
<h:commandButton value="Entrar" action="#{loginBean.entrar}"/>
</h:form>
</ui:define>
</ui:composition>
</html>

40. Implemente o Managed Bean que autentica os usurios. Adicione uma classe no pacote
managedbeans chamada LoginBean.
141

K19 Treinamentos

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

@ManagedBean
public class LoginBean {
private String usuario;
private String senha;
public String entrar() {
if ("k19".equals(this.usuario) && "k19".equals(this.senha)) {
HttpSession session = (HttpSession) FacesContext
.getCurrentInstance().getExternalContext()
.getSession(false);
session.setAttribute("autenticado", true);
return "/selecoes";
} else {
return "/login";
}
}
public String sair() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
.getExternalContext().getSession(false);
session.removeAttribute("autenticado");
return "/ate-logo";
}
// GETTERS AND SETTERS
}

41. Crie uma tela de despedida que ser utilizada quando um usurio sair da aplicao. Adicione um arquivo chamado ate-logo.xhtml na pasta WebContent.

1
2
3
4
5
6
7
8
9
10
11

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h3 class="titulo" >At Logo</h3>
</ui:define>
</ui:composition>
</html>

42. Modifique o template das telas para acrescentar um boto de sair.


www.k19.com.br

142

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Copa do Mundo</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
</h:head>
<h:body>
<div id="header">
<img class="logo" src="k19-logo.png" />
<h:outputLink styleClass="botao" value="selecoes.xhtml">Selecoes</h:outputLink>
<h:outputLink styleClass="botao" value="jogadores.xhtml">Jogadores</h:outputLink>
<h:form style="display: inline;">
<h:commandLink styleClass="botao" action="#{loginBean.sair}">Sair</h:commandLink>
</h:form>
<hr/>
</div>
<ui:insert name="conteudo"> Espao para o contedo da tela </ui:insert>
<div id="footer" style="text-align: center">
<hr />
&copy; 2010 K19. Todos os direitos reservados.
</div>
</h:body>
</html>

13.27

Ordem dos filtros

Em alguns casos a ordem de execuo dos filtros afeta o funcionamento da aplicao. No


caso da nossa aplicao, a ordem correta de execuo dos filtros primeiro o filtro de autenticao e depois o de controle transacional.
No podemos definir a ordem de execuo de uma conjunto de filtros atravs de anotaes.
Podemos determinar essa sequncia se os filtros forem registrados no arquivo de configuraes
do Web Container, web.xml. A ordem de execuo do filtros a ordem na qual eles aparecem
no arquivo de configurao.

13.28

Exerccios

43. Remova a anotao @WebFilter das classes JPAFilter e LoginFilter que esto no pacote filtros.

44. Adicione o seguinte trecho de configurao no arquivo web.xml.


143

K19 Treinamentos

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

<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>jpa.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
<filter>
<filter-name>JPAFilter</filter-name>
<filter-class>jpa.JPAFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>JPAFilter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>

13.29

Controle de Erro

Quando uma exception ocorre durante o processamento de uma requisio, o filtro de controle transacional dispara um rollback para desfazer o que j havia sido alterado no banco de
dados. Porm, o usurio no informado sobre o problema.
Podemos configurar uma pgina de erro padro para ser utilizada toda vez que um erro
ocorrer. O filtro de controle transacional deve lanar uma ServletException aps disparar o
rollback para informar o Web Container que houve uma falha no processamento da requisio.
Depois, devemos configurar uma pgina de erro padro no Web Container.

13.30

Exerccios

45. Modifique o filtro de controle transacional para que ele informe o Web Container atravs
de uma exception que houve um problema no processamento de uma requisio.
www.k19.com.br

144

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

public class JPAFilter implements Filter {


private EntityManagerFactory factory;
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
EntityManager entityManager = this.factory.createEntityManager();
request.setAttribute("entityManager", entityManager);
entityManager.getTransaction().begin();
chain.doFilter(request, response);
try {
entityManager.getTransaction().commit();
} catch (Exception e) {
entityManager.getTransaction().rollback();
throw new ServletException(e);
} finally {
entityManager.close();
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.factory = Persistence.createEntityManagerFactory("copadomundo");
}
@Override
public void destroy() {
this.factory.close();
}
}

46. Configure a pgina de erro no arquivo web.xml. Acrescente o seguinte trecho.


1
2
3
4

<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/erro.xhtml</location>
</error-page>

47. Crie a pgina de erro adicionando um arquivo chamado erro.xhtml na pasta WebContent com o seguinte contedo.
1
2
3
4
5
6
7
8
9
10
11

145

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h3 class="titulo" >Erro Interno</h3>
</ui:define>
</ui:composition>
</html>

K19 Treinamentos

Projeto
48. Vamos criar um Managed Bean que sempre gera um problema para testar a pgina de
erro. Adicione a classe ErroBean no pacote managedbeans com o seguinte contedo.

1
2
3
4
5
6

@ManagedBean
public class ErroBean {
public void erro(){
throw new NullPointerException();
}
}

49. Modifique o template para adicionar um boto que dispara o Managed Bean que sempre
gera um erro.

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

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


"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<h:head>
<title>Copa do Mundo</title>
<link rel="stylesheet" href="style.css" type="text/css"/>
</h:head>
<h:body>
<div id="header">
<img class="logo" src="k19-logo.png" />
<h:outputLink styleClass="botao" value="selecoes.xhtml">Selecoes</h:outputLink>
<h:outputLink styleClass="botao" value="jogadores.xhtml">Jogadores</h:outputLink>
<h:form style="display: inline;">
<h:commandLink styleClass="botao" action="#{loginBean.sair}">Sair</h:commandLink>
<h:commandLink styleClass="botao" action="#{erroBean.erro}">Erro</h:commandLink>
</h:form>
<hr/>
</div>
<ui:insert name="conteudo"> Espao para o contedo da tela </ui:insert>
<div id="footer" style="text-align: center">
<hr />
&copy; 2010 K19. Todos os direitos reservados.
</div>
</h:body>
</html>

13.31

Enviando email

Quando um erro ocorre na nossa aplicao, podemos permitir que o usurio envie uma
email para os administradores do sistema. Devemos utilizar a especificao JavaMail para que
a nossa aplicao JSF tenha a capacidade de enviar mensagems por email.
www.k19.com.br

146

Projeto

13.32

Exerccios

50. Altere a tela de erro adicionando um formulrio para o usurio escrever uma mensagem
para os administradores da aplicao.

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

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="conteudo">
<h3 class="titulo">Erro Interno</h3>
<p>Envie uma mensagem para os administradores do sistema.</p>
<h:form styleClass="formulario">
<h:panelGrid columns="3">
<h:outputLabel value="Mensagem: " for="campo-mensagem" />
<h:inputTextarea
id="campo-mensagem"
value="#{emailBean.mensagem}"
required="true"
rows="10"
cols="30"/>
<h:message for="campo-mensagem" />
<h:commandButton value="Enviar" action="#{emailBean.envia}" />
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
</html>

51. Crie um Managed Bean que envie as mensagens por email utilizando a especificao
JavaMail. Observao, utilize usurios, senhas e emails vlidos do gmail para este exerccio.
147

K19 Treinamentos

Projeto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

@ManagedBean
public class EmailBean {
private String mensagem;
private Properties properties = new Properties();
private Authenticator authenticator;
public EmailBean() {
this.properties.put("mail.smtp.auth", true);
this.properties.put("mail.smtp.port", "465");
this.properties.put("mail.host", "smtp.gmail.com");
this.properties.put("mail.smtp.socketFactory.class",
"javax.net.ssl.SSLSocketFactory");
this.properties.put("mail.smtp.socketFactory.fallback", "false");
this.authenticator = new Authenticator() {
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("USURIO DO GMAIL", "SENHA DO USURIO");
};
};
}
public String envia() throws AddressException, MessagingException {
Session session = Session.getInstance(this.properties,
this.authenticator);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress("EMAIL DE ORIGEM"));
message.setRecipients(Message.RecipientType.TO, "EMAIL DE DESTINO");
message.setSentDate(new Date());
message.setSubject("Copa do Mundo - Erro");
message.setContent(this.mensagem, "text/plain");
Transport.send(message);
return "/selecoes";
}
// GETTERS AND SETTERS
}

www.k19.com.br

148

Você também pode gostar