Você está na página 1de 177

Apostila de JSP

Traduo Resumida do Livro


Web Development with JavaServer Pages
de Duane K. Fields e Mark A. Kolb
Prof. Carlos Ribeiro
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 2
ndice
1. INTRODUO.................................................................................................................................. 5
1.1 Desempenho ............................................................................................................................. 5
1.2 Separando a Apresentao da Implementao.......................................................................... 7
1.3 Diviso do Trabalho ................................................................................................................. 8
2. FUNDAMENTOS............................................................................................................................... 9
2.1 Primeiro Exemplo de Pgina JSP............................................................................................ 9
2.2 Segunda Verso do Exemplo Al Mundo ................................................................................ 9
2.3 Verso do Exemplo Al Mundo com Bean............................................................................ 10
2.4 Convenes sobre Tags .......................................................................................................... 12
2.5 Como JSP Funciona................................................................................................................ 13
3. PROGRAMANDO SCRIPTS JSP.................................................................................................. 17
3.1 Linguagens de Script .............................................................................................................. 17
3.2 Tags JSP ................................................................................................................................. 17
3.3 Diretivas JSP .......................................................................................................................... 17
3.3.1 Diretiva de Pgina .............................................................................................................. 18
3.3.2 Diretiva Include .................................................................................................................. 23
3.3.3 Diretiva Tag Library........................................................................................................... 23
3.4 Elementos de Script ................................................................................................................ 24
3.4.1 Declaraes......................................................................................................................... 24
3.4.2 Expresses .......................................................................................................................... 27
3.4.3 Scriptlets ............................................................................................................................. 28
3.5 Fluxo de Controle ................................................................................................................... 29
3.5.1 Condies ........................................................................................................................... 29
3.5.2 Iterao ............................................................................................................................... 30
3.5.3 Tratamento de excees...................................................................................................... 31
3.6 Comentrios............................................................................................................................ 32
3.6.1 Comentrios de Contedo................................................................................................... 32
3.6.2 Comentrios JSP................................................................................................................. 32
3.6.3 Comentrios da Linguagem de Script................................................................................. 33
4. OBJETOS IMPLCITOS E AES........................................................................................ 34
4.1 Objetos Implcitos................................................................................................................... 34
4.1.1 Objetos Relacionados a Servlets......................................................................................... 35
4.1.2 Entrada e Sada ................................................................................................................... 37
4.1.3 Objetos Contextuais............................................................................................................ 42
4.1.4 Tratamento de Erros ........................................................................................................... 49
4.2 Aes ...................................................................................................................................... 49
4.2.1 Forward............................................................................................................................... 50
4.2.2 Plug-in ................................................................................................................................ 53
4.2.3 Bean Tags ........................................................................................................................... 53
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 3
5. UTILIZANDO COMPONENTES JSP....................................................................................... 54
5.1 O Modelo de Componentes JSP ............................................................................................. 54
5.1.1 Arquiteturas de Componentes............................................................................................. 54
5.1.2 Benefcios da Abordagem Baseada em Componentes........................................................ 54
5.1.3 O Projeto de Componentes para Aplicaes Web .............................................................. 54
5.2 Fundamentos de JavaBeans .................................................................................................... 55
5.3 JSP Bean Tags ........................................................................................................................ 58
5.3.1 Programao com Componentes Baseados em Tags.......................................................... 58
5.3.2 Acessando Componentes JSP............................................................................................. 59
5.3.3 Inicializando Beans............................................................................................................. 65
5.3.4 Controlando o Escopo de um Bean..................................................................................... 69
6. DESENVOLVENDO COMPONENTES JSP............................................................................ 75
6.1 O Que Faz de um Bean um Bean............................................................................................ 75
6.1.1 Convenes......................................................................................................................... 75
6.1.2 O Construtor Bean.............................................................................................................. 76
6.1.3 Definindo as Propriedades de um Bean.............................................................................. 77
6.1.4 Propriedades Indexadas ...................................................................................................... 79
6.1.5 Propriedades Boleanas........................................................................................................ 82
6.1.6 Converso de Tipo JSP....................................................................................................... 83
6.1.7 Configurando Beans ........................................................................................................... 83
6.2 Alguns Exemplos.................................................................................................................... 85
6.2.1 Exemplo: HoraCorrenteBean.............................................................................................. 85
6.2.2 Um Bean que Calcula Juros Compostos............................................................................. 86
6.3 Interfaces Definidas para Beans ............................................................................................. 90
6.3.1 A Interface Serializable ...................................................................................................... 90
6.3.2 A Interface HttpSessionBindingListener ............................................................................ 90
6.4 Misturando Scriptlets e Bean Tags ......................................................................................... 91
6.4.1 Acessando Beans Atravs de Scriptlets .............................................................................. 91
6.4.2 Acessando Objetos Criados Atravs de Scriptlets .............................................................. 91
7. TRABALHANDO COM BANCOS DE DADOS....................................................................... 95
7.1 JSP e JDBC............................................................................................................................. 95
7.1.1 JNDI e Data Sources........................................................................................................... 95
7.2 Aplicaes de Banco de Dados com JSP................................................................................ 96
7.2.1 Criando Componentes JSP a partir de Dados de uma Tabela............................................. 96
7.2.2 Tipos de Dados JSP e JDBC............................................................................................... 98
7.2.3 Mantendo Conexes Persistentes...................................................................................... 100
7.2.4 Manipulando Grandes Conjuntos de Resultados .............................................................. 102
7.3 Exemplo: Ferramenta para Controle de Reservas para Conferncias........................................ 106
7.3.1 Resumo do Projeto............................................................................................................ 106
7.3.2 O Banco de Dados ............................................................................................................ 107
7.3.3 Resumo do Projeto............................................................................................................ 107
8. PROJETANDO APLICAES JSP........................................................................................ 114
8.1 Aplicaes para a Web ......................................................................................................... 114
8.1.1 O Fluxo de Aplicaes para a Web .................................................................................. 115
8.1.2 Abordagens de Projeto...................................................................................................... 116
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 4
8.2 Projeto Page-Centric............................................................................................................. 116
8.2.1 Pginas Baseadas em Funes.......................................................................................... 116
8.2.2 Construindo Pginas Compostas ...................................................................................... 118
8.2.3 Limitaes da Abordagem Page-Centric .......................................................................... 120
8.3 Abordagem Servlet-Centric.................................................................................................. 120
8.3.1 O Exemplo Al Mundo com Servlets............................................................................... 121
8.3.2 JSP e a API Servlet ........................................................................................................... 122
8.3.3 Servlets para Controle de Aplicaes ............................................................................... 125
8.3.4 Servlets para o Tratamento da Lgica da Aplicao......................................................... 126
8.3.5 Servlets como Ponto nico de Entrada ............................................................................ 129
8.3.6 Tratando Erros no Servlet ................................................................................................. 133
8.3.7 Exemplo: Uma Aplicao Servlet-Centric........................................................................ 133
8.3.8 Retornando uma Lista de Empregados ............................................................................. 139
8.3.9 Retornando um nico Empregado ................................................................................... 140
8.4 Enterprise JavaBeans............................................................................................................ 141
8.4.1 O que so Enterprise JavaBeans ....................................................................................... 142
8.4.2 JavaBeans x EJBs ............................................................................................................. 142
8.4.3 Projeto de Aplicaes com EJBs ...................................................................................... 142
9. EXECUTANDO TAREFAS COMUNS COM JSP................................................................. 144
9.1 Tratando Cookies.................................................................................................................. 144
9.1.1 Gerenciando Cookies........................................................................................................ 144
9.1.2 A Classe Cookie ............................................................................................................... 144
9.1.3 Exemplo 1: Criando um Cookie ....................................................................................... 146
9.1.4 Exemplo 2: Recuperando um Cookie ............................................................................... 147
9.2 Criando Pginas de Erro....................................................................................................... 148
9.2.1 Uma Pgina com Erro....................................................................................................... 149
9.9.2 Mtodos para a Coleta de Dados sobre o Erro.................................................................. 149
9.2.3 Enviando Correio Eletrnico ............................................................................................ 153
9.2.4 A pgina de Erro............................................................................................................... 155
9.3 Misturando JSP e JavaScript ................................................................................................ 158
9.4 Construindo Interfaces Interativas........................................................................................ 161
9.4.1 Mtodos Utilitrios ........................................................................................................... 162
9.4.2 O Formulrio Exemplo..................................................................................................... 164
9.4.3 Criando o Formulrio ....................................................................................................... 164
9.4.4 Campos de Texto e Escondidos........................................................................................ 165
9.4.5 reas de Texto.................................................................................................................. 165
9.4.6 Botes de Rdio................................................................................................................ 166
9.4.7 Caixas de Seleo ............................................................................................................. 166
9.4.8 Caixas de Confirmao..................................................................................................... 166
9.4.9 Cdigo Fonte do Formulrio ............................................................................................ 167
9.5 Validando Dados de Formulrio........................................................................................... 170
9.5.1 Validao de Dados nos Lados Cliente e Servidor ........................................................... 170
9.5.2 Exemplo de Validao no Lado Servidor ......................................................................... 170
9.6 Tarefas Variadas................................................................................................................... 174
9.6.1 Determinando a ltima Data de Modificao de uma Pgina.......................................... 174
9.6.2 Executando Comandos de Sistema................................................................................... 175
9.6.3 Gerando XML................................................................................................................... 176
10. BIBLIOGRAFIA.................................................................................................................... 177
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 5
1. INTRODUO
Em 1996 a Sun Microsystems introduziu os servlets como pequenas aplicaes
baseadas em Java para adicionar funcionalidade dinmica aos servidores web. Java
Servlets possuem um modelo de programao similar a scripts CGI, uma vez que eles
recebem do servidor web uma requisio HTTP como entrada e geralmente constrem o
contedo apropriado para a resposta que o servidor web dever encaminhar ao usurio.
1.1 Desempenho
No entanto, diferentemente dos CGIs que necessitam de um novo processo na memria
para tratar cada nova requisio, todos os servlets associados a um servidor web so
executados dentro de um nico processo. Este processo executa a Mquina Virtual
Java (JVM) que dependente de plataforma para executar (em qualquer plataforma)
programas Java compilados. Em vez de criar um processo para cada requisio, a JVM
cria uma thread Java para manipular cada requisio enviada a um servlet. Threads
Java causam um overhead muito menor do que a completa instanciao de processos
para a execuo de programas CGI, isto , o overhead causado para a instanciao e
destruio de uma thread significativamente menor do que para a instanciao e
destruio de um processo. Por esta razo threads costumam ser chamadas de
processos peso leve. Por utilizarem menos recursos, so muito mais eficientes do que
processos. Por exemplo, processos geralmente copiam a memria do processo pai,
enquanto as threads compartilham a memria com o processo pai.
Por outro lado, como as requisies a servlets e a pginas JSP so atendidas por um
mesmo processo (JVM) que persiste alm do ciclo de vida de uma nica requisio,
servlets tambm podem evitar operaes que consomem muito tempo, tal como a
conexo com bancos de dados. Isto , uma nica conexo pode ser compartilhada por
vrias requisies. Por exemplo, o acesso a banco de dados muito mais rpido
quando se utiliza um pool de conexes reutilizveis que sempre permanecem abertas.
Ao mesmo tempo, como servlets so escritos em Java, eles se beneficiam do ncleo da
plataforma Java: um modelo de programao orientado a objetos, gerenciamento de
memria automtico, portabilidade total e acesso a uma rica coleo de APIs Java
agora disponveis para acesso a bancos de dados, recursos de rede, etc.
Uma desvantagem potencial desta abordagem, no entanto, reside no cdigo fonte do
programa. Como resultado, qualquer modificao em um documento requer a
interveno de um programador. O designer de uma pgina HTML no pode modificar o
layout de uma pgina a menos que saiba como mexer no cdigo fonte do servlet. De
fato, qualquer mudana em um elemento esttico de um documento requer a
correspondente mudana do cdigo fonte.
Como discutido no pargrafo anterior, a incorporao de contedo dinmico a um
documento envolve alguma forma de programao para descrever como este contedo
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 6
gerado. Cdigo de programa, no entanto, tende a ser caro na criao e manuteno,
logo, minimizar a necessidade de programao geralmente um objetivo desejvel.
JSP combina este objetivo com o suporte completo todas as caractersticas da
linguagem Java.
JSP um sistema hbrido entre os sistemas template existentes, pois suportam dois
estilos diferentes para se adicionar contedo dinmico a pginas web. Como PHP e ASP,
scripts podem ser embutidos em pginas JSP contendo cdigo de programao. No
caso de JSP este cdigo geralmente Java, embora, de acordo com a especificao de
JSP, uma linguagem de script alternativa possa ser utilizada. E como ColdFusion, JSP
suporta um conjunto de tags no estilo HTML que interagem com objetos Java no
servidor, sem a necessidade de aparecer cdigo Java na pgina. Em particular, estes
tags so projetados para se criar, consultar e modificar server-side JavaBeans.
De fato, a especificao de JSP 1.1 prov um mecanismo que permite que os
desenvolvedores criem bibliotecas de tags customizados que possam ser carregados em
uma pgina JSP. Estes tags customizados podero ento ser utilizados na pgina assim
como os tags JSP padro.
Como uma demonstrao do poder desta abordagem, a empresa Live Software,
construtora do JRun (um software que habilita a execuo se servlets e de pginas JSP
em qualquer servidor web), desenvolveu um conjunto de tags JSP customizados que
reproduziam os tags utilizados pelo produto ColdFusion da Allaire. Este produto (um
clone do ColdFusion, multi-plataforma e baseado em Java) foi liberado em maio de
1999 como <CF_Anywhere>. A Allaire ficou to impressionada com o produto que em
maio de 1999 comprou a Live Software.
Servlets e JavaServer Pages apareceram pela primeira vez como parte do Java Web
Server da Sun, um servidor HTTP escrito em Java. Posteriormente a Sun liberou a
tecnologia servlet como uma extenso padro da linguagem Java. A primeira
especificao de JSP surgiu em Junho de 1999.
Logo aps a Sun ter publicado a especificao para servlets, outras companhias
comearam a adicionar suporte a servlets em seus produtos. Atualmente h uma srie
de produtos de terceiros capazes de adicionar a funcionalidade de servlets e JSP a
servidores web. Dois dos mais populares produtos nesta categoria so JRun da Allaire
e o ServletExec da New Atlanta. E em junho de 1999 a Sun Microsystems e a Apache
Software Foundation anunciaram o projeto Jakarta, com o objetivo de gerar uma
implementao Open Source de servlets e JSP que tambm ir servir de referncia para
estas tecnologias. E dentre os Enterprise Web Application Servers podemos encontrar
o Netscape Application Server, IBM WebSphere e BEA WebLogic, entre outros.
Atualmente, o desenvolvimento de aplicaes JSP est comeando a deixar de ser um
processo manual. Boas ferramentas de desenvolvimento esto sendo desenvolvidas.
Vrios vendedores de ferramentas para a construo de sites para a web esto
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 7
providenciando o suporte a JSP nas verses de seus produtos. Entre eles podemos citar
Dreamweaver Ultradev (sucessor do Drumbeat 2000 que deixa de existir) da
Macromedia, Visual Age for Java da IBM, e o HomeSite da Allaire.
1.2 Separando a Apresentao da Implementao
JSP agora parte integrante do desenvolvimento de aplicaes para web utilizando
Java. Em funo da sua habilidade de separar a apresentao da lgica de
implementao atravs da combinao de texto markup padro com elementos de
script e componentes orientados a objetos (JavaBeans), JSP prov uma excelente
tecnologia de front-end para a web. Isto , possvel manter uma estrita separao
entre a apresentao dos dados a exibio da informao para o usurio final e a
sua implementao o cdigo necessrio para gerar a informao. O benefcio de
desacoplar estes dois aspectos que isto permite que modificaes sejam efetuadas em
um dos lados sem afetar o outro. Por exemplo, a forma como os dados so exibidos
(tipo de letra, cor, layout da pgina) podem ser revisados sem que seja necessrio
modificar qualquer cdigo Java. Da mesma forma, enquanto a interface com um
componente permanece inalterada, a implementao do componente pode ser alterada
(por ex., para melhorar o desempenho ou a manutenibilidade) sem nenhum efeito sobre
as pginas JSP que utilizam o componente. Se uma pgina JSP contm apenas tags e
nenhum cdigo Java, o primeiro requisito para garantir a separao entre apresentao
e implementao foi atingido, uma vez que no haver nenhum cdigo de
implementao misturado com cdigo de apresentao.
O segundo requisito fcil de explicar: no deve haver nenhum cdigo HTML em seus
JavaBeans, uma vez que nada impede que um JavaBean possua uma propriedade que
inclua strings de HTML. Por exemplo, pode ser tentador criar um JavaBean que tenha a
habilidade de gerar uma grande tabela HTML a partir dos resultados de uma query a um
banco de dados. Se, por qualquer razo, for necessrio modificar a aparncia da tabela
HTML, o JavaBean necessitar ser editado, compilado e testado.
Em algumas situaes, no entanto, a gerao de cdigo HTML programaticamente a
melhor soluo. Por exemplo, escrever uma aplicao que mostre as 10 ltimas
transaes bancrias de um cliente utilizando um Bean que retorne uma transao seria
desajeitado. Isto porque JSP no inclui nenhum built-in tag para interagir com
propriedades de Beans. Para resolver este dilema, as solues seriam: incluir cdigo
Java em sua pgina JSP, ou, escrever um Bean que gere sada HTML.
Felizmente JSP prov uma terceira alternativa, especificamente criada para se gerar
cdigo HTML programaticamente utilizando cdigo Java. O programador pode
implementar um novo tag JSP e empacot-lo em uma biblioteca especfica de uma
aplicao. Pginas JSP podero, ento, import-lo.
A utilizao de tags customizados no resolve o problema da separao entre
apresentao e implementao, mas h duas vantagens na gerao de cdigo HTML
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 8
atravs de tags customizados. Em primeiro lugar, tags customizados so uma forma de
se evitar a insero de cdigo Java em uma pgina HTML e, segundo, no lado da
programao, a gerao de cdigo HTML isolada dentro do cdigo da tag library. A tag
library ter dependncias sobre o seu cdigo JavaBeans, mas no vice-versa. Logo,
tags customizados provem uma interface bem definida entre apresentao e
implementao, sem contaminar arquivos JSP com cdigo de implementao, ou a
propriedade de um Bean com cdigo de apresentao.
E o fato de que JSP suporta a utilizao de componentes atravs de JavaBeans,
promete habilitar um novo conjunto de ferramentas para a criao de pginas web
graficamente, utilizando a abordagem da programao visual. A habilidade de criar
sofisticadas pginas JSP sem escrever um nico tag HTML pode ser uma realidade em
breve.
1.3 Diviso do Trabalho
Um importante efeito colateral deste desacoplamento entre apresentao e
implementao atravs de pginas JSP que ele promove uma clara diviso do
trabalho no desenvolvimento e manuteno de aplicaes para a web. De fato, raro o
indivduo que possui grande habilidade em programao e no projeto artstico.
Como resultado a maioria das equipes de desenvolvimento de aplicaes para a web
possuem pessoas com habilidades distintas, representando mltiplas especialidades.
Projetistas, artistas grficos e codificadores HTML so responsveis pela apresentao.
Programadores Java e projetistas de sistemas so responsveis pela implementao.
Equipes grandes de corporaes podem incluir ainda editores, consultores de
marketing, administradores de banco de dados, administradores de rede e
administradores de sistemas.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 9
2. FUNDAMENTOS
JavaServer Pages (JSP) uma tecnologia baseada na linguagem Java que simplifica o
processo de desenvolvimento de sites de contedo dinmico. Com JSP, web designers
e desenvolvedores podem rapidamente incorporar elementos dinmicos em suas
pginas utilizando cdigo Java embutido e uns poucos markup tags bastante simples.
Pense em JSP como um tipo de linguagem de script executada no servidor web,
embora, internamente seu funcionamento seja bastante diferente.
Como os elementos HTML estticos provem uma estrutura (framework) na qual o
contedo dinmico gerado pelo cdigo script ser inserido, ferramentas como JSP,
PHP, ASP, ColdFusion e etc, so conhecidas como sistemas template.
2.1 Primeiro Exemplo de Pgina JSP
Nesta sesso vamos criar uma pgina JSP que envia para o browser cliente a frase Al
Mundo!.
<HTML>
<BODY>
Al Mundo!
</BODY>
</HTML>
Para chamar esta pgina JSP: http://sbd:8100/jsp/aluno01/exercicio01/alomundo.jsp
Embora o exemplo acima contenha apenas cdigo HTML, no h nada errado nisto. Este
arquivo, com a extenso .jsp seria interpretado como uma requisio JSP. O servidor
web encaminharia a requisio ao container JSP local (a JSP engine) para
processamento. Naturalmente, o container JSP no encontraria nenhum elemento JSP
e, consequentemente, apenas devolveria estes comandos HTML ao servidor web que os
encaminharia ao browser do usurio.
2.2 Segunda Verso do Exemplo Al Mundo
Abaixo vem uma nova verso do exemplo anterior, desta vez no entanto, gerando
contedo dinamicamente atravs do uso um par de tags JSP.
<html>
<body>
<% String visitante = request.getParameter("nome");
if (visitante == null) visitante = "Mundo!"; %>
Al, <%= visitante %>!
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 10
Neste exemplo JSP tenta inicializar a varivel visitante a partir da requisio HTTP. Um
valor default designado varivel visitante caso um valor no seja fornecido pela
requisio. Uma expresso JSP ento utilizada para inserir o valor desta varivel na
sada HTML da pgina.
Parmetros de requisies so passados a pginas JSP utilizando o mecanismo normal
de passagem de parmetros HTTP. Para requisies do tipo GET valores de parmetros
so codificados e adicionados ao URL.
Para chamar esta pgina JSP: http://sbd:8100/jsp/aluno01/exercicio02/alomundo.jsp
ou http://sbd:8100/jsp/aluno01/exercicio02/alomundo.jsp?nome=Vinicius+Aguiar
O que torna este documento especial a sua terminao .jsp. Por default o nosso
servidor Web, configurado para reconhecer arquivos com a extenso .jsp e traduzi-
los para Java Servlets. Esta operao totalmente transparente para o cliente que
solicita a pgina. E o browser cliente v apenas a resposta do servidor web requisio
do usurio.
Em outras palavras, quando o servidor web recebe a requisio correspondente a uma
pgina JSP, esta requisio encaminhada ao container JSP para processamento. o
container JSP quem l e interpreta o cdigo no arquivo .jsp e gera o contedo
dinmico, inserindo o resultado no contedo esttico existente na pgina e retornando a
pgina completa ao servidor HTTP. Esta a pgina que enviada de volta ao browser.
2.3 Verso do Exemplo Al Mundo com Bean
Alm se suportar scripts, JSP possui tags para a interao com Java Beans. A vantagem
de se utilizar a abordagem baseada em Java Beans, como vimos no captulo anterior,
que esta abordagem promove a reutilizabilidade de cdigo (vrias pginas JSP podem
utilizar a classe AloBean sem a necessidade de escrever nenhuma linha de cdigo Java
adicional) e a separao entre apresentao e implementao (um arquivo contm
apenas HTML e tags tipo HTML, e outro contm apenas Java). Tambm fica evidente que
esta ltima abordagem requer um esforo maior para alcanar os mesmos resultados.
Antes de examinarmos a pgina JSP que faz uso de um Bean preciso cri-lo. Abaixo
vem o cdigo para um Bean denominado AloBean, que possui uma propriedade
denominada nome.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 11
package jsp.aluno01.exercicio03;
public class AloBean implements java.io.Serializable
{ String nome;
public AloBean ()
{ this.nome = "Mundo!";
}
public String getNome ()
{ return nome;
}
public void setNome (String nome)
{ this.nome = nome;
}
}
Java Beans, como se pode ver, so implementados como classes Java que aderem a um
conjunto de convenes para sua instanciao e para o acesso e determinao de suas
propriedades. Para conhecer todos os detalhes sobre estas convenes veja o captulo
Desenvolvendo Componentes.
Por enquanto observe que a classe AloBean possui um construtor sem argumentos, mas
que designa um valor default para a propriedade nome. Esta propriedade acessada
atravs do mtodo getNome(), e pode ser modificada atravs do mtodo setNome().
Agora vejamos a utilizao deste Bean na pgina JSP abaixo:
<html>
<body>
<jsp:useBean id="alo" class="jsp.aluno01.exercicio03.AloBean"/>
<jsp:setProperty name="alo" property="nome" param="nome"/>
Al, <jsp:getProperty name="alo" property="nome"/>!
</body>
</html>
O tag <jsp:useBean> indica que o Bean de uma classe particular ser utilizado nesta
pgina. Aqui a classe AloBean especificada. Alm disso, um identificador, alo,
especificado para a instncia deste Bean. Este identificador poder ser utilizado mais
tarde, para referenciar o Bean no arquivo JSP.
J o tag <jsp:setProperty>, neste exemplo, utilizado para modificar a propriedade
nome do Bean alo baseado no valor do parmetro nome da requisio. Este tag indica
que deve ser pesquisado na requisio HTTP um parmetro denominado nome, e se
encontrado, seu valor deve ser copiado da requisio para a propriedade nome do Bean.
E o tag <jsp:getProperty>, utilizado para acessar o valor de uma propriedade do
Bean e inseri-lo na pgina no local do tag original. Neste caso, o tag recupera a
propriedade nome do Bean associado ao identificador alo.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 12
Neste caso foi preciso criar, no servidor web, a pgina JSP
jsp/aluno01/exercicio03/alomundo.jsp sob o diretrio onde so armazenados os
arquivos .html e o Bean jsp/aluno01/exercicio03/AloBean sob o diretrio onde so
armazenados os arquivos .class.
Caso venhamos a executar esta pgina JSP assim:
http://sbd:8100/jsp/aluno01/exercicio03/alomundo.jsp
a sada ser Al Mundo! pois o valor default da propriedade nome o string
Mundo!. Como nenhum parmetro foi fornecido, o tag <jsp:setProperty> no
pde designar um novo valor para a propriedade nome. Por esta razo foi utilizado o
valor default, designado pelo construtor, que foi chamado como resultado do tag
<jsp:useBean>.
Por outro lado, se executarmos esta pgina JSP assim,
http://sbd:8100/jsp/aluno01/exercicio03/alomundo.jsp?nome=Vinicius+Aguiar
o tag <jsp:setProperty> encontraria um parmetro denominado nome na requisio
HTTP e atribuiria o valor deste parmetro propriedade nome do Bean.
2.4 Convenes sobre Tags
Tags JSP podem ser classificados em duas categorias bsicas: tags orientados a scripts
inspirados no ASP, e um conjunto completo de tags baseados em Extensible Markup
Language (XML).
2.4.1 Tags Orientados a Scripts
Estes tags so facilmente reconhecidos pelos seus delimitadores. Comeam com <% e
terminam com %>, e um caracter adicional pode aparecer aps <%, tais como !, =, ou
@.
Por exemplo:
<%! double raio = 7.5; %>
<%= 2 * Math.PI * raio %>
<% if (raio > 10.0)
{ out.println (Excede o mximo recomendvel);
} %>
<%@ include file=copyright.html %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 13
2.4.2 Tags Baseados em XML
Tags XML so case-sensitive enquanto tags HTML no so. XML requer que todos os
valores de atributos apaream entre aspas simples ou duplas. Valores de atributos HTML
s necessitam aparecer entre aspas quando contm espaos em branco. XML tambm faz
uma distino entre os tags que contm um corpo e os que no contm: os tags que no
contm corpo (tags que contm corpo so aqueles que possuem abertura e fechamento,
como <B> ... </B>) so delimitados por < e />. Por exemplo:
<jsp:forward page=admin.jsp/>
E os tags que possuem um corpo utilizam a mesma sintaxe do HTML. O tag de abertura
utiliza < para indicar o incio do tag e > para indicar o seu fim. E o tag de fechamento
utiliza </ para indicar o seu incio e > para indicar o seu fim. Abaixo vem um exemplo
de tag JSP com corpo:
<jsp:useBean id="login" class="jsp.aluno01.exercicio03.AloBean">
<jsp:setProperty name="login" property="grupo" value="admin"/>
</jsp:useBean>
Neste caso o contedo do corpo outro tag JSP. O tag no corpo no possui ele prprio
um corpo, logo, segue a outra conveno.
2.5 Como JSP Funciona
O primeiro componente de uma implementao de JavaServer Pages baseada em
servlets um servlet especial geralmente referenciado como compilador de pgina. O
container configurado para chamar este servlet para todas as requisies cujos URLs
possuam a extenso .jsp (ou outra qualquer que tenha sido configurada). A tarefa deste
servlet encontrar a pgina JSP solicitada, e compil-la em um servlet se necessrio.
Este servlet ter a funo de gerar o contedo dinmico da pgina JSP.
Logo, sempre que o servidor HTTP recebe uma requisio de uma pgina JSP, esta
requisio encaminhada ao container JSP que chama o compilador de pgina para
tratar a requisio. Na primeira vez que uma requisio recebida para uma pgina
JSP especfica, esta pgina JSP compilada em um servlet.
Para compilar a pgina, o compilador de pgina JSP examina a pgina procurando por
tags JSP. O contedo desta pgina traduzido no equivalente cdigo Java que, quando
executado, ir gerar a sada indicada pelo contedo do arquivo original. Comandos
HTML estticos so traduzidos em Java strings e so escritos sem modificao e na
mesma seqncia no output stream. Tags JSP so traduzidos em cdigo Java para a
gerao de contedo dinmico: tags para acesso a Beans so traduzidos nas
correspondentes chamadas a objetos e propriedades, enquanto elementos de scripts so
transferidos sem modificao. Uma vez construdo todo o cdigo do servlet, este
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 14
cdigo compilado e o arquivo .class resultante colocado no diretrio apropriado
para execuo subsequente.
A figura abaixo mostra o processo de criao e execuo de servlets JSP.
A maioria dos sistemas de gerao de contedo dinmico se baseiam em tags especiais,
linguagens de scripts interpretadas, ou a combinao de ambos. Na maioria destes
sistemas os arquivos que contm estes tags e/ou scripts devem sofrer o parse toda vez
que o documento requisitado. Este parse produz um overhead que evitado com
JavaServer Pages, uma vez que os arquivos JSP sofrem o parse apenas na primeira vez
que so requisitados. JSP mais lento do que outras abordagens na primeira
requisio, mas mais rpido nas requisies subsequentes.
Existe tambm um mecanismo que faz com que uma pgina JSP possa ser pr-
compilada pelo container JSP antes de qualquer usurio requisitar por esta pgina.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 15
Alm disso a JVM que executada dentro do container JSP procura manter residente na
memria do servidor web o cdigo associado a uma classe servlet JSP se as requisies
encaminhadas a esta classe ocorrem regularmente.
Sada Buferizada
Um servidor HTTP pode receber vrios tipos de requisies (GET ou POST, por exemplo)
que determinam como dados de parmetros so transmitidos para o servidor.
Requisies tambm podem ser acompanhadas por informaes de header que so
tipicamente utilizadas para identificar o tipo e capacidades do browser, controle de
cache e o suporte a cookies.
Da mesma forma o protocolo HTTP permite que o servidor envie informaes
adicionais de volta para o cliente na forma de headers de resposta. Estes headers so
enviados de volta ao cliente juntamente com o contedo solicitado, que referenciado
como o corpo da resposta. Headers de resposta so principalmente utilizados para
enviar ao browser informao de status sobre a requisio. E assim como headers de
requisio, tambm podem ser utilizados para controlar o cache e para enviar cookies.
Uma limitao do protocolo HTTP que o servidor no pode comear a enviar um
documento para um browser, mudar de idia, e pedir ao browser para no mostr-lo. O
servidor web pode abortar a transmisso do documento, mas o que j foi enviado
exibido. Por exemplo, se um erro ocorre no meio do processamento de uma pgina,
todo o contedo gerado at o momento do erro exibido pelo browser, seguido da
mensagem de erro.
Para resolver este problema os projetistas de JSP determinaram que toda sada gerada
por uma pgina JSP no deve ser automaticamente enviado ao browser a medida que a
pgina gerada. Todo o contedo da pgina deve ser temporariamente armazenado em
um buffer de sada. A sada armazenada no buffer s deve ser enviada ao browser
(como o corpo de uma resposta HTTP) aps o processamento de toda a pgina.
Como a sada armazenada em um buffer possvel gerar informao de header em
qualquer ponto do processamento de uma pgina JSP. Por exemplo, uma pgina JSP
pode incluir cdigo (ou um tag customizado) que condicionalmente envia um cookie, e
este cdigo (ou tag) pode aparecer em qualquer lugar da pgina. Assim sendo, o autor
de uma pgina JSP possui a garantia de que o corpo da resposta no ser enviado at
que toda a pgina seja processada, logo o header de resposta que envia o cookie
necessariamente ser enviado antes do corpo da resposta.
A buferizao da sada tambm permite que o processamento de uma resposta seja
abortado a qualquer momento, permitindo assim que uma nova resposta seja gerada.
Esta deciso pode ser baseada na lgica de programao associada ao processamento
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 16
da pgina JSP, ou pode resultar da deteco de um erro durante o processamento da
pgina.
importante levar em considerao, no entanto, que o buffer de sada finito. Seu
tamanho default de 8K, mas este valor pode ser alterado para cada pgina. Uma vez
atingido o limite de 8K (ou o valor especificado) a sada gerada at o momento
enviada ao browser cliente e o buffer e esvaziado para posterior utilizao. A partir do
momento que seu contedo enviado ao browser novas informaes de header no
podem mais ser adicionadas.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 17
3. PROGRAMANDO SCRIPTS JSP
A abordagem purista recomendada no captulo anterior para o desenvolvimento de
aplicaes baseadas em JavaBeans nem sempre a soluo mais prtica. Por exemplo,
no desenvolvimento do prottipo de uma aplicao o cronograma de desenvolvimento
pode no fornecer tempo suficiente para a construo de todos os componentes
necessrios aplicao. Nestes casos a alternativa a utilizao de uma linguagem de
script dentro de pginas JSP.
3.1 Linguagens de Script
A linguagem de script default para JSP Java. Se uma linguagem de script capaz de
interagir com objetos Java, ou pode ser estendida para interagir com objetos Java,
ento esta linguagem uma boa candidata para integrao com um container JSP. H
no mercado, por exemplo, containers JSP que utilizam Java Script como linguagem de
script.
3.2 Tags JSP
JSP prov quatro categorias principais de markup tags:
Directives um conjunto de tags que especificam caractersticas especficas para
uma pgina, isto , contm informaes de como um documento que contm estas
diretivas deve ser processado.
Scripting Elements so utilizados para embutir instrues de programao,
escritas na linguagem de script designada para a pgina.
Comments so utilizados para adicionar strings de documentao a pginas JSP.
Actions suportam vrios comportamentos diferentes. Assim como elementos de
script, actions so processados para cada requisio recebida pela pgina. Actions
podem transferir o controle entre pginas, especificar Applets e interagir com
componentes server-side JavaBeans.
3.3 Diretivas JSP
Uma diretiva pode, por exemplo, especificar qual a linguagem de script utilizada em
uma determinada pgina, incluir o contedo de outra pgina, ou indicar que a pgina
utiliza uma determinada biblioteca de tags customizados (custom tag library).
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 18
Diretivas no produzem diretamente nenhuma sada que seja visvel para os usurios
finais quando a pgina requisitada. Elas determinam a forma como um container JSP
ir processar a pgina.
3.3.1 Diretiva de Pgina
A sintaxe bsica a seguinte:
<%@ page atributo1=valor1 atributo2=valor2 atributo3=... %>
O espao em branco aps <%@ e antes de %> opcional mas recomendvel para
melhorar a leitura.
Como todos os tags JSP, a diretiva de pgina suporta a sintaxe baseada em XML, como
vem abaixo:
<jsp:directive.page atributo1=valor1
atributo2=valor2 atributo3=... />
Nos exemplos abaixo ser utilizada a primeira sintaxe por ser mais simples e mais
utilizada na prtica.
A figura abaixo relaciona os 11 atributos que podem ser utilizados nesta diretiva.
possvel especificar vrias diretivas de pgina em uma nica pgina. Com a exceo
do atributo import, no entanto, nenhum atributo de pgina individual pode aparecer em
mais de uma diretiva de pgina.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 19
Por exemplo, as diretivas abaixo so vlidas:
<%@ page info=Este um conjunto vlido de diretivas de pgina. %>
<%@ page language=java import=java.net.* %>
<%@ page import=java.util.List, java.util.ArrayList %>
Esta uma diretiva de pgina invlida, pois session aparece duas vezes:
<%@ page info=Este uma diretiva de pgina invlida session=false
buffer=16k autoFlush=false session=false %>
E estas so diretivas invlidas, pois o atributo info est repetido:
<%@ page info=Este no um conjunto vlido de diretivas de pgina. %>
<%@ page extends=com.taglib.wdjsp.MinhaPaginaJsp
info=Usa minha superclasse. %>
O Atributo Info
Permite a incluso de comentrios que podero ser vistos por outras ferramentas,
programaticamente.
O Atributo Language
Especifica a linguagem de script a ser utilizada na pgina. O default Java.
<%@ page language=java %>
O Atributo ContentType
Este atributo utilizado para indicar o tipo MIME da resposta sendo gerada pela
pgina JSP. Os tipos MIME mais comuns so text/html, text/xml, e text/plain.,
indicando respostas em HTML, XML ou texto puro. O tipo MIME default text/html.
<%@ page contentType=text/html %>
O Atributo Extends
Este atributo identifica a superclasse a ser utilizada pelo container JSP quando ele est
traduzindo a pgina JSP em um Servlet, e especificado assim:
<%@ page extends=com.taglib.wdjsp.MinhaPaginaJsp %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 20
Se, como geralmente ocorre, a pgina JSP est sendo entregue atravs do protocolo
HTTP, ento a superclasse especificada deve implementar a interface
javax.servlet.jsp.JspPage.
Na prtica este atributo raramente utilizado.
O Atributo Import
Ao contrrio do atributo extends, o uso deste atributo bastante comum.
<%@ page import=java.util.List, java.text.* %>
<%@ page import=java.util.ArrayList %>
O Atributo Session
O atributo session indica se a pgina JSP participa ou no do gerenciamento de
sesses. Isto , se haver ou no uma sesso associada a esta pgina. O valor default
para este atributo true. Caso no haja uma sesso associada a uma pgina h um leve
ganho de desempenho quando especificamos este fato.
<%@ page session=false %>
O Atributo Buffer
Para desabilitar a buferizao que ocorre por default em relao ao contedo
encaminhado aos browsers, faa:
<%@ page buffer=none %>
Alternativamente, este atributo pode ser utilizado para se modificar o tamanho default
do buffer em kilobytes, assim:
<%@ page buffer=12kb %>
Geralmente os containers JSP, com o objetivo de melhorar o desempenho, criam um
pool de buffers de sada em vez de criar um buffer de sada para cada requisio de
pgina JSP.
Em particular, a sada buferizada permite que se faa uso do atributo errorPage para
transferir o controle para uma pgina de erro amigvel quando ocorrem excees ao
longo da execuo de uma pgina JSP. Tais pginas de erro customizadas so
geralmente preferidas em vez de uma mensagem de erro da JVM no meio de uma sada
normal. Alm disso, pginas de erro podem ser escritas para notificar o webmaster ou a
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 21
equipe de desenvolvimento quando um erro de run-time ocorre. Veja o captulo
Executando Tarefas JSP Comuns para maiores informaes sobre tratamento de
erros.
Lembre-se de estipular um tamanho para o buffer de sada caso o valor default de 8k
no seja suficiente.
O Atributo AutoFlush
Este atributo controla o comportamento do container JSP quando o buffer de sada de
uma pgina enche. Se este atributo for designado para true (o default), o buffer de sada
ser automaticamente enviado ao servidor HTTP, que o responsvel por enviar este
contedo ao browser cliente.
<%@ page autoFlush=true %>
Por outro lado, se este atributo for designado para false, o container JSP no enviar o
buffer automaticamente para o servidor HTTP quando ele encher. Em vez disso, o
container JSP gerar uma exceo, que ter o efeito de interromper o processamento da
pgina JSP e exibir uma pgina de erro no browser que originou a requisio da
pgina. Atravs do uso deste atributo pode-se descobrir o tamanho da resposta gerada
por uma pgina JSP.
O Atributo IsThreadSafe
Este atributo utilizado para indicar se sua pgina JSP, uma vez compilada em um
servlet, ser capaz de responder a vrias requisies simultneas. Caso contrrio, este
atributo deve ser designado para false, assim:
<%@ page isThreadSafe=false %>
Quando este atributo designado para false, o container JSP despachar as requisies
para a pgina seqencialmente, na ordem em que foram recebidas, esperando pelo
trmino do processamento da requisio corrente antes de iniciar a prxima. Quando
este atributo designado para true (o default), uma nova thread criada para tratar
cada requisio para a pgina. Assim, vrias requisies para uma mesma pgina
podero ser tratadas simultaneamente.
Se este atributo pode ou no ser designado para true, no entanto, geralmente depende
dos recursos que so utilizados. Por exemplo, se sua pgina JSP cria e armazena uma
conexo de banco de dados, esta conexo dever ser utilizada apenas por um usurio
final de cada vez caso esta pgina trate transaes no atmicas, exceto se controles
especiais forem efetuados na utilizao da conexo (como a utilizao de blocos
synchronized). Se, por outro lado, uma pgina JSP acessa um pool de conexes de
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 22
banco de dados e espera por uma conexo livre antes de comear seu processamento,
ento o atributo isThreadSafe pode provavelmente ser designado para true.
Logo, preciso examinar cuidadosamente todas as variveis estticas e todos os
objetos utilizados por pginas JSP cujos escopos sejam session ou application (veja o
prximo captulo).
Finalmente, importante saber que se uma pgina JSP designa o atributo isThreadSafe
para false, possvel determinar que uma implementao instancie vrias instncias do
servlet correspondente a fim de prover um desempenho melhor. Desta forma as
instncias individuais manipulam uma requisio de cada vez. No entanto, atravs da
criao de um pool de instncias, o container JSP poder ainda tratar um limitado
nmero de requisies simultneas.
O Atributo ErrorPage
Este atributo utilizado para especificar uma pgina alternativa que dever ser exibida
caso um erro (no capturado) ocorra enquanto o container JSP processa uma pgina.
Esta pgina alternativa especificada atravs de um URL local, conforme vem abaixo:
<%@ page errorPage=/webdev/misc/error.jsp %>
Isto , o URL do atributo errorPage deve especificar uma pgina JSP no mesmo servidor
da pgina que gerou o erro. Um URL relativo tambm pode ser especificado. Neste caso
o URL ser relativo pgina que provocou o erro. No contexto do atributo errorPage,
URLs absolutos comeam por /, enquanto URLs relativos no.
Se a sada de uma pgina JSP no est sendo armazenada em um buffer e alguma sada
j tiver sido gerada antes da ocorrncia do erro, no ser possvel efetuar um forward
para a pgina de exibio de erro. Caso a sada esteja sendo armazenada em um buffer
e o atributo autoFlush esteja designado para true, no momento em que o buffer encher
e a sada for enviada pela primeira vez, tambm no ser mais possvel efetuar o
forward para a pgina de exibio de erro.
O Atributo IsErrorPage
O atributo isErrorPage utilizado para marcar uma pgina JSP que serve como
pgina de exibio de erro para uma ou mais pginas JSP.
<%@ page isErrorPage=true %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 23
Quando este atributo designado para true, ele indica que a pgina corrente ser
capaz de acessar o objeto implcito exception que ser ligado ao objeto Java
exception.
O valor default deste atributo false.
3.3.2 Diretiva Include
Esta diretiva permite que se inclua o contedo de um arquivo em outro. O arquivo a ser
includo identificado atravs de um URL local.
<%@ include file=URLlocal %>
Como todos os tags JSP, h uma sintaxe XML alternativa para esta diretiva;
<jsp:directive.include file=URLlocal %>
O valor do atributo file da diretiva include pode especificar um URL absoluto ou
relativo.
O container JSP recompila uma pgina JSP quando detecta que ela foi modificada. Isto
no se aplica a um arquivo includo a uma pgina. Isto , o container JSP no controla
dependncias entre arquivos.
3.3.3 Diretiva Tag Library
Esta diretiva utilizada para notificar o container JSP que a pgina utiliza uma ou mais
bibliotecas de tags customizados (custom tag libraries). Uma biblioteca de tags uma
coleo de tags customizados que podem ser utilizados para estender a funcionalidade
do JSP. Esta funcionalidade estendida se aplica pgina que utiliza o tag customizado.
Utilizando esta diretiva podemos indicar, por exemplo, que uma pgina JSP ir utilizar
uma determinada biblioteca de tags. A partir deste momento todos os tags existentes
nesta biblioteca se tornam disponveis para uso na pgina.
<%@ taglib uri=tagLibraryURI prefix=tagPrefix %>
ou a variao XML
<jsp:directive.taglib uri=tagLibraryURI prefix=tagPrefix />
Em ambas as sintaxes, o valor do atributo uri indica o local do arquivo Tag Library
Descriptor (TLD) para a biblioteca, e o atributo prefix especifica o identificador do
namespace XML que ser pr-adicionado a todas as ocorrncias dos tags da biblioteca na
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 24
pgina. Por exemplo, a seguinte diretiva carrega uma biblioteca de tags cujo TLD
acessvel atravs do URI local /EncomTags:
<%@ taglib uri=EncomTags prefix=mcp %>
Dentro da pgina na qual esta diretiva aparece, os tags definidos por esta biblioteca so
acessados utilizando o prefixo mcp. Um tag desta biblioteca denominado endProgram,
ento, seria referenciado dentro da pgina como <mcp:endProgram/>. Note que todos
os tags customizados seguem a sintaxe XML.
Como o prefixo especificado externamente biblioteca (em cada pgina), vrias
bibliotecas podem ser carregadas em uma nica pgina sem o risco de ocorrerem
conflitos entre os nomes dos tags. Se duas bibliotecas definem tags com o mesmo
nome, uma pgina JSP ainda assim capaz de carrega e utilizar ambas as bibliotecas j
que os tags podem ser identificados pelo prefixo especificado para a biblioteca.
Por razes de segurana, a especificao JSP determina que containers JSP podem ler
apenas TDLs armazenadas no servidor local.
3.4 Elementos de Script
Elementos de script permitem que os desenvolvedores insiram cdigo diretamente em
uma pgina JSP, inclusive cdigo capaz de gerar sada que enviada de volta ao
usurio.
JSP prov trs tipos de elementos de script: declaraes, expresses e scriptlets. E
nenhum dos tags para elementos de script suportam atributos.
3.4.1 Declaraes
Declaraes so utilizadas para definir variveis e mtodos especficos de uma pgina
JSP.
Declaraes de Variveis
Variveis definidas como declaraes se tornam variveis de instncia da classe servlet
na qual a pgina JSP ser traduzida e compilada. Exemplo:
<%! private int x = 0, y = 0; private String unidade = metros; %>
Esta declarao ter o efeito de criar 3 variveis de instncia no servlet criado para a
pgina JSP. Estas variveis podem ser referenciadas por quaisquer elementos de script
na pgina, incluindo aqueles que aparecem antes da declarao destas variveis.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 25
Quando variveis de instncia JSP so declaradas, importante ter em mente que
vrias threads podero acessar simultaneamente estas variveis. Se um elemento de
script em uma pgina modifica o valor de uma varivel de instncia, todas as
referncias subsequentes a esta varivel de instncia utilizaro o novo valor, inclusive
referncias em outras threads. Se voc deseja criar uma varivel cujo valor local ao
processamento de uma nica requisio, isto deve ser feito em um scriptlet. Variveis
declaradas so associadas pgina (atravs da classe servlet), e no a requisies
individuais.
Para definir uma varivel de classe, isto , uma varivel esttica (variveis cujos
valores so compartilhados entre todas as instncias de uma classe), faa:
<%! static public int contador = 0; %>
Na prtica, como o container JSP geralmente cria apenas uma instncia da classe
servlet representando uma pgina JSP em particular, h pouca diferena entre se
declarar uma varivel de classe e uma varivel de instncia. A principal exceo a esta
regra quando a pgina JSP designa o valor false ao atributo isThreadSafe da
diretiva de pgina, indicando que a pgina no a prova de threads. Neste caso o
container pode criar vrias instncias da classe servlet da pgina, para poder tratar
requisies simultneas (uma requisio por instncia). Para compartilhar uma varivel
entre estas vrias instncias esta varivel necessita ser declarada como esttica.
Declaraes de Mtodos
Mtodos definidos atravs de declaraes se tornam mtodos da classe servlet na qual
a pgina JSP ser compilada. Por exemplo, a seguinte declarao define um mtodo
para calcular fatoriais:
<%! public long fatorial (long x)
{ if (x == 0) return 1;
else return x * fatorial (x-1);
} %>
Este mtodo pode ser referenciado por quaisquer elementos de script na pgina,
incluindo aqueles que aparecem antes da declarao do mtodo.
Vrios mtodos e variveis podem aparecer dentro de um nico tag de declarao,
conforme vem abaixo:
<%! static public int contador = 0;
public long fatorial (long x)
{ if (x == 0) return 1;
else return x * fatorial (x-1);
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 26
static public double varlor = 0;
public int ...
{ ...
}
%>
Assim como existem variveis de classe, h tambm os mtodos de classe. So
mtodos estticos que no podem referenciar variveis de instncias, mas apenas
variveis de classe. Na prtica, como geralmente no possvel obter o nome da classe
servlet correspondente a uma pgina JSP particular, mtodos de classe no so
utilizados em pginas JSP.
Tratando Eventos do Ciclo de Vida
Um evento de inicializao de uma pgina JSP ocorre na primeira vez que um
container recebe uma requisio para esta pgina. E um evento de destruio da pgina
ocorre quando o container JSP est sofrendo um shutdown ou quando a pgina
retirada da memria por no ter sido utilizada recentemente.
O evento de inicializao tratado atravs da declarao de um mtodo especial que
ser automaticamente chamado pelo container JSP quando o evento correspondente
ocorrer. O evento de inicializao tratado pelo mtodo denominado jspInit() e o
de destruio tratado pelo mtodo denominado jspDestroy(). Exemplos:
<%! public void jspInit()
{ // Cdigo de inicializao aparece aqui!
}
public void jspDestroy()
{ // Cdigo de destruio aparece aqui!
}
%>
Um exemplo de utilizao do mtodo jspInit() seria a criao de um pool de
conexes de banco de dados antes que uma requisio possa ser atendida.
<%! private static PoolDeConexoes pool = null;
public void jspInit()
{ try
{ pool = new PoolDeConexoes
("jdbc:oracle:thin:@sbd:1521:orcl",
"java01", "java01",
"oracle.jdbc.driver.OracleDriver", 5, 1);
}
catch (Exception e)
{ throw new UnavailableException
(this, "No foi capaz de criar o pool!!!");
}
} %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 27
Observao: o mtodo construtor da classe PoolDeConexoes reutiliza um pool de
conexes existente ou, se necessrio, cria um.
Da mesma forma, se o mtodo jspDestroy for definido, ele ser chamado aps todas
as requisies pendentes terem sido processadas, mas logo antes do container JSP
retirar de servio o servlet correspondente.
<%! public void jspDestroy()
{ pool.destroiConexoes();
} %>
Se esta pgina a nica pgina a utilizar o pool, o pool pode encerrar as conexes pois
elas no so mais necessrias.
3.4.2 Expresses
Declaraes so utilizadas para adicionar variveis e mtodos a pginas JSP, mas no
so capazes de contribuir diretamente para a gerao de contedo dinmico de uma
pgina. Para este fim deve-se utilizar o elemento JSP denominado expression.
<%= expresso %>
ou a variao XML:
<jsp:expression> expresso </jsp:expression>
O efeito deste elemento avaliar a expresso especificada e substituir o valor
resultante na sada da pgina, no exato local do elemento.
Por exemplo:
<%= fatorial(12) %>
Esta expresso resultaria na sua substituio pelo nmero 479001600.
Considerando que elementos de script produzem sada apenas atravs de expresses, e
no atravs de comandos, como condicionar uma sada de uma pgina JSP? Atravs do
operador abaixo:
<%= (horas < 12) ? AM : PM %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 28
3.4.3 Scriptlets
Declaraes e expresses so intencionalmente limitadas no tipo de cdigo script que
elas suportam. Scriptlets podem conter quaisquer comandos de linguagem, e no
adicionam automaticamente contedo sada de uma pgina JSP.
A seguir vem um exemplo de scriptlet:
<% GameGrid grid = GameGrid.getGameGrid();
Recognizer r1 = new Recognizer (new Coordinates(grid, 0, 0));
Recognizer r2 = new Recognizer (new Coordinates(grid, 100, 100));
r1.findProgram(Flynn);
r2.findProgram(Flynn); %>
Este scriptlet instancia um objeto que utilizado para instanciar dois outros objetos.
Mtodos so ento chamados sobre estes objetos para efetuar alguns clculos.
Note que este scriptlet ser executado para cada requisio recebida por uma pgina.
No exemplo acima duas novas instncias da classe Recognizer sero criadas toda vez
que a pgina JSP que contm este scriptlet requisitada. importante saber ainda que,
quaisquer variveis introduzidas em um scriptlet ficam disponveis para uso em
scriptlets subsequentes e expresses na mesma pgina (sujeitas a regras de escopo de
variveis). O scriptlet acima, por exemplo, poderia ser seguido da expresso:
<%= r1.statusReport() %>
Esta expresso inseriria o resultado do mtodo statusReport() na sada da pgina.
Para se controlar o escopo de uma varivel introduzida em um scriptlet, pode-se
utilizar blocos de cdigo. Um bloco pode englobar mais de um scriptlet, conforme vem
no exemplo abaixo:
<html>
<body>
<h1>Alerta de Intruso</h1>
<p>Entrada no autorizada, disparar recognizers...</p>
<% GameGrid grid = GameGrid.getGameGrid();
{ Recognizer r1 = new Recognizer (new Coordinates(grid, 0, 0));
Recognizer r2 = new Recognizer (new Coordinates(grid, 100, 100));
r1.findProgram(Flynn);
r2.findProgram(Flynn); %>
<h2>Status</h2>
<ul>
<li>First Recognizer: <%= r1.statusReport() %>
<li>second Recognizer: <%= r2.statusReport() %>
</ul>
<% } %>
Nvel de Alerta:<%= grid.alertLevel() %>
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 29
Neste exemplo, o primeiro scriptlet introduz um novo bloco de programa antes de criar
duas instancias de Recognizer.
O segundo scriptlet, no final da pgina, fecha este bloco. Dentro deste bloco, as
instncias r1 e r2 podem ser referenciadas livremente. Aps o bloco ser fechado, no
podem mais ser referenciadas, pois seu escopo delimitado pelo bloco no qual foram
declaradas. J a varivel grid, que foi definida fora do bloco, no sofre esta limitao.
A razo para isto funcionar tem a ver como o contedo de uma pgina JSP traduzido
no cdigo fonte de um servlet. Contedo esttico, tal como cdigo HTML, traduzido
em comandos Java que imprimem o texto como sada do servlet. Da mesma forma,
expresses so traduzidas em comandos Java que avaliam a expresso, convertem o
resultado em um string, e imprimem este string como sada do servlet. Scriptlets, no
entanto, no passam por qualquer traduo, e so simplesmente inseridos no cdigo
fonte do servlet.
Comandos Java correspondentes a contedo esttico de pginas JSP, expresses e
scriptlets so utilizados para criar o mtodo _jspService() do servlet correspondente.
Este mtodo responsvel por gerar a sada da pgina JSP. Diretivas e declaraes
tambm so traduzidas em cdigo servlet mas no contribuem com o mtodo
_jspService() e no so afetados pelo escopo determinado por scriptlets. Por outro
lado, os tags JSP de acesso a Beans, discutidos no captulo 5, so traduzidos em
comandos Java para o mtodo _jspService() e esto sujeitos s restries de escopo
introduzidas por scriptlets.
3.5 Fluxo de Controle
A possibilidade dos scriptlets introduzirem blocos de comandos sem fech-los pode ser
utilizada para afetar o fluxo do controle atravs de vrios elementos, estticos ou
dinmicos, que controlam a sada gerada pela pgina.
3.5.1 Condies
O comando if pode ser utilizado para gerar contedo condicional em uma pgina JSP.
Exemplo:
<% if(x < 0) { %>
<p> No possvel calcular o fatorial de um nmero negativo.</p>
<% } else if(x > 20) { %>
<p> Argumentos maiores do que 20 causam um erro de overflow.</p>
<% } else { %>
<p align=center><%= x %>! = <%=fatorial(x) %></p>
<% } %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 30
3.5.2 Iterao
Java possui trs comandos diferentes para controlar a execuo de loops: for loop,
while loop e o comando do/while. Todos podem ser utilizados atravs de scriptlets
para adicionar iterativamente contedo a uma pgina JSP, e so particularmente teis
na exibio de dados tabulares. A seguir vem um exemplo de um fragmento de cdigo
que utiliza o mtodo fatorial definido anteriormente para construir uma tabela de
fatoriais de um nmero.
<html>
<body>
<%! public long fatorial (long x)
{ if (x == 0) return 1;
else return x * fatorial (x-1);
} %>
<table>
<tr><th><i>x</i></th><th><i>x</i>! </th></tr>
<% for (long x = 1; x <= 20; x++)
{ %> <tr><td><%= x %></td><td><%= fatorial(x) %></td></tr>
<% } %>
</table>
</body>
</html>
HTML esttico utilizado para criar a tabela e os seus headers, enquanto um for loop
utilizado para gerar o contedo da tabela. O resultado gerado ser:
x x!
1 1
2 2
3 6
4 24
5 120
6 720
7 5040
8 40320
9 362880
10 3628800
11 39916800
12 479001600
13 6227020800
14 87178291200
15 1307674368000
16 20922789888000
17 355687428096000
18 6402373705728000
19 121645100408832000
20 2432902008176640000
Um outro uso comum de iterao em scriptlets o loop atravs de um cursor que
retorna um resultado de uma consulta a um banco de dados.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 31
3.5.3 Tratamento de excees
O comportamento default quando uma exceo gerada durante o processamento de
uma pgina JSP a exibio de uma mensagem de erro especfica da implementao,
na janela do browser. Neste captulo tambm vimos como o atributo errorPage da
diretiva de pgina pode ser utilizado para especificar uma pgina alternativa para o
tratamento de erros no capturados, gerados por uma pgina JSP. Uma terceira opo
permite um controle mais apurado sobre os erros atravs da incorporao do
mecanismo de tratamento de excees da linguagem Java em uma pgina JSP
utilizando scriptlets.
Se um bloco de cdigo possui o potencial de gerar um erro, conveniente capturar este
erro e gerar uma mensagem de erro adequada. Exemplo:
<html>
<body>
<%! public long fatorial (long x) throws IllegalArgumentException
{ if ((x < 0) || (x > 20))
throw new IllegalArgumentException (Fora dos Limites.);
else if (x == 0) return 1;
else return x * fatorial (x-1);
} %>
<table>
<tr><th><i>x</i></th><th><i>x</i>! </th></tr>
<% for (long x = 1; x <= 201; x++)
{ %> <tr><td><%= x %></td><td><%= fatorial(x) %></td></tr>
<% } %>
</table>
</body>
</html>
Utilizando esta verso do mtodo poderamos considerar uma implementao
alternativa do exemplo acima:
<html>
<body>
<%! public long fatorial (long x) throws IllegalArgumentException
{ if ((x < 0) || (x > 20))
throw new IllegalArgumentException (Fora dos Limites.);
else if (x == 0) return 1;
else return x * fatorial (x-1);
} %>
<h1>Fatorial</h1>
<%! private int x = 24; %>
<% try
{ %> <p align=center> <%= x %>! = <%= fatorial(x) %></p>
<% } catch (IllegalArgumentException e) { %>
<p>Fatorial fora dos limites.</p>
<% } %>
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 32
A razo da exceo IllegalArgumentException ser gerada porque valores inteiros
do tipo long (em Java) esto limitados a 64 bits. E vinte o maior nmero cujo fatorial
pode ser armazenado em um long. Note que toda a sada gerada at o momento da
chamada ao mtodo fatorial aparece na pgina. Isto ocorre porque o cdigo do servlet
que produz esta sada no gera nenhuma exceo, e portanto executado quando a
pgina processada. Assim que a chamada a fatorial() ocorre, no entanto, a
exceo gerada e o controle transferido ao bloco catch, que imprime a mensagem
de erro.
Alm das bibliotecas de tags customizados (custom tag libraries), scriptlets que fazem
uso de blocos so a nica forma de se implementar em uma pgina JSP contedo
condicional, iterativo, ou de se utilizar tratamento de exceo customizado. Por outro
lado, o uso excessivo de scriptlets pode acarretar problemas de manuteno.
3.6 Comentrios
H comentrios que so transmitidos para o browser como parte da resposta JSP e
aqueles que so visveis apenas no arquivo JSP original.
3.6.1 Comentrios de Contedo
Para escrever um comentrio que ser includo na sada de uma pgina JSP, utilize a
seguinte sintaxe:
<!-- comentrio -->
Estes comentrios so enviados para o usurio como parte da resposta. Como so
comentrios, no produzem nenhuma sada visvel, mas podem ser vistos pelo usurio
final atravs dos itens de menu Exibir / Cdigo fonte do browser.
3.6.2 Comentrios JSP
Comentrios JSP so independentes do tipo de contedo sendo produzido pela pgina.
Tambm so independestes da linguagem de script que est sendo utilizada. Sintaxe:
<%-- comentrios --%>
O corpo deste comentrio ignorado pelo container JSP. Quando a pgina compilada
em um servlet, qualquer coisa que aparece entre estes delimitadores ignorada.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 33
3.6.3 Comentrios da Linguagem de Script
E finalmente, comentrios tambm podem ser introduzidos em uma pgina JSP dentro
de scriptlets utilizando a sintaxe de comentrio nativa da linguagem de script que
estiver sendo utilizada.
Em Java a sintaxe utilizada para a produo de comentrios a seguinte:
// comentrio em uma nica linha
/* Comentrio abrangendo
mais de uma linha */
Exemplo de utilizao de comentrios em scriptlets:
<%= /* Comentrio antes de uma expresso */ fatorial(5) %>
<%= fatorial(5) /* Comentrio aps uma expresso */ %>
<%= fatorial(5 /* Comentrio dentro de uma expresso */ ) %>
<% long numeroValido = fatorial(5); // Isto vai funcionar
long overflow = fatorial(25); // Isto no vai
%>
Evite o estilo de comentrio abaixo. Dependendo da implementao do container JSP
poder no funcionar:
O fatorial de 3 <%= fatorial(3); //Isto pode no funcionar %>, certo?
Nestes casos utilize os delimitadores /* ... */
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 34
4. OBJETOS IMPLCITOS E AES
Trs tipos de tags foram introduzidos no captulo 3: diretivas, elementos de script e
comentrios. O ltimo tipo, Aes (Actions), sero introduzidos neste captulo. Aes
encapsulam comportamento comum, em simples tags que podem ser utilizados em
qualquer pgina JSP. Aes so a base para a existncia dos tags customizados, mas
uma srie de aes (actions) fazem parte da especificao bsica de JSP. Estas aes
padro so suportadas por todos os containers JSP.
Antes de estudarmos as aes padro, vamos primeiramente examinar um conjunto de
objetos Java que o container JSP torna disponvel para os desenvolvedores de pginas
JSP.
4.1 Objetos Implcitos
O container JSP disponibiliza, para os desenvolvedores, uma srie de objetos
implcitos que podem ser utilizados no desenvolvimento de pginas JSP. Estes objetos
so denominados implcitos pois sua disponibilidade em uma pgina JSP automtica.
Estes objetos podem ser acessados pelos desenvolvedores atravs de elementos de
script. Mais especificamente, podem ser utilizados nomes especficos de variveis que
permitem o acesso a estes objetos.
A tabela abaixo relaciona todos os objetos implcitos que podem ser utilizados em uma
pgina JSP.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 35
Os nove objetos implcitos fornecidos por JSP pertencem a uma das seguintes
categorias:
Objetos relacionados ao servlet decorrente da pgina JSP;
Objetos utilizados na entrada e sada de dados;
Objetos que fornecem informaes sobre o contexto no qual cada pgina JSP est
sendo processada.
Objetos resultantes de erros.
Alm desta categorizao funcional, os objetos request, session, application e
pageContext so capazes de armazenar e recuperar valores arbitrrios de atributos.
Os mtodos padro para o gerenciamento de atributos fornecidos pelas classes e
interfaces destes quatro objetos so relacionados na tabela abaixo:
4.1.1 Objetos Relacionados a Servlets
O Objeto Page
O objeto page representa a prpria pgina JSP ou, mais especificamente, uma instncia
da classe servlet na qual a pgina ser traduzida. Logo, o objeto page pode ser
utilizado para se chamar qualquer dos mtodos definidos para aquela classe servlet. O
atributo extends da diretiva de pgina pode ser utilizado para especificar a classe do
servlet explicitamente, caso contrrio uma classe especfica de implementao ser
utilizada pelo container JSP na construo do servlet. Em ambos os casos, a classe
servlet sempre implementa a interface javax.servlet.jsp.JspPage. Nos casos
especficos de aplicaes JSP para a web, construdas com HTTP, a classe servlet deve
implementar a interface javax.servlet.jsp.HttpJspPage.
Na prtica, o objeto page raramente utilizado quando a linguagem de script Java,
pois o objeto page representado pela varivel this.
Abaixo vem um fragmento de cdigo que exemplifica a utilizao deste objeto
implcito:
<%@ page info=Demosntrao do objeto implcito page. %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 36
Page info: <%= ((javax.servlet.jsp.HttpJspPage)page).getServletInfo() %>
Esta expresso ir inserir, na sada gerada pela pgina, o valor do string de
documentao desta pgina.
Como a classe servlet varia de uma pgina para outra, o tipo padro do objeto page
object. Logo, para se poder acessar mtodos definidos na interface
javax.servlet.jsp.HttpJspPage o objeto page deve primeiramente sofrer um cast.
O Objeto Config
O objeto config armazena dados de configurao do servlet na forma de parmetros
de inicializao no qual a pgina JSP compilada. Como pginas JSP raramente
interagem com parmetros de inicializao, este objeto implcito raramente utilizado
na prtica. Este objeto uma instncia da interface javax.servlet.ServletConfig.
O cdigo abaixo mostra um exemplo de utilizao do objeto implcito config.
<%! private static PoolDeConexoes pool = null;
public void jspInit()
{ try
{ if pool == null
{ String usuario = config.getInitParameter(usuario);
String senha = config.getInitParameter(senha);
pool = new PoolDeConexoes
("jdbc:oracle:thin:@sbd:1521:orcl",
usuario, senha,
"oracle.jdbc.driver.OracleDriver", 5, 1);
}
catch (Exception e)
{ throw new UnavailableException
(this, "No foi capaz de criar o pool!!!");
}
} %>
Neste caso, em vez de armazenar o nome do usurio e a password diretamente no
cdigo da pgina JSP, estas informaes foram fornecidas atravs de parmetros de
inicializao e so acessadas atravs do objeto config.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 37
4.1.2 Entrada e Sada
O objeto request representa os dados enviados a uma pgina JSP, e o objeto
response representa o resultado enviado ao usurio. O objeto implcito out representa
o stream de sada associado ao objeto response, no qual o contedo da pgina escrito.
O Objeto Request
O objeto request representa a requisio que disparou o processamento da pgina
corrente. Para requisies HTTP, este objeto prov acesso a todas as informaes
associadas requisio, como sua fonte, o URL requisitado, e quaisquer headers,
cookies ou parmetros associados requisio. O objeto request deve implementar a
interface javax.servlet.ServletRequest. Quando o protocolo utilizado HTTP, o
objeto request deve implementar uma subclasse desta interface,
javax.servlet.http.HttpServletRequest.
O objeto request um dos quatro objetos implcitos JSP que suportam atributos,
atravs dos mtodos apresentados na tabela abaixo:
A interface HttpServletRequest tambm inclui mtodos para a recuperao de
parmetros de requisio e cabealhos HTTP. Veja tabelas abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 38
Outros mtodos freqentemente utilizados desta interface encontram-se listados na
tabela abaixo:
Entre os usos mais comuns do objeto request est a procura de valores de parmetros
e cookies.
Abaixo vem um fragmento de cdigo que ilustra o uso do objeto request para acessar
um valor de parmetro:
<% String xStr = request.getParameter(num);
try
{ long x = Long.parseLong(xStr); %>
Resultado: <%= x %>! = <%= fatorial(x) %>
<% } catch (NumberFormatException e)
{ %> String ivlido. Informe um nmero.
<% } %>
O valor do parmetro num recuperado do objeto request. Note que todos os valores
de parmetros so armazenados como strings, logo preciso efetuar uma converso
antes de se poder utilizar este valor como um nmero.
O Objeto Response
O objeto response representa a resposta que ser enviada de volta ao usurio como
resultado do processamento de uma pgina JSP. Este objeto implementa a interface
javax.servlet.ServletResponse. Como ele representa uma resposta HTTP, ele
tambm implementa uma subclasse desta interface,
javax.servlet.http.HttpServletResponse. Os mtodos principais desta ltima
interface encontram-se relacionados nas tabelas abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 39
Abaixo vem um exemplo de um scriptlet que designa, atravs do objeto response,
vrios headers que impedem que o browser faa o cache desta pgina JSP.
<% response.setDateHeader(Expires, 0);
response.setHeader(Pragma, no-cache);
if (request.getProtocol().equals(HTTP/1.1))
{ response.setHeader(Cache-Control, no-cache);
}
%>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 40
O scriptlet primeiramente informa que a data de expirao da pgina uma data no
passado. Isto indica que ao browser que o contedo da pgina j expirou, logo seu
contedo no deveria sofrer cache.
O mtodo setDateHeader deve receber como data de expirao da pgina um objeto
do tipo java.util.Date. E o zero informado representa a meia noite de 31 de
dezembro de 1969.
A verso 1.0 do protocolo HTTP 1.0 utiliza o header Pragma com valor no-cache para
indicar que a pgina no deve sofrer cache. J a verso 1.1 do protocolo HTTP
substituiu o header Pragma pelo header Cache-Control (mais especfico para controle
de cache), mas recomenda a incluso do header Pragma por questes de
compatibilidade com o passado. Logo, se a requisio indicar que o browser (ou
servidor proxy) suporta HTTP 1.1, ambos os headers so enviados.
O Objeto Out
Este objeto implcito representa o stream de sada para a pgina. O contedo deste
output stream enviado ao browser como o corpo (body) da resposta.
Utilizando este objeto implcito, sada pode ser gerada de dentro do corpo de um
scriptlet, sem a necessidade de se fechar temporariamente o scriptlet para se inserir
contedo esttico ou expresses JSP.
<p> Gerando os nmeros de 1 a 10.</p>
<% int contador = 0;
while (contador < 10)
{ contador++;
out.println(contador + "<BR>");
}
%>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 41
A tabela abaixo apresenta uma srie de mtodos que podem ser utilizados para
controlar o buffer de sada, e gerenciar o seu relacionamento com o stream de sada
que envia contedo de volta ao browser.
Segue abaixo um fragmento de cdigo que utiliza o objeto out para exibir o status do
buffer:
<% int total = out.getBufferSize();
int disponivel = out.getRemaining();
int utilizado = total - disponivel;
%>
Status do buffer:
<%= utilizado %>/<%= total %> = <%= (100.0 * utilizado)/total %>%
Esta uma forma de se descobrir o tamanho do buffer necessrio para se gerar uma
pgina.
Os mtodos fornecidos para limpar o contedo do buffer so bastante teis. Em
algumas situaes, quando um erro detectado necessrio escrever novamente a
pgina que deve ser encaminhada ao usurio. Veja o exemplo abaixo:
<html>
<body>
<p>Exemplo para calcular o fatorial de um nmero.</p>
<% out.flush(); // Para enviar tudo o que foi gerado at o momento
%>
<%! public long fatorial (long x) throws IllegalArgumentException
{ if ((x < 0) || (x > 20))
throw new IllegalArgumentException ("Fora dos Limites.");
else if (x == 0) return 1;
else return x * fatorial (x-1);
}
%>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 42
<% String xStr = request.getParameter("num");
try
{ long x = Long.parseLong(xStr); %>
Resultado: <%= x %>! = <%= fatorial(x) %>
<% }
catch (NumberFormatException e)
{ %> // No preciso chamar out.clearBuffer() aqui pois nenhum
// contedo foi gerado.
String ivlido. Informe um nmero.
<% }
catch (IllegalArgumentException e)
{ out.clearBuffer();
%>
Fatorial fora dos limites.
<% } %>
</body>
</html>
Lembre-se, no entanto, que uma vez enviado algum contedo ao usurio no mais
possvel modificar o header de resposta j encaminhado.
4.1.3 Objetos Contextuais
O Objeto Session
Este objeto implcito JSP representa uma sesso do usurio corrente. Uma sesso de
um usurio corresponde a uma srie de interaes do usurio com o servidor web. No
entanto, se um certo intervalo de tempo decorre sem que novas requisies do usurio
sejam encaminhadas ao servidor, a sesso expira.
O objeto session armazena informaes sobre a sesso. Dados especficos da
aplicao so adicionados ao objeto session atravs de atributos, utilizando-se os
mtodos da tabela abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 43
E informaes sobre a sesso podem ser obtidas atravs dos mtodos constantes da
tabela abaixo:
Um dos usos mais importantes do objeto session o armazenamento e a recuperao
de valores de atributos, com o objetivo de transmitir informaes especficas do
usurio entre pginas. A seguir vem um scriptlet que armazena dados em um objeto
session na forma de um objeto hipottico denominado dadosUsuario.
<% LoginUsuario dadosUsuario = new LoginUsuario (nome, senha);
session.setAtribute (login, dadosUsuario); %>
Aps este scriptlet ter sido utilizado para armazenar dados atravs do mtodo
setAtribute(), um outro elemento de script, na mesma ou em outra pgina JSP,
posteriormente visitada pelo usurio poder acessar os mesmos dados da sesso
utilizando o mtodo getAttribute(), conforme vem abaixo:
<% LoginUsuario dadosUsuario =
(LoginUsuario) session.getAttribute(login);
if (dadosUsuario.pertenceAoGrupo(admin))
{ session.setMaxInactiveInterval(60 * 60 * 8); // oito horas
}
else
{ session.setMaxInactiveInterval(60 * 15); // 15 minutos
}
%>
Observe que quando este scriptlet recupera o dado armazenado no objeto sesso
necessrio efetuar a operao de cast, pois o tipo utilizado para valores de atributos
java.lang.Object, que o tipo retornado pelo mtodo getAttribute().
JSP prov um mecanismo que permite que objetos sejam notificados quando so
adicionados ou removidos de uma sesso do usurio. Em particular, se um objeto
armazenado em uma sesso e sua classe implementa a interface
javax.servlet.http.HttpSessionBindingListener, ento certos mtodos
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 44
definidos na interface sero chamados sempre que ocorrerem eventos relacionados
com a sesso.
E finalmente deve ser mencionado que, diferentemente da maioria dos outros objetos
implcitos JSP que podem ser acessados sempre que necessrio por qualquer pgina
JSP, o uso do objeto session restrito s pginas que efetuam o gerenciamento de
sesso. E isto indicado atravs do atributo session da diretiva de pgina. O default,
no entanto, que todas as pginas participam do gerenciamento de sesso.
O Objeto Application
Este objeto implcito representa a aplicao qual a pgina JSP pertence. Ele uma
instncia da interface javax.servlet.ServletContext. Pginas JSP so agrupadas
em aplicaes de acordo com seus URLs. Containers JSP tratam o primeiro nome de
diretrio em um URL como uma aplicao. Por exemplo: http://server/games/index.jsp,
http://server/games/matrixblaster.jsp, e http://server/games/space/paranoids.jsp so
considerados parte da mesma aplicao denominada games. Alternativamente, o
controle completo sobre o agrupamento de uma aplicao pode ser obtido atravs do
uso de arquivos do tipo Web Application Descriptor.
Os mtodos da interface javax.servlet.ServletContext podem ser agrupados em
cinco categorias principais:
Mtodos para recuperar informaes de verso do container servlet. Observe que se
trata da verso do container servlet (JVM que executa os servlets) e no JSP. (Tabela
4.13)
Mtodos para acessar recursos server-side representados por nomes de arquivos e
URLs. (Tabela 4.14)
O objeto application que tambm prov suporte para log. (Tabela 4.15)
Mtodos para obter e designar valores de atributos. (Tabela 4.2)
Mtodos para prover acesso a parmetros de inicializao associados com a
aplicao como um todo (os parmetros de inicializao especficos de uma pgina
so acessados atravs do objeto config).
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 45
Do ponto de vista do desenvolvedor os mtodos mais teis so aqueles utilizados para
associar atributos com uma aplicao. Em particular, um grupo de pginas JSP que
reside em uma mesma aplicao podem utilizar atributos de aplicao para
implementar recursos compartilhados. Considere, por exemplo, uma outra verso do
exemplo que implementa um pool de conexes de banco de dados.
<%! private static PoolDeConexoes pool = null;
public void jspInit()
{ try
{ pool = (PoolDeConexoes) application.getAttribute(dbPool);
if (pool == null)
{ String usuario = config.getInitParameter(usuario);
String senha = config.getInitParameter(senha);
pool = new PoolDeConexoes
("jdbc:oracle:thin:@sbd:1521:orcl",
usuario, senha,
"oracle.jdbc.driver.OracleDriver", 5, 1);
application.setAttribute(dbPool, pool);
}
}
catch (Exception e)
{ throw new UnavailableException
(this, "No foi capaz de criar o pool!!!");
}
}
%>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 46
Neste exemplo, o pool de conexes construdo da mesma forma, e continua a ser
armazenado em uma varivel de classe denominada pool. Antes de construir o pool de
conexes, no entanto, um atributo de aplicao checado para se verificar se o pool j
foi construdo anteriormente.
A diferena mais significativa que podemos, desta forma, ter um pool de conexes
para cada aplicao. Parmetros de inicializao associados com a aplicao podem ser
acessados por qualquer pgina JSP da aplicao. Estes parmetros devem ser
especificados atravs do arquivo Web Application Descriptor.
A utilizao de parmetros de inicializao de aplicao permite que este cdigo seja
reutilizado por vrias pginas de uma mesma aplicao, sem a necessidade de se
especificar parmetros de inicializao vrias vezes (parmetros de inicializao
associados ao objeto config devem ser especificados em cada pgina). Este reuso pode
ser facilitado atravs da diretiva JSP include, e garante que o pool de conexes ser
criado uma nica vez, por aplicao, e compartilhado entre as diversas pginas.
O Objeto PageContext
O objeto pageContext prov, atravs de cdigo de programao, acesso a todos os
outros objetos implcitos. Para os objetos implcitos que suportam atributos, o objeto
pageContext tambm prov mtodos para acessar estes atributos. O objeto
pageContext implementa mtodos para a transferncia do controle da pgina corrente
para outra pgina, temporariamente para gerar sada a ser includa na sada da pgina
corrente, ou permanentemente para transferir o controle.
O objeto pageContext uma instncia da classe javax.servlet.jspPageContext.
Os principais mtodos desta classe pertencem a 4 grupos principais:
Um conjunto de mtodos para programaticamente acessar todos os outros objetos JSP
implcitos. (Tabela 4.16) No momento estes mtodos no so muito teis uma vez que
podemos acessar estes objetos (em scriptlets) atravs de variveis de script. No
entanto, vamos descobrir sua utilidade quando estudarmos como os tags customizados
so implementados.
O segundo grupo de mtodos permite que pginas JSP despachem requisies de uma
pgina JSP para outra. (Tabela 4.17) Maiores detalhes sobre esta funcionalidade sero
estudados quando estudarmos as aes <jsp:forward> e <jsp:include>.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 47
E os dois outros grupos de mtodos lidam com atributos. A classe qual pertence o
objeto implcito pageContext implementa todos os mtodos de acesso a atributos
relacionados na tabela da pg 35. E para permitir que os atributos de outros objetos
implcitos JSP tambm possam ser acessados programaticamente, a classe
javax.servlet.jspPageContext prov uma srie de mtodos relacionados abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 48
Como j foi mencionado anteriormente, quatro diferentes objetos implcitos so
capazes de armazenar atributos: o objeto pageContext, o objeto request, o objeto
session e o objeto application. Como resultado desta habilidade, estes objetos so
tambm referenciados como scopes, pois a longevidade de um valor de atributo varia
em funo de qual dos quatro objetos foi utilizado para armazenar o valor do atributo.
Atributos de pgina armazenados no objeto pageContext, duram apenas enquanto
durar o processamento de uma nica pgina. Atributos de requisio tambm possuem
vida curta, mas podem ser passados entre pginas a medida que o controle
transferido. Atributos de sesso persistem enquanto o usurio estiver interagindo com
o servidor web. E os atributos de aplicao persistem enquanto o container JSP
mantm uma ou mais pginas de uma aplicao carregadas na memria.
Apenas uma nica thread dentro de um container JSP pode acessar atributos
armazenados nos escopos de pgina ou requisio: a thread que manipula o
processamento da requisio associada.
A preocupao se uma aplicao thread safe, ento, maior quando atributos de
sesso e de aplicaes so utilizados. Como vrias requisies para uma pgina de uma
aplicao sero tratadas simultaneamente, objetos armazenados com o escopo de
aplicao devem ser robustos com respeito ao acesso por estas mltiplas threads. Da
mesma forma, como um usurio pode ter vrias janelas de browser abertas, todas
acessando uma mesma pgina JSP ao mesmo tempo, tambm deve ser assumido que
objetos armazenados com o escopo de sesso podem ser acessados por mais de uma
thread de cada vez.
Alm dos mtodos relacionados na tabela acima cujos parmetros incluem uma
especificao de escopo, a classe javax.servlet.jsp.PageContext prov constantes
estticas que representam estes quatro escopos.
<%@ page import=javax.servlet.jsp.PageContext %>
<% Enumeration atts =
pageContext.getAttributeNamesInScope(PageContext.SESSION_SCOPE);
while (atts.hasMoreElements())
{ %>
Session Atribute: <%= atts.nextElement() %><BR>
<% } %>
Estas constantes esto relacionadas na tabela abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 49
Os ltimos dois mtodos relacionados na ltima tabela da pg 47 permitem que
desenvolvedores procurem em todos os escopos definidos, por um atributo com
determinado nome. Em ambos os casos, o objeto pageContext ir procurar o atributo
na seguinte ordem: pgina, requisio, sesso e aplicao.
4.1.4 Tratamento de Erros
Esta ltima categoria de objetos implcitos possui apenas o objeto exception.
O Objeto Exception
Assim como o objeto session o objeto exception no se encontra automaticamente
disponvel em toda pgina JSP. Este objeto pode ser acessado apenas nas pginas que
foram designadas como pginas de erro utilizando o atributo isErrorPage da diretiva
de pgina. Nestas pginas que so pginas para tratamento de erros, o objeto
exception ser uma instncia da classe java.lang.Throwable correspondendo a um
erro no capturado que causou a transferncia do controle para a pgina de erro. Os
mtodos mais teis da classe java.lang.Throwable encontram-se na tabela abaixo:
Abaixo vem um fragmento de cdigo que demonstra o uso do objeto exception:
<%@ page isErrorPage=true %>
<H1>Aviso!</H1>
O seguinte erro foi detectado:<BR>
<% exception.printStackTrace(out); %>
4.2 Aes
Aes (Actions) JSP permitem que o controle do fluxo de execuo seja transferido de
uma pgina para outra, que pginas JSP interajam com componentes JavaBeans
residentes no servidor, e suportam a especificao de applets java de uma forma
independente do browser utilizado pelo usurio.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 50
Alm disso, todos os tags customizados definidos atravs de tag libraries possuem
a forma de Aes JSP. Diferentemente das diretivas e elementos de script, aes
suportam apenas a sintaxe baseada em XML.
4.2.1 Forward
A ao <jsp:forward> utilizada para transferir permanentemente o controle de uma
pgina JSP para outro local no mesmo servidor. Qualquer contedo gerado pela pgina
corrente descartado, e o processamento da requisio comea novamente em um
local alternativo.
<jsp:forward page=URLlocal />
O atributo page da ao <jsp:forward> utilizado para se especificar este local
alternativo para o qual o controle deve ser transferido, que pode ser um documento
html esttico, um CGI, um servlet, ou outra pgina JSP. Note que o browser no
notificado quando a requisio transferida para outro URL. O campo location no topo
da janela do browser continuar a exibir o URL que foi originalmente requisitado.
O valor do atributo page pode ser calculado em tempo de execuo. No exemplo
abaixo, por exemplo, o fluxo da execuo ser transferido para a pgina denominada
mensagem404.html, caso o valor de statuscode seja 404.
<jsp:forward page=<%= mensagem + statusCode + .html %> />
Como foi mencionado acima, a ao <jsp:forward> pode transferir o controle para
qualquer outro documento no mesmo servidor. Quando o controle transferido para
outra pgina JSP, o container JSP ir automaticamente designar um novo objeto
pageContext para esta nova pgina. O objeto session e o objeto request, no entanto,
sero os mesmos. O compartilhamento do objeto application depende se ambas as
pginas so parte da mesma aplicao ou no. Consequentemente, nem todos os
valores de atributos podem ser acessados pela pgina de destino: atributos de pgina
no so compartilhados, atributos de sesso e de requisio so compartilhados e os
atributos de aplicao talvez possam ser compartilhados.
Esta abordagem tambm pode ser utilizada para transferir dados quando se est
passando o fluxo de execuo de uma pgina JSP para um servlet.
possvel, ainda, especificar parmetros adicionais para serem enviados para a nova
pgina atravs do tag <jsp:param> dentro do corpo da ao <jsp:forward>.
<jsp:forward page=URLlocal>
<jsp:param name=nomeDoParametro1 value=valorDoParametro1 />
...
<jsp:param name=nomeDoParametroN value=valorDoParametroN />
</jsp:forward>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 51
Note que a passagem de parmetros de requisio adicionais independe do tipo de
documento para o qual o controle ser transferido.
O efeito do tag <jsp:param> quando utilizado com <jsp:forward> e <jsp:include>
de adicionar um valor a um parmetro especfico, em vez de simplesmente designar
um valor.
Isto significa que se um parmetro de requisio j possui um ou mais valores
designados por algum outro mecanismo, o tag <jsp:param> ir simplesmente
adicionar o valor especificado aos valores j existentes. Observe, no entanto, que este
novo valor ser adicionado como o primeiro valor do parmetro de requisio, logo,
chamadas subsequentes ao mtodo getParameter(), que retorna um nico valor,
retornaro os demais valores do parmetro.
Como a ao <jsp:forward> efetivamente termina o processamento da pgina
corrente em benefcio de outra pgina, este tag geralmente utilizado em comandos
condicionais.
<% if (!database.estaDisponivel())
{ %> <jsp:forward page=manutencaobd.html />
<% } %}
<%-- Se o banco est no ar, prossiga ... --%>
A ao <jsp:forward> pode, no entanto, ser utilizada para passar adiante o controle
da execuo aps utilizar o tag <jsp:param> para designar parmetros de requisio
para a outra pgina.
Quando o processamento de uma pgina JSP encontra o tag <jsp:forward> toda a
sada gerada at o momento automaticamente descartada. Isto , o buffer de sada
esvaziado. No entanto, se o buffer de sada j foi enviado antes da execuo do tag
<jsp:forward> a ao ir falhar e ser gerada a exceo IllegalStateException.
Logo, se uma pgina gera sada para o usurio antes da execuo do tag
<jsp:forward>, esteja certo que o buffer utilizado pela pgina grande o suficiente
para evitar esta exceo.
Include
A ao <jsp:include> permite que se incorpore sada de uma pgina o contedo
gerado por outro documento local. A sada do documento includo inserida na sada
gerada pela pgina original, no mesmo local do tag <jsp:include>.
A ao <jsp:include> possui a forma:
<jsp:include page=URLlocal flush=true />
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 52
No se deve inserir informaes de host e de protocolo no URL. Apenas diretrios e
arquivos.
O atributo flush da ao <jsp:include> indica se o buffer de sada da pgina
corrente deve ser enviado ao browser antes da incluso do contedo gerado pela pgina
includa. A verso 1.1 de JSP determina que deve ser utilizado o atributo flush
designado para true, indicando que o buffer enviado antes que o processamento da
pgina includa comece. Isto se deve em funo de uma limitao da API servlet.
Futuramente este requisito deve ser relaxado.
Assim como as pginas acessadas com a ao <jsp:forward>, pginas processadas
atravs do tag <jsp:include> recebero um novo objeto pageContext, mas iro
compartilhar os mesmos objetos session e request.
Tambm possvel especificar novos parmetros de requisio adicionais para o
documento includo, atravs do tag <jsp:param>, conforme vem no exemplo abaixo:
<jsp:include page=URLlocal flush=true>
<jsp:param name=nomeDoParametro1 value=valorDoParametro1 />
...
<jsp:param name=nomeDoParametroN value=valorDoParametroN />
</jsp:include>
Como o container JSP automaticamente gera e compila novos servlets para pginas
JSP que tenham sido modificadas, se o texto em um arquivo JSP includo atravs da
ao <jsp:include> modificado, as modificaes aparecero automaticamente na
sada do arquivo modificado.
Por outro lado, a diretiva JSP include, descrita no captulo anterior no atualiza
automaticamente a pgina includa quando a pgina includa modificada. Isto ocorre
porque a diretiva include levada em considerao quando a pgina traduzida em um
servlet, inserindo o contedo da pgina includa no servlet. J a ao <jsp:include>
levada em considerao no momento do processamento das requisies.
H vrias vantagens e desvantagens que devem ser levadas em considerao quando
temos que optar entre a ao <jsp:include> e a diretiva include. A ao
<jsp:include> possui os benefcios da recompilao automtica, arquivos de classe
menores e a possibilidade de se especificar parmetros de requisio adicionais, alm
de suportar o uso de valores de atributos especificados em tempo de execuo. A
diretiva include no suporta o uso de valores de atributos especificados em tempo de
execuo, permite apenas a incluso de contedo esttico ou outra pgina JSP. J a
ao <jsp:include>, no entanto, inclui a sada gerada por um URL em vez do
contedo de um documento fonte, logo, a ao <jsp:include> permite que se inclua o
contedo gerado por um servlet ou um programa CGI.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 53
Por outro lado a diretiva include oferece a opo de compartilhar variveis locais, e
possui uma melhor eficincia em tempo de execuo e no impe restries em relao
ao buffer de sada.
4.2.2 Plug-in
A ao <jsp:plugin> utilizada para gerar cdigo HTML especfico para determinado
browser com o objetivo de executar Java Applets. Este assunto, no entanto, est fora do
escopo desta apostila.
4.2.3 Bean Tags
JSP prov trs diferentes aes para a interao com server-side JavaBeans:
<jsp:useBean>, <jsp:setProperty>, e <jsp:getProperty>. Como o projeto de
aplicaes baseadas em componentes permite que a apresentao de uma aplicao
seja separada de sua lgica de implementao, os prximos dois captulos tratam da
interao entre JSP e JavaBeans.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 54
5. UTILIZANDO COMPONENTES JSP
JSP prov uma abordagem alternativa para o desenvolvimento de aplicaes. Esta
abordagem (baseada em componentes) permite que a apresentao seja separada da
lgica da aplicao.
5.1 O Modelo de Componentes JSP
O modelo de componentes JSP baseado em componentes de software denominados
JavaBeans.
5.1.1 Arquiteturas de Componentes
Pode-se pensar em um componente como uma caixa preta que executa operaes
especficas sem revelar nenhum detalhe de sua implementao. Componentes so
stand-alone e no esto conectados a nenhuma aplicao ou uso. Esta caracterstica
permite que eles sejam utilizados na construo na construo de vrios projetos,
possivelmente sem nenhuma ligao.
Os dois princpios bsicos relacionados utilizao de componentes no
desenvolvimento de aplicaes so: abstrao e reutilizabilidade.
Pense em componentes como elementos de cdigo reutilizveis que podem ser
aglutinados para construir uma nova aplicao. Um bom modelo de componentes nos
permite eliminar ou reduzir fortemente a quantidade de cdigo cola necessrio para
construir as aplicaes.
5.1.2 Benefcios da Abordagem Baseada em Componentes
Geralmente uma aplicao desenvolvida com a abordagem de componentes envolve a
combinao de componentes de propsito geral e componentes especficos da
aplicao. O principal benefcio desta abordagem a reutilizao dos componentes.
No apenas pelo compartilhamento de componentes entre diferentes aplicaes, mas
tambm atravs da reutilizao de componentes por vrios segmentos da mesma
aplicao ou de aplicaes relacionadas.
5.1.3 O Projeto de Componentes para Aplicaes Web
A abordagem baseada em componentes ideal para o projeto de aplicaes para a web.
JSP permite que os projetistas de aplicaes para a web empreguem os princpios que
outros desenvolvedores de software vm utilizando h vrios anos. Em vez de ter de
embutir uma complexa lgica de programao dentro das pginas atravs de cdigo
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 55
script, eles (projetistas) podem simplesmente empregar cdigo HTML para a
determinao de layout, em torno de componentes. Veja a figura abaixo. A habilidade
do modelo de componentes de reutilizar componentes comuns provoca a reduo do
tempo de desenvolvimento e a reduo da complexidade dos projetos.
Em alguns casos uma nica pessoa pode tratar de ambos os aspectos do projeto, mas a
medida que a complexidade aumenta, a separao das tarefas do processo de
desenvolvimento pode resultar em uma srie de benefcios.
5.2 Fundamentos de JavaBeans
JavaBeans so componentes de software escritos em Java. Os componentes so
denominados Beans e devem aderir a especificaes definidas na API JavaBeans. A
API JavaBeans foi definida pela Sun com a cooperao da indstria e determina as
regras que os desenvolvedores de software devem seguir para criar componentes de
software reutilizveis. Como muitos outros componentes de software, Beans
encapsulam estado e comportamento. Utilizando a coleo de tags JSP relacionada a
Beans, desenvolvedores de contedo podem aumentar o poder de Java para adicionar
elementos dinmicos a suas pginas sem escrever uma nica linha de cdigo Java.
Containers de Beans
Um container de beans uma aplicao, um ambiente, ou uma linguagem de
programao que permite aos desenvolvedores chamar Beans, configur-los, e acessar
suas informaes e comportamentos. Aplicaes que utilizam Beans so compostas
puramente de cdigo Java, mas containers de Beans permitem que os desenvolvedores
trabalhem com eles em um nvel conceitual mais alto.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 56
Aplicaes como o Visual Age for Java da IBM ou Visual Caf, entre outras, incluem
Bean containers que trabalham com Beans de forma visual. Assim como estas
ferramentas, containers JSP permitem que desenvolvedores criem aplicaes Java para
a web sem a necessidade de se escrever cdigo Java. Em pginas JSP possvel a
interao com Beans atravs de uma coleo de tags que podem ser embutidos em
cdigo HTML.
Propriedades dos Beans
Containers de Beans permitem que se trabalhe com Beans em termos de propriedades
denominadas atributos do Bean que mantm seu estado e controla seu comportamento.
As propriedades de um Bean podem ser modificadas em tempo de execuo. Estes
valores de propriedades so o nico mecanismo que o container do Bean utiliza para
expor os Beans para o desenvolvedor. Uma propriedade pode ser apenas de leitura, de
leitura e escrita, ou apenas de escrita. Desta forma, um projetista de um Bean pode
impor limites de como um Bean pode ser utilizado.
Gatilhos e Propriedades Relacionadas
Algumas propriedades so utilizadas para determinar um comportamento. Esta
propriedades so chamadas de trigger properties. A atividade de leitura ou de
escrita em uma trigger property pode indicar ao Bean para executar determinada
atividade. Estes triggers, uma vez ativados, podem atualizar os valores de outras
propriedades ou fazer com que algo acontea. Por exemplo, alterar o CEP de um Bean
que retorna a temperatura mxima, mnima e mdia para aquele local, provocar a
atualizao das outras propriedades relacionadas. Estas propriedades relacionadas so
conhecidas como link properties.
Propriedades Indexadas
Tambm possvel para uma nica propriedade armazenar uma coleo de valores.
Estas propriedades so conhecidas como indexed properties pois cada valor
armazenado na propriedade acessado atravs de um ndice, que especifica que valor
se deseja acessar. Nem todo container de Bean, no entanto, prov um mecanismo
simples para se trabalhar com propriedades multivaloradas. Os tags JSP para acesso a
Beans, por exemplo, no reconhecem propriedades indexadas. Para trabalhar com elas
preciso utilizar scriptlets JSP, expresses JSP, ou tags customizados.
Tipos de Dados de Propriedades
Propriedades podem armazenar qualquer tipo de dado Java, assim como objetos Java,
como Strings e Dates. Propriedades tambm podem armazenar objetos definidos
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 57
pelo usurio. E propriedades indexadas geralmente armazenam um array de valores,
todos do mesmo tipo.
O container de Beans determina como trabalhar com os valores de propriedades de um
Bean. Com scriptlets JSP e expresses deve-se referenciar valores de propriedades
atravs do seu tipo de dado Java. Se uma propriedade armazena valores inteiros obtm-
se valores inteiros dela e deve-se armazenar valores inteiros nela. Com tags Bean, no
entanto, tratamos todas as propriedades como se elas armazenasses texto, isto ,
Strings. Quando se designa um valor a uma propriedade, designa-se um texto. E
quando se l o contedo de uma propriedade obtm-se um texto. Esta estratgia torna a
utilizao de JavaBeans simples e funciona bem com HTML.
O container JSP executa todas as converses de tipo necessrias. Por exemplo, quando
se designa um valor para uma propriedade inteira, ele (container) executa todas as
chamadas Java necessrias para converter os caracteres numricos informados em um
nmero.
5.2.1 Os Diferentes Tipos de JavaBeans
Os Beans podem ser divididos em trs categorias: Beans visuais, Beans para acesso a
dados e Beans de servio.
Beans Visuais
O desenvolvimento de componentes visuais tem sido uma das utilizaes mais comuns
de JavaBeans. Como Beans visuais tm sido projetados para serem executados como
parte de uma aplicao Java grfica, eles no so compatveis com JSP, que utilizado
no desenvolvimento de aplicaes baseadas em texto, como o projeto de interface
HTML.
Beans para Acesso a Dados
Este tipo de Bean prov uma forma de se acessar dados. Eles so tipicamente read-
only. Isto , permitem que o dado seja lido, mas no atualizado.
Alguns Beans para acesso a dados (data Beans), no entanto, permitem que se designe
valores para algumas de suas propriedades para que se possa controlar como os dados
devem ser formatados ou filtrados antes de serem retornados atravs de outras
propriedades. Por exemplo, um Bean denominado ContaCorrenteStatusBean poderia
ter uma propriedade denominada formato para controlar se os valores devem ser
retornados em dlar ou reais ou francos suos. Este tipo de Bean til para se
padronizar o acesso a informaes atravs de uma interface estvel.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 58
Beans de Servio
Este tipo de Bean prov acesso a um comportamento ou a um servio particular. Eles
podem recuperar informaes de um banco de dados, efetuar clculos, ou formatar
informaes. Um Bean projetado para acessar a tabela de empregados de um banco de
dados poderia, por exemplo, ter uma propriedade denominada numeroDoEmpregado
que poderia ser designada para um nmero desejado. Esta designao dispararia uma
busca ao banco de dados e designaria valores para as propriedades do Bean nome e e-
mail.
Note que nem todos os Beans de servio coletam dados de uma fonte de dados. Alguns
simplesmente encapsulam a lgica necessria para executar clculos, converses, ou
operaes. Um Bean denominado estatisticaBean poderia, por exemplo, saber como
calcular mdias, desvio padro, etc.
Alguns Beans de servio podem no retornar nenhuma informao. Um Bean deste
tipo pode, por exemplo, armazenar informaes de log em algum banco de dados ou
arquivo de log. Beans de servio permite uma clara separao de responsabilidade. O
web designer no necessita entender de clculos estatsticos, e o programador no
necessitar entender de design. Uma modificao na apresentao ou na lgica de
programao no afeta o outro lado, supondo que a interface do Bean no
modificada.
5.3 Tags JSP para Acesso a Beans
JSP possui um conjunto de tags que permitem o acesso a Beans. Estes tags podem ser
utilizados para colocar Beans dentro de pginas HTML. Estes Beans podero, ento, ser
acessados atravs de suas propriedades. No necessrio ser um programador Java
para se projetar pginas que utilizam Beans.
5.3.1 Programao com Componentes Baseados em Tags
JSP necessita de apenas 3 tags para permitir a interao com JavaBeans. Atravs da
utilizao destes tag possvel colocar Beans dentro de uma pgina e alterar e acessar
suas propriedades.
Algumas pessoas reclamam da simplicidade do conjunto de tags JSP, preferindo a
abordagem que embute mais funcionalidade nos tags como ocorre com PHP e
ColdFusion. importante compreender que este conjunto limitado de funcionalidade
disponibilizado pelos tags JSP de acesso a Beans intencional. Os projetistas de JSP
optaram por manter o ncleo da funcionalidade bastante simples, definindo apenas
poucos tags para se trabalhar com Beans e estabelecendo uma especificao que
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 59
permite o desenvolvimento de novos tags customizados para resolver problemas
especficos.
Os tags padro permitem que se crie referncias a Beans que se necessita utilizar, a
designao de valores para propriedades configurveis, e a leitura de valores de
propriedades. Tags customizados com um nvel de funcionalidade mais complexo
podem ser criados por indivduos e organizaes e integrados em qualquer ambiente
JSP atravs de um mecanismo de extenso conhecido como bibliotecas de tags
customizados (custom tag libraries). Atravs de tags customizados a linguagem JSP
pode ser estendida para suportar construes de programao como comandos
condicionais e iteraes, assim como prover funcionalidade adicional como o acesso
direto a bancos de dados.
Um Exemplo Ilustrativo
<jsp:useBean id=user class=RegisteredUser scope=session />
<jsp:useBean id=news class=NewsReport scope=request>
<jsp:setProperty name=news property=category value=financial/>
<jsp:setProperty name=news property=maxItems value=5 />
</jsp:useBean>
<html>
<body>
Oi <jsp:getProperty name=user property=fullName />,
sua ltima visita foi em
<jsp:getProperty name=user property=lastVisitDate />.
Seja benvindo.
<p>
Existem <jsp:getProperty name=news property=newItems /> novos
artigos disponveis para voc.
</body>
</html>
Esta pgina JSP utiliza dois componentes, user e news. O primeiro nos permite dar
boas vindas ao visitante, e o segundo armazena novos itens que eles (visitantes) podem
estar interessados.
Veja abaixo como seria a aparncia desta pgina no browser:
Oi Vinicius Aguiar, sua ltima visita foi dia 17/06/2000. Seja benvindo.
Existem 4 novos artigos disponveis para voc.
5.3.2 Acessando Componentes JSP
Para interagir com um Bean, primeiramente indicamos para a pgina onde encontrar o
arquivo de classe Java que define o Bean e designa um nome para ele. Podemos ento
utilizar este nome para acessar os valores armazenados nas propriedades do Bean.
necessrio conhecer apenas 3 tags JSP para se utilizar Beans em uma pgina JSP.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 60
O Tag <jsp:useBean>
Este tag indica que desejamos tornar um Bean disponvel para a pgina JSP. O tag
utilizado para criar um Bean ou recuperar um existente no servidor. Atributos do tag
especificam o tipo de Bean que se deseja utilizar e atribui um nome ao Bean que
poder ser utilizado posteriormente para fazer referncia a ele. Este tag possui duas
formas:
<jsp:useBean id=nome do bean class=nome da classe />
ou
<jsp:useBean id=nome do bean class=nome da classe>
Cdigo de inicializao.
</jsp:useBean>
Na formato mais simples so necessrios apenas dois atributos, id e class. Como em
todos os tags JSP, os valores dos atributos devem aparecer entre aspas.
A tabela abaixo mostra todos os valores de atributos suportados pelo tag
<jsp:useBean>.
O Atributo ID
O atributo id especifica um nome para o Bean um valor nico utilizado para se
referenciar um Bean ao longo de uma pgina JSP. (Mais tarde, aprenderemos como
estender a vida de um Bean alm da pgina corrente.) Podemos utilizar vrios tags
<jsp:useBean> para definir mais de um Bean em uma pgina, ou para definir vrias
instncias de um mesmo Bean, contanto que haja um identificador nico associado a
cada Bean individual. O nome escolhido para o Bean arbitrrio, mas deve seguir as
seguintes regras:
Deve ser nico na pgina.
case sensitive.
O primeiro caracter deve ser uma letra.
Apenas letras, nmeros e underscore (_) so permitidos.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 61
O Atributo Class
O valor do atributo class especifica o nome da classe do JavaBean. Para ajudar na
organizao do cdigo e evitar conflitos, classes Java so geralmente armazenadas em
packages. A menos que o tag <%@ page> com o atributo import tenha sido utilizado
para que a pgina tenha acesso ao package do componente JavaBean, ser necessrio
especificar o nome completamente qualificado da classe deste componente.
Por conveno, packages comeam com o nome de domnio Internet do criador do
componente, e geralmente incluem mais nveis para melhor organizar as classes.
Exemplos:
com.manning.RegisteredUserBean
com.deepmagic.beans.database.logging.LogBean
Podemos incluir um Bean sem especificar seu nome completamente qualificado se
todas as classes do package forem previamente importadas.
<%@ page import=com.taglib.wdjsp.* %>
<jsp:useBean name=user class=RegisteredUserBean />
ou simplesmente ...
<jsp:useBean name=user class=com.taglib.wdjsp.RegisteredUserBean />
O Atributo Type
Na prtica este atributo no muito utilizado. O atributo class do tag <jsp:useBean>
determina que classe Java utilizada para criar o Bean. No entanto, se for necessrio
fazer referncia a um Bean, por exemplo, pela interface que ele implementa pode-se
utilizar o atributo type.
O Corpo do Tag <jsp:useBean>
Esta parte opcional do tag <jsp:useBean> pode ser utilizada para se inicializar
qualquer propriedade configurvel do Bean. Isto nos permite configurar um Bean para
uma pgina especfica ou para uma aplicao em particular. Mais tarde estudaremos os
detalhes a respeito da inicializao de Beans. Por enquanto veremos Beans que no
necessitam de nenhuma inicializao especial.
<jsp:useBean id=myclock class=com.manning.jsp.ClockBean />
<html>
<body>
H um Bean escondido nesta pgina!
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 62
O exemplo acima diz pgina que ser utilizado um Bean definido no arquivo de
classe Java ClockBean existente no package com.manning.jsp. O nome atribudo a
este Bean, nesta pgina, foi myclock. O tag <jsp:useBean> pode ser aparecer em
qualquer lugar da pgina HTML. No entanto, um Bean s pode ser acessado em uma
pgina HTML aps aparecer sua definio.
O tag <jsp:useBean> cria uma instncia do Bean e designa um id para ela. Quando
um Bean criado (instanciado) executado o construtor da classe JavaBean. A partir
deste momento possvel acessar as propriedades do bean.
Para entender melhor a diferena entre uma classe e sua instncia, observe o exemplo
abaixo:
<jsp:useBean id=clock1 class=com.manning.jsp.ClockBean />
<jsp:useBean id=clock2 class=com.manning.jsp.ClockBean />
O cdigo acima cria dois Beans completamente independentes, que podero ser
referenciados pelos seus nomes: clock1 e clock2. Eles so instncias da mesma
classe, mas qualquer modificao efetuada em um no afeta o outro. Nos exemplos
acima Beans foram definidos mas no foram utilizados.
Acessando as Propriedades de um Bean com <jsp:getProperty>
O tag <jsp:getProperty> um tag vazio, isto , sem um corpo, e possui dois
atributos: name e property.
<jsp:getProperty name=nome do Bean property=nome da propriedade />
O atributo name deve corresponder ao atributo id do tag <jsp:useBean>. O atributo
id utilizado para definir um novo objeto e o atributo name utilizado para referenciar
objetos existentes. Na pgina HTML que exibida em tempo de execuo, o tag
substitudo pelo valor da propriedade do Bean. Naturalmente, como estamos criando
um documento HTML, a propriedade convertida para texto pelo container JSP.
Exemplo:
<jsp:useBean id=myclock class=com.manning.jsp.ClockBean />
<html>
<body>
O Bean diz que agora so:
<jsp:getProperty name=myclock property=time />
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 63
O cdigo acima geraria a seguinte pgina HTML:
<html>
<body>
O Bean diz que agora so: 12:33 pm
</body>
</html>
O tag <jsp:getProperty> pode ser utilizado para gerar valores nicos, blocos de
texto, ou para controlar atributos HTML. perfeitamente vlido embutir tags JSP em
atributos HTML. Uma propriedade de um Bean poderia ser utilizada, por exemplo, para
controlar a cor de fundo de uma pgina HTML, a largura de uma tabela, ou o endereo
de uma imagem.
Por exemplo, um Bean que reflete o estilo padro de uma empresa poderia ter uma
propriedade que expe o URL da ltima verso do logotipo da empresa e o esquema de
cores da empresa. Poderamos exibir esta imagem em uma pgina HTML sem a
necessidade de informar o URL em cada pgina.
<jsp:useBean id=style class=beans.CorporateStyleBean />
<html>
<body bgcolor=<jsp:getProperty name=style property=color/>>
<center>
<img src=<jsp:getProperty name=style property=logo/>>
Benvindo UFF.
</center>
</body>
</html>
Observao:
Espaos em branco em um documento deveriam ser preservados pelo processador JSP
para os tags abaixo, por exemplo, produzissem a sada: primeiroNome ltimoNome
em vez de primeiroNomeltimoNome.
<jsp:getProperty name=usuario property=nome />
<jsp:getProperty name=usuario property=sobrenome />
Isto pode acontecer porque, alguns processadores JSP ignoram o caracter de newLine
que seria interpretado como um espao em branco. Uma alternativa para este
problema inserir uma linha de comentrio entre os dois tags. Este comentrio faz com
que o caracter de newLine seja preservado pelo processador JSP.
<jsp:getProperty name=usuario property=nome />
<!-- insere um espao -->
<jsp:getProperty name=usuario property=sobrenome />
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 64
O Tag <jsp:setProperty>
O tag <jsp:setProperty> utilizado para se modificar uma propriedade de um
Bean. Valores de propriedades de Beans so modificados para controlar o modo de
operao de um Bean ou para acessar seus servios. O comportamento exato causado
pela modificao de uma propriedade de um Bean depende de como ele foi construdo.
Por exemplo, o autor de um Bean pode prover uma propriedade query que especifica
uma query de banco de dados cujos resultados so refletidos em outras propriedades.
Neste caso, pode-se chamar <jsp:getProperty> diversas vezes para ler o resultado da
query. Este resultado seria modificado a cada mudana da propriedade query.
A maioria dos Beans de servio requerem alguma configurao em tempo de execuo.
Por exemplo, se um desenvolvedor necessita de um Bean para prover informaes a
respeito de um usurio registrado, no seria necessrio criar um tipo de Bean diferente
para cada usurio: BobBean, SueBean, etc. O projetista projetaria as propriedades do
Bean para referenciar as propriedades de qualquer usurio, e faria com que uma
propriedade do Bean fosse utilizada para se controlar qual usurio estamos
interessados.
O tag <jsp:setProperty> requer 3 atributos: name, property e value.
<jsp:setProperty name=nome do bean property=nome da propriedade
value=valor da propriedade />
Em tempo de execuo JSP avalia os tags em uma pgina na ordem em que foram
definidos, de cima para baixo. Quaisquer valores de propriedades que forem
modificados em uma pgina afetaro apenas os tags definidos abaixo.
Exemplos de modificao de uma propriedade de um Bean:
<jsp:setProperty name=user property=daysLeft value=30 />
<jsp:setProperty name=user property=daysLeft
value=<%= 15 * 2 %> />
Propriedades Indexadas
Para acessar uma propriedade indexada preciso passar ao Bean um ndice para
indicar qual valor se deseja recuperar. Propriedades indexadas no podem ser
acessadas atravs de tags JSP padro para acesso a Beans. Estas propriedades s
podem ser acessadas atravs de scriptlets JSP, expresses e tags customizados.
Exemplo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 65
<B>Previso do Tempo</B>: <%= weather.getForeCast(0) %> <BR>
<>Previso do resto da Semana</B>
<UL>
<% for (int index=1; index < 5; index++)
{ %> <LI><%= weather.getForecasts(index) %> (talvez)
<% } %>
</UL>
No exemplo acima utilizamos scriptlets JSP e expresses para acessar a propriedade
indexada forecasts, que foi carregada na pgina com o id = weather. Para exibir a
previso do tempo de amanh foi utilizada uma expresso JSP para obter o primeiro
elemento da propriedade forecasts atravs da chamada a seu mtodo de acesso,
getForecasts() com o argumento 0 (zero).
5.3.3 Inicializando Beans
Quando um Bean criado pela primeira vez ele pode ser inicializado atravs da
designao de valores a suas propriedades configurveis. Por default, esta fase de
inicializao ocorre cada vez que a pgina acessada, j que um Bean est sendo
criado para cada requisio. Como veremos mais adiante, Beans podem ser
armazenados e recuperados do ambiente do servidor web. Nestes casos eles no
necessitaro ser reinicializados.
Antes de um Bean ser criado pode ser necessrio inicializ-lo, designando os valores
de suas propriedades, antes de se tentar ler qualquer propriedade do Bean. Poderamos
simplesmente utilizar o tag <jsp:setProperty> na pgina, mas como ser visto mais
adiante, possvel para um Bean existir alm do escopo de uma nica requisio, logo
torna-se necessrio definir um bloco separado de cdigo para a inicializao do Bean.
Configurao do Bean
A verso do tag <jsp:useBean> que possui corpo, permite que um Bean seja
configurado antes de ser utilizado atravs da designao de valores de propriedades.
Exemplo:
<jsp:useBean id=myBean class=com.manning.jsp.MyBean>
<%- rea do corpo --%>
</jsp:useBean>
Quaisquer comandos dentro do corpo so processados imediatamente aps o Bean ser
instanciado e antes de ele se tornar disponvel para o resto da pgina.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 66
<jsp:useBean id=CLOCK class=com.manning.jsp.ClockBean>
<jsp:setProperty name=clock property=timezone value=CST />
</jsp:useBean>
O corpo do tag <jsp:useBean> tambm pode conter scriptlets JSP e cdigo HTML. Este
cdigo HTML ser exibido como parte da pgina apenas se o Bean for instanciado.
(Tenha o cuidado de colocar este texto aps o tag HTML de abertura.) Se o Bean j
existe no ambiente, requisies subseqentes pgina no provocaro a exibio deste
cdigo HTML. Exemplo:
<html>
<body>
<jsp:useBean id=clock class=com.manning.jsp.ClockBean>
O <B>ClockBean</B> est sendo inicializado...
<jsp:setProperty name=clock property=timezone value=CST />
</jsp:useBean>
O resto da pgina html ...
</body>
</html>
Inicializando Beans a partir de Requisies
Uma caracterstica importante do tag <jsp:setProperty> a sua habilidade de
atribuir valores s propriedades de um Bean a partir de informaes recuperadas de
uma requisio encaminhada a determinada pgina. Isto faz com que um Bean possa
ser configurado dinamicamente a partir de dados informados pelo usurio.
Exemplo de um Bean para Calcular Juros Compostos
<html>
<body>
<form action=JurosCompostos.jsp>
Principal: <input type=text name=principal>
Taxa de Juros: <input type=text name=taxaJuros>
Anos: <input type=text name=anos>
<input type=submit value=Calcular Valor Futuro>
</form>
</body>
</html>
Podemos criar um manipulador para nosso formulrio denominado
JurosCompostos.jsp, que utilizar os valores especificados nos campos do formulrio
para configurar um Bean capaz de calcular juros compostos. Este Bean ser criado no
prximo captulo, mas por enquanto vamos nos concentrar na sua utilizao como um
servio para a nossa pgina.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 67
Folha de propriedades do Bean
Nome Acesso Tipo Java Exemplo
principal read/write double 100.50
taxaDeJuros read/write double .10
anos read/write int 10
valorFuturo read-only String 155.21
A propriedade valorFuturo est ligada s outras propriedades. Seu valor calculado
utilizando-se os valores especificados para as propriedades principal, taxaDeJuros
e anos. Logo, para utilizar este Bean necessrio primeiramente designar valores para
estas trs propriedades, e ento ler o resultado da propriedade valorFuturo. Vejamos
o cdigo JSP que ser o manipulador do formulrio. Primeiramente necessrio criar
uma referncia para o Bean JurosCompostosBean.
<%@ page import=com.taglib.wdjsp.components.* %>
<jsp:useBean id=calculadora class=JurosCompostosBean />
No corpo do tag <jsp:useBean> preciso mapear cada propriedade de configurao
do Bean para uma campo do formulrio. O tag <jsp:setProperty> procura por um
parmetro de requisio que combine com o valor especificado no seu atributo param.
Se um parmetro com este nome for encontrado, o tag diz ao Bean para designar para a
propriedade correspondente, especificada atravs do atributo property, este valor,
efetuando qualquer tipo de converso necessria.
<jsp:setProperty name=calculadora property=principal
param=principal />
<jsp:setProperty name=calculadora property=taxaDeJuros
param=taxaDeJuros />
<jsp:setProperty name=calculadora property=anos param=anos />
O atributo param do tag <jsp:setProperty> o equivalente ao scriptlet JSP <%
request.getParameter(algo) %>.
Exemplo de cdigo com scriptlets em vez do atributo param para inicializar os valores
de um Bean:
<jsp:setProperty name=calculadora property=principal
param=<%= request.getParameter(principal) %> />
Quando uma requisio vem de um formulrio, as propriedades do Bean devem ser
designadas para os valores dos parmetros do formulrio. Como esta uma forma
comum de se configurar Beans em JSP, h uma sintaxe abreviada para o tag
<jsp:setProperty>.
<jsp:setProperty name=calculadora property=principal />
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 68
Se o nome da propriedade igual ao nome do parmetro passado atravs do
formulrio, possvel omitir o atributo param.
Quando vrios nomes de campos do formulrio so mapeados diretamente para
propriedades de um Bean, possvel utilizar o caracter * no local do nome da
propriedade.
<jsp:setProperty name=calculadora property=* />
Para cada propriedade do Bean ser procurado um parmetro de mesmo nome.
Parmetros extras so ignorados, embora eles possam ser acessados atravs de
scriptlets e atravs do objeto request implcito. possvel, naturalmente, emitir
comandos <jsp:setProperty> adicionais para apanhar parmetros de requisio
cujos nomes no casam diretamente com propriedades de um Bean. No h como
especificar a ordem de alterao das propriedades do Bean. Se existem
interdependncias (uma propriedade dependendo de outra), ser necessrio especificar
um tag <jsp:setProperty> para cada propriedade.
Agora que o Bean j foi configurado possvel ler o resultado do Bean armazenado na
propriedade valorFuturo. Tambm podemos verificar que valores foram informados
pelo usurio, lendo os valores das propriedades que foram configuradas.
<%@ page import=com.taglib.wdjsp.components.JurosCompostosBean %>
<jsp:useBean id=calculadora class=JurosCompostosBean >
<jsp:setProperty name=calculadora property=principal />
<jsp:setProperty name=calculadora property=taxaDeJuros />
<jsp:setProperty name=calculadora property=anos />
</jsp:useBean>
<html>
<body>
Se voc investir R$<jsp:getProperty name=calculadora
property=principal /> por <jsp:getProperty name=calculadora
property=anos /> anos a uma taxa de juros compostos de
<jsp:getProperty name=calculadora property=taxaDeJuros />, voc
receber R$<jsp:getProperty name=calculadora property=valorFuturo
/>.
</body>
</html>
A sada desta pgina JSP ser:
Se voc investir R$1000,00 por 10 anos a uma taxa de juros compostos
de .15, voc receber R$87.541,99.
Para JSP no faz diferena qual mtodo (GET ou POST) est sendo utilizado para
submeter o formulrio. Se for necessrio, tambm possvel adicionar elementos de
formulrio HIDDEN para adicionar informaes de configurao a um formulrio sem
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 69
a necessidade do usurio entrar com esta informao. Tambm possvel digitar um
URL completo sem a necessidade de um formulrio:
http://host/JurosCompostos.jsp?taxaDeJuros=0.10&anos=15&principal=1000
Especificando Valores de inicializao Default
A tentativa de inicializar uma propriedade de um Bean atravs de um parmetro de
requisio inexistente ou atravs de um valor de parmetro definido como vazio, faz
com que o comando <jsp:setProperty> no produza nenhum efeito. A propriedade
no recebe null. O tag <jsp:setProperty> simplesmente ignorado. possvel, no
entanto, prover um valor default para uma propriedade, designando a ela este valor,
para s ento tentar buscar o valor do parmetro correspondente.
<jsp:setProperty name=calculadora property=taxaDeJuros
value=0.10 />
Neste exemplo, a taxa de Juros default de 10%, mas este valor pode ser modificado
pelo usurio.
5.3.4 Controlando o Escopo de um Bean
At agora foram criados Beans que encapsulam dados e comportamento durante a vida
de uma nica pgina. Cada vez que uma pgina requisitada, uma nova instncia de
um Bean criada e possivelmente modificada atravs do tag <jsp:setProperty>. No
entanto, JSP possui uma caracterstica poderosa que permite que um Bean continue a
existir alm do escopo de uma nica requisio de pgina. Estes Beans so
armazenados no ambiente do servidor e so reutilizados em vrias pginas, ou por
vrias requisies de uma mesma pgina. Isto faz com que seja possvel criar um Bean
uma nica vez e reutiliz-lo diversas vezes. Quaisquer propriedades modificadas
permanecero modificadas durante a vida do Bean.
Tempo de Vida de um Bean
O tempo de vida de um Bean controlado atravs do atributo scope do tag
<jsp:useBean>. Este atributo pode possuir os seguintes valores: page, request,
session, ou application. A acessibilidade de um Bean determina quais pginas ou partes
de uma aplicao (web) podem acessar o Bean e suas propriedades.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 70
Quando um Bean criado no servidor para reutilizao entre pginas ele identificado
pelo valor atribudo ao atributo id do tag <jsp:useBean>. Sempre que uma pgina
JSP tenta criar um Bean com o tag <jsp:useBean>, o container JSP verifica se h na
memria do servidor um Bean com este mesmo id. Caso um Bean com este mesmo
seja encontrado, ele poder ser acessado pela requisio corrente. Isto , uma nova
instncia deste Bean no ser criada. Se quaisquer comandos de configurao tiverem
sido especificados no corpo do tag <jsp:useBean>, eles sero ignorados uma vez que
o Bean j foi inicializado. Um Bean pode ter apenas um escopo.
<jsp:useBean id=nomeDoBean class=classe
scope=page|request|session|application />
Beans com Escopo de Pgina
Este o escopo default. Toda vez que uma pgina requisitada por um novo visitante
ou por um visitante que est retornando, o Bean criado. Estes Beans no podem ser
acessados fora da pgina em que foram criados. Caso uma pgina referenciada pelos
tags <jsp:include> ou <jsp:forward> contenha tags que referenciam um Bean com
o mesmo id de um Bean criado na pgina pai, o Bean criado na pgina pai ser
ignorado pois est fora de escopo, e um novo Bean ser criado.
Se um Bean no necessita persistir entre requisies, ou caso sua informao no tenha
utilidade aps a requisio ter sido completada, este provavelmente um bom
candidato a Bean com escopo de pgina.
Beans com Escopo de Requisio
Se sua pgina, no entanto, utiliza os tags <jsp:include> ou <jsp:forward> pode ser
necessrio designar o escopo do Bean para request.
Caso se especifique o valor request para o atributo scope do tag <jsp:useBean>, o
container JSP tentar recuperar o Bean armazenado na requisio. Como o protocolo
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 71
HTTP no prov um mecanismo que permita um browser armazenar nada alm de
simples pares de nome/valor na requisio, um Bean pode apenas ser armazenado na
requisio por um servlet ou outra pgina JSP no servidor local. Beans so
armazenados em requisies como atributos, uma caracterstica da API Java Servlet
2.2. Se um Bean no encontrado na requisio, ele ser criado e colocado l.
O tempo de vida de um Bean com escopo de requisio essencialmente o mesmo de
um Bean com o escopo de pgina, exceto que o Bean poder ser acessado por pginas
referenciadas atravs dos tags <jsp:include> e <jsp:forward>. Isto permite que um
Bean seja criado por um servlet e, posteriormente, encaminhado para uma pgina JSP.
Por exemplo, considere o exemplo (abaixo) de pginas includas em outras como p
de pgina, atravs do tag <jsp:include>.
<jsp:useBean id=contato class=jsp.ContatoBean scope=request >
<jsp:setProperty name=contato property=nome
value=Vinicius Aguiar />
</jsp:useBean>
<html>
<body>
Bem-vindo ao nosso web site!
<jsp:include file=peDePagina/peDePaginaPadrao.jsp flush=true />
</body>
</html>
Neste exemplo, contato ser acessvel pela pgina corrente e pela pgina
peDePaginaPadrao.jsp, cuja definio vem abaixo:
<HR>
Para requisitar modificaes nesta pgina, entre em contato com
<jsp:getProperty name=contato property=nome />
Beans com Escopo de Sesso
O escopo de sesso introduz a persistncia de componentes em pginas JSP, e uma
das construes mais poderosas. Um Bean com escopo de sesso armazenado em um
objeto de sesso do usurio. O container JSP mantm um nico objeto de sesso para
cada usurio que esteja visitando o site. Para armazenar um Bean em um objeto
session, utilizado o valor do atributo id.
Um Bean no necessita fazer nada de especial para suportar esta persistncia. O
container JSP ir cuidar da manuteno do estado sempre que um Bean for colocado
em um objeto session, atravs do atributo scope. Como o container JSP que
determina o tempo de durao de uma sesso, o tempo de vida de um Bean pode ser de
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 72
alguns minutos, horas ou dias. Alguns servidores web, como o WebSphere da IBM,
podem escrever os dados de uma sesso em disco quando o servidor sofre um
shutdown, e recuper-los no momento do reinicio. Nem todos os containers, no
entanto, possuem este comportamento, logo, se necessrio armazenar informaes de
uma sesso por um tempo indefinido, ou no caso da sesso armazenar dados crticos,
seria interessante considerar a possibilidade de se armazenar este tipo de informao
em um banco de dados. Geralmente, a maioria dos containers deixam a sesso expirar
quando decorre um intervalo de tempo sem que a sesso seja acessada neste intervalo.
Um bom exemplo de utilizao de Bean com o escopo de sesso a utilizao de um
CarrinhoDeComprasBean armazenado na sesso do usurio. Em cada pgina pode ser
includa uma referncia ao CarrinhoDeComprasBean, permitindo que o total de
compras seja calculado a qualquer momento, se necessrio.
A seguir vem um exemplo de um Bean denominado TimerBean, cujo objetivo nos
informar a quanto tempo uma sesso do usurio est ativa. Poderamos utilizar um
Bean deste tipo para armazenar em um arquivo de log o tempo gasto por um usurio
para responder a uma prova. Este Bean possui uma funo bsica: reportar a diferena
entre o momento de criao do Bean e o momento corrente.
Folha de propriedades do Bean
Nome Acesso Tipo Java Exemplo
elapsedMillis read-only long 180000
elapsedSeconds read-only long 180
elapsedMinutes read-only long 3
startTime read/write long 857374234
A propriedade startTime existe para que se possa atribuir um valor ao momento de
incio de contagem do tempo. Uma poca em particular (expressa em milissegundos
deste epoch), ou o momento corrente (passando um zero ou um nmero negativo).
Segue abaixo uma simples utilizao deste componente que na primeira carga inicia a
contagem do tempo, e exibe o tempo decorrido a cada novo acesso a esta pgina.
(Naturalmente, o tempo entre visitas no pode ser superior ao tempo de expirao da
sesso definido pelo container JSP.)
<%@ page import=com.taglib.wdjsp.components.* %>
<jsp:useBean id=timer class=TimerBean scope=session />
<html>
<body>
Tempo decorrido:
<jsp:getProperty name=timer property=elapsedMinutes /> minutos
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 73
Caso houvesse o interesse de adicionar esta funcionalidade a vrias pginas, os tags do
Bean poderiam ser includos em um arquivo. Este arquivo, por sua vez, poderia ser
includo nas diversas pginas atravs do tag <jsp:include>.
Beans com Escopo de Aplicao
Beans com escopo de aplicao esto associados a uma aplicao JSP no servidor.
Uma aplicao JSP formada por um conjunto de pginas JSP, pginas HTML, imagens,
applets, e outros recursos, sob uma hierarquia de URL particular. Beans com o escopo
de aplicao existem enquanto o container JSP est no ar. Beans de aplicao so
compartilhados por todos os usurios de uma aplicao. Qualquer pgina JSP que faa
parte da aplicao pode acessar Beans de aplicao criados por outras pginas da
mesma aplicao. Se o Bean necessitar de alguma informao de configurao, esta
informao dever ser independente de pgina.
Para cada aplicao em um servidor h no mximo uma instncia de um Bean com este
tipo de escopo.
Um bom uso de Bean com escopo de aplicao a possibilidade de se utilizar um Bean
para se efetuar cache de informaes (de aplicaes). interessante efetuar o cache
deste tipo de informao quando so caros os recursos computacionais necessrios para
se gerar estas informaes, a cada nova requisio. Por exemplo, digamos que muitas
pginas de uma aplicao necessitam acessar uma tabela com os preos de fretes
cobrados para a entrega das mercadorias. Estas informaes podem ser encapsuladas
em um Bean com escopo de aplicao. Isto significa que estas informaes precisariam
ser coletadas de um banco de dados apenas uma vez. Em cada pgina deve-se
simplesmente referenciar o Bean.
<jsp:useBean id=ship class=ShipRateBean scope=application />
<html>
<body>
As taxas de frete atuais so:
<jsp:getProperty name=ship property=baseCharge />
por frete mais
<jsp:getProperty name=ship property=perItemCharge />
por cada item enviado.
</body>
</html>
Caso o Bean necessite de configurao deve ser utilizado o corpo do tag
<jsp:useBean> para designar os valores iniciais de propriedades. Como seria
necessrio fazer isto em todas as pginas onde este Bean pode ser utilizado, seria
interessante analisar algumas alternativas. Primeiro, o construtor do Bean poderia obter
informaes de outras fontes (um arquivo de propriedades, por exemplo). Segundo,
preciso ter certeza que o Bean foi criado (com escopo de aplicao) antes de qualquer
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 74
pgina dependente necessitar acessar o Bean. Tambm seria possvel serializar o Bean
pr-configurado para disco, e restaur-lo quando necessrio.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 75
6. DESENVOLVENDO COMPONENTES JSP
Este captulo trata da criao de JavaBeans para utilizao como componentes JSP.
6.1 O Que Faz de um Bean um Bean
O que torna um Bean to especial? Um Bean simplesmente uma classe Java que
segue um conjunto de convenes de nome e de projeto definidas pela especificao
dos JavaBeans. Beans no necessitam estender uma classe em particular ou
implementar determinada interface. Se uma classe segue as convenes estipuladas
para Beans e tratada como um Bean, ento ela um Bean.
6.1.1 Convenes
As convenes para JavaBeans possibilitam o desenvolvimento de Beans pois
permitem a um container de Beans analisar um arquivo de classe Java e interpretar
seus mtodos como propriedades, designando a classe como um JavaBean. As
convenes determinam as regras para a definio do construtor de um Bean e os
mtodos que iro definir suas propriedades.
A API JavaBeans
As convenes especificadas pela API JavaBeans permitem ao container JSP interagir
com Beans a nvel de programao, mesmo que a aplicao que contm o Bean no
entenda realmente o que o Bean faz, ou como ele funciona. No caso de JSP
necessrio conhecer os aspectos da API que determinam as assinaturas dos mtodos
construtores de Beans, e dos mtodos de acesso a propriedades.
Beans So Apenas Objetos
Como qualquer outra classe Java, instncias de classes JavaBeans so simplesmente
objetos Java. Consequentemente, sempre haver a possibilidade de se referenciar
Beans e seus mtodos diretamente atravs de cdigo Java em outras classes ou atravs
de elementos de script JSP. Como eles seguem a conveno JavaBeans, possvel
trabalhar com eles de uma forma muito mais simples do que atravs de cdigo Java.
Containers de Beans, como o container JSP, pode prover um fcil acesso a Beans e
suas propriedades. Desenvolvedores JSP utilizam scriptlets, expresses, ou tags
customizados para acess-los uma vez que o container de um Bean capaz de
manipular um Bean apenas atravs de suas propriedades.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 76
Convenes de Nome de Classes
Os Beans seguem as mesmas regras para nomes de classes Java: devem comear por
um caracter alfabtico, devem conter apenas caracteres alfanumricos e underscore, e
so case sensitive. E como ocorre com as demais classes Java, comum (mas no
obrigatrio) comear o nome de um Bean com letra maiscula.
A Mgica da Introspeco
Como pode o container JSP interagir com um Bean sem o benefcio de uma interface
comum ou classe base? Java gerencia este pequeno milagre atravs de um processo
denominado introspeco que permite que uma classe exponha seus mtodos e
capacidades no momento da requisio. Este processo de introspeco ocorre em
tempo de execuo, e controlado por um container de Beans. a introspeco que
possibilita a utilizao de convenes para a definio de propriedades.
A introspeco ocorre atravs de um mecanismo denominado reflexo (reflection), que
permite que o container de Beans examine qualquer classe em tempo de execuo para
identificar a assinatura de seus mtodos. O container de Beans identifica que
propriedades um Bean suporta analisando seus mtodos pblicos. Estes mtodos
devem seguir os critrios definidos pela API JavaBeans. Para uma propriedade existir,
a classe do Bean deve definir um mtodo de acesso para retornar o valor da
propriedade, mudar o valor da propriedade, ou ambos. a presena destes mtodos de
acesso que determinam as propriedades de uma classe de Bean.
6.1.2 O Construtor do Bean
A primeira regra de construo de um Bean JSP que ele deve possuir um construtor
sem argumentos. este construtor que o container JSP utilizar para instanciar o Bean
atravs do tag <jsp:useBean>. Lembre-se que toda classe Java que no especifica
explicitamente nenhum construtor, possui por default um construtor com zero
argumentos.
O exemplo abaixo apresenta um Bean que sabe a hora do dia. A classe deste Bean
possui um construtor com zero argumentos e armazena a hora em que o Bean foi
instanciado. Naturalmente, para poder ser utilizado dentro de uma pgina JSP ser
necessrio definir algumas propriedades para o Bean e criar os mtodos de acesso para
control-las.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 77
package jsp.aluno01.exercicio12;
import java.util.*;
public class HoraCorrenteBean
{ private int hora;
private int minuto;
public HoraCorrenteBean()
{ Calendar agora = Calendar.getInstance();
hora = agora.get(Calendar.HOUR_OF_DAY);
minuto = agora.get(Calendar.MINUTE);
}
}
6.1.3 Definindo as Propriedades de um Bean
Como mencionado anteriormente, as propriedades de um Bean so definidas
simplesmente atravs da criao de mtodos de acesso para elas. Para se definir
propriedades para um bean preciso simplesmente criar um mtodo pblico com o
mesmo nome da propriedade que se deseja definir, prefixado pelas palavras get ou
set.
Mtodos do tipo get devem retornar o tipo de dado apropriado, e mtodos do tipo set
devem ser declarados como void e devem aceitar um argumento do tipo apropriado.
Exemplo:
No exemplo abaixo foram adicionadas duas propriedades ao Bean HoraCorrenteBean
denominadas hora e minuto. Para estas propriedades devem ser definidos mtodos do
tipo get, conforme vem no exemplo abaixo:
package jsp.aluno01.exercicio12;
import java.util.*;
public class HoraCorrenteBean
{ private int hora;
private int minuto;
public HoraCorrenteBean()
{ Calendar agora = Calendar.getInstance();
hora = agora.get(Calendar.HOUR_OF_DAY);
minuto = agora.get(Calendar.MINUTE);
}
public int getHora()
{ return hora;
}
public int getMinuto()
{ return minuto;
}
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 78
Estes mtodos simplesmente retornar os valores armazenados nas variveis de
instncia. Como eles seguem as regras para nomes de mtodos de acesso, foram
definidas, desta forma, duas propriedades que podero ser acessadas atravs de tags
Bean em pginas JSP. Por exemplo:
<jsp:useBean id="hora"
class="jsp.aluno01.exercicio12.HoraCorrenteBean" />
<html>
<body>
Agora so <jsp:getProperty name="hora" property="hora" />
horas e <jsp:getProperty name="hora" property="minuto" /> minutos.
</body>
</html>
preciso no confundir propriedades com variveis de instncia, embora variveis de
instncia so geralmente mapeadas diretamente para nomes de propriedades. As
propriedades de um Bean no necessitam corresponder diretamente a variveis de
instncia.
O Bean abaixo, por exemplo, gera valores de propriedades dinamicamente. Este Bean
cria nmeros randmicos nos mtodos de acesso a propriedades, em vez de
simplesmente retornar uma cpia de uma varivel de instncia.
package com.taglib.wdjsp.components;
import java.util.*;
public class DadosBean
{ private Random numero;
public DadosBean()
{ numero = new Random();
}
public int getDado()
{ // retorna um nmero entre 1 e 6
return numero.nextInt(6) + 1;
}
public int getDados()
{ // retorna um nmero entre 2 e 12
return getDado() + getDado();
}
}
No obrigatria a criao dos mtodos get e set para cada propriedade de um Bean.
Se uma propriedade deve ser read-only, basta que o mtodo set no seja criado. Isto ,
apenas o mtodo get deve ser definido. E para definir uma propriedade write-only
deve ser criado apenas o mtodo set.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 79
Convenes de Nomes de Propriedades
Uma conveno comum que os nomes de propriedades possuem letras maisculas e
minsculas misturadas, comeando por uma letra minscula e com uma letra
maiscula no incio de cada palavra que compe o nome da propriedade. Para a
propriedade nome, por exemplo, os mtodos get e set seriam: getNome() e
setNome(). Observe as diferenas de tamanho de letras entre o nome da propriedade e
os nomes de mtodos de acesso. O container JSP altera a primeira letra de uma
propriedade para letra maiscula quando estiver tentando executar um mtodo de
acesso. Caso uma propriedade possua por exemplo, o nome URL, seus mtodos de
acesso devero ser getURL() e setURL().
6.1.4 Propriedades Indexadas
Propriedades de Beans no esto limitadas a valores atmicos. Beans tambm podem
conter propriedades multivaloradas. Por exemplo, pode ser necessrio armazenar uma
propriedade denominada contatos que utilizada para armazenar uma lista de objetos
do tipo Contato, que contm informaes de telefone e endereo. Cada valor desta
propriedade poderia ser acessado atravs de scriptlets ou atravs de tags customizados.
E todos os valores armazenados nesta propriedade devem ser de um mesmo tipo.
H duas formas de se definir uma propriedade indexada: O primeiro estilo atravs da
definio de um mtodo de acesso que retorna todo o conjunto de propriedades como
um nico array. Neste caso o autor da pgina JSP ou do tag customizado pode
determinar o tamanho do conjunto e interagir com ele. Por exemplo:
public TipoDaPropriedade[] getProperty()
public void setProperty(TipoDaPropriedade[])
A segunda opo de acesso a propriedades indexadas utiliza um valor de ndice para se
ter acesso aos elementos do conjunto. Desta forma possvel acessar um elemento
especfico do conjunto. Por exemplo:
public TipoDaPropriedade getProperty(int index)
public void setProperty(int index, TipoDaPropriedade value)
Embora no seja obrigatrio, interessante implementar os dois estilos de acesso a
propriedades multivaloradas. No d muito mais trabalho e adiciona muita
flexibilidade na utilizao do Bean.
Um outro tipo de mtodo comumente implementado e reconhecido pelos containers de
Beans o mtodo size() que pode ser utilizado para determinar o tamanho de uma
propriedade indexada. Uma implementao tpica seria:
public int getPropertySize()
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 80
Este mtodo tambm no obrigatrio, mas d aos desenvolvedores de pginas mais
opes de trabalho.
Exemplo de um Bean com Propriedade Indexada
No exemplo abaixo foi construdo um componente que efetua clculos estatsticos em
uma srie de nmeros. Os nmeros so armazenados em uma nica propriedade
indexada. Outras propriedades do Bean armazenam valores de clculos estatsticos
como mdia e soma.
package jsp.aluno01.exercicio13;
import java.util.*;
public class StatBean
{ private double[] numbers;
public StatBean()
{ numbers = new double[2];
numbers[0] = 1;
numbers[1] = 2;
}
public double getAverage()
{ double sum = 0;
for (int i=0; i < numbers.length; i++)
sum += numbers[i];
return sum/numbers.length;
}
public double[] getNumbers()
{ return numbers;
}
public double getNumbers(int index)
{ return numbers[index];
}
public void setNumbers(double[] numbers)
{ this.numbers = numbers;
}
public void setNumbers(int index, double value)
{ numbers[index] = value;
}
public void setNumbersList(String values)
{ Vector n = new Vector();
StringTokenizer tok = new StringTokenizer(values, ",");
while (tok.hasMoreTokens())
n.addElement(tok.nextToken());
numbers = new double[n.size()];
for (int i=0; i < numbers.length; i++)
numbers[i] = Double.parseDouble((String) n.elementAt(i));
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 81
public String getNumbersList()
{ String list = new String();
for (int i=0; i < numbers.length; i++)
{ if (i != numbers.length)
list += numbers[i] + ",";
else
list += "" + numbers[i];
}
return list;
}
public int getNumbersSize()
{ return numbers.length;
}
public static void main(String[] args)
{ StatBean sb = new StatBean();
sb.setNumbersList("100,200,300");
System.out.println(sb.getNumbers(0));
System.out.println(sb.getNumbers(1));
System.out.println(sb.getNumbers(2));
System.out.println("avg=" + sb.getAverage());
}
}
Como os tags JSP para a manipulao de Beans lidam exclusivamente com
propriedades atmicas, a nica forma de interagir com propriedades indexadas
atravs de scriptlets e expresses. Na pgina JSP abaixo foi utilizado um scriptlet no
corpo do tag <jsp:useBean> para passar um array de inteiros para a propriedade
numbers do Bean. Tambm foi preciso utilizar um scriptlet para exibir os nmeros,
mas para o clculo e exibio da mdia foi utilizado um tag <jsp:getProperty>.
<jsp:useBean id="stat" class="jsp.aluno01.exercicio13.StatBean">
<%
double[] mynums = {100, 250, 150, 50, 450};
stat.setNumbers(mynums);
%>
</jsp:useBean>
<html>
<body>
A mdia de
<%
double[] numbers = stat.getNumbers();
for (int i=0; i < numbers.length; i++)
{ if (i == 0)
out.print(numbers[i]);
else if (i < (numbers.length - 1))
out.print(", " + numbers[i]);
else
out.println(" e " + numbers[i]);
}%>
igual a <jsp:getProperty name="stat" property="average" />
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 82
</body>
</html>
O uso de tags customizados, uma tcnica que est fora do escopo desta apostila, pode
ajudar muito na manipulao de propriedades indexadas, eliminando a necessidade de
cdigo Java dentro da pgina JSP. Tags customizados encapsulam funcionalidade
comum em simples tags. possvel, tambm, mover este cdigo para dentro do Bean,
conforme vem abaixo.
Acessando Valores Indexados Atravs de JSP Bean Tags
Examinando-se o Bean acima pode-se observar que foram includos dois mtodos
(setNumbersList(String values) e getNumbersList(String values)) que
permitem que um array de nmeros seja passado atravs de um tag padro. Como os
tags lidam exclusivamente com valores atmicos, o mtodo de acesso
(setNumbersList(String values)) fica com a responsabilidade de converter um
String contendo nmeros delimitados por vrgulas, em um array de nmeros.
Agora, em funo da existncia destes dois mtodos, possvel acessar este Bean
utilizando apenas tags JSP.
<jsp:useBean id="stat" class="jsp.aluno01.exercicio13.StatBean">
<jsp:setProperty name="stat" property="numbersList"
value="100,250,150,50,450" />
</jsp:useBean>
<html>
<body>
A mdia de
<jsp:getProperty name="stat" property="numbersList" />
igual a
<jsp:getProperty name="stat" property="average" />
</body>
</html>
6.1.5 Propriedades Boleanas
Para uma propriedade do tipo boolean, que armazena apenas valores true e false,
pode ser utilizada uma outra conveno para os mtodos do tipo get. Esta nova
conveno prev a prefixao da palavra is no nome da propriedade. Exemplo:
public boolean isHabilitado();
public boolean isAutorizado();
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 83
O container procurar automaticamente por estes nomes de mtodos caso no encontre
mtodos com a sintaxe discutida anteriormente.
J a designao de valores boleanos no diferente:
public void setHabilitado (boolean b);
public void setAutorizado(boolean b);
6.1.6 Converso de Tipo JSP
Propriedades de componentes JSP no esto limitadas a valores do tipo String, mas
importante compreender que todos os valores de propriedades acessados atravs do tag
<jsp:getProperty> so convertidos em um String. Da mesma forma, todos os valores
de propriedades atribudos atravs de um tag <jsp:setProperty> so
automaticamente convertidos de String para o tipo apropriado.
Propriedades no esto restritas aos tipos primitivos. Para objetos, o container JSP
chama o mtodo toString() da classe Object, que, a menos que tenha sofrido um
overload, provavelmente no ser muito representativo da informao armazenada no
objeto. Uma alternativa para o armazenamento de um objeto como propriedade seria,
por exemplo, permitir que o usurio designe valores para horas e minutos
separadamente atravs de um par de propriedades write-only e disponibilizar uma
nica propriedade read-only denominada hora.
Tratando Propriedades com Valores Nulos
Propriedades do tipo get para tipos primitivos como int e double no podem retornar
o valor null, que s vlido para mtodos que retornam objetos. Nestes casos, uma
alternativa, nem sempre indicada, seria o estabelecimento de uma conveno que
indicasse que se trata de um valor nulo. Exemplo: retornar um nmero negativo,
quando se tratar de um nulo.
Uma melhor abordagem para este problema seria adicionar uma propriedade boleana
para validar o contedo da propriedade em questo. Logo, seriam necessrios dois
mtodos para a leitura desta informao: um mtodo getNomeDaPropriedade() e um
mtodo isValidoNomeDaPropriedade().
6.1.7 Configurando Beans
Muitas vezes um Bean necessita de configurao em tempo de execuo, pela pgina
que o est utilizando, antes que ele possa realizar suas tarefas. Como no possvel
passar informaes para o construtor de um Bean preciso utilizar propriedades do
Bean para armazenar informaes de configurao. Esta configurao deve ocorrer
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 84
imediatamente aps o container instanciar o Bean, no corpo do tag <jsp:useBean> ou
em qualquer lugar da pgina antes que as propriedades do Bean sejam acessadas.
Embora tags para o acesso a Beans no permitem que se passe argumentos para o
construtor de um Bean, possvel definir construtores que aceitam argumentos.
Atravs de um scriptlet seria possvel instanciar um objeto que requer argumentos no
seu construtor. Por exemplo:
<% Termostato t = new Termostato(78); %>
O termostato foi configurado para a temperatura de
<%= t.getTemperatura() %> graus.
Uma tcnica interessante prover um nico mtodo que manipula todos os passos de
configurao. Este mtodo pode ser chamado pelo construtor que possui argumentos e
pelo(s) mtodo(s) set. No exemplo abaixo foram construdos dois construtores para a
classe Termostato e um mtodo init() responsvel pela configurao do Bean. O
construtor com zero argumentos foi fornecido para prover compatibilidade com a
especificao dos Beans. Este construtor, quando executado, chama o construtor que
possui um argumento, atribuindo assim um valor default para a temperatura. O mtodo
init() ento chamado por este construtor alternativo.
public class Termostato
{ private int temp;
private int maxTemp;
private int minTemp;
private int fuelType;
public Termostato()
{ // construtor sem argumentos
this(75);
}
public Termostato(int temp)
{ this.temp = temp;
init();
}
public void setTemp(int temp)
{ this.temp = temp;
init();
}
public int getTemp(int temp)
{ return temp;
}
private void init()
{ maxTemp = this.temp + 10;
minTemp = this.temp 15;
if (maxTemp > 150)
fuelType = Fuels.DILITHEUM;
else
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 85
fuelType = Fuels.NATURALGAS;
}
}
6.2 Alguns Exemplos
6.2.1 Exemplo: HoraCorrenteBean
No captulo anterior foi utilizado um Bean denominado TimerBean para determinar a
quanto tempo um usurio est ativo na sesso corrente.
package jsp.aluno01.exercicio15;
public class TimerBean
{ private long start;
public TimerBean() // Determina o incio da contagem do tempo
{ start = System.currentTimeMillis();
}
public long getElapsedMillis()
{ long now = System.currentTimeMillis();
return now - start;
}
public long getElapsedSeconds() // Retorna segundos
{ return (long)this.getElapsedMillis() / 1000;
}
public long getElapsedMinutes() // Retorna minutos
{ return (long)this.getElapsedMillis() / 60000;
}
public void reset() // Re-inicia contagem do tempo
{ start = System.currentTimeMillis();
}
public long getStartTime()
{ return start;
}
public void setStartTime(long time)
// Determina um novo momento de incio de contagem do tempo
{ if (time <= 0)
reset();
else
start = time;
}
}
Seguem abaixo duas pginas JSP utilizadas para acessar este Bean.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 86
Primeira Pgina:
<%@ page import=jsp.aluno01.exercicio15.TimerBean %>
<jsp:useBean id=timer class=TimerBean scope=session />
<html>
<body>
Tempo decorrido:
<jsp:getProperty name=timer property=elapsedMillis />
milissegundos
</body>
</html>
Segunda Pgina:
<%@ page import="jsp.aluno01.exercicio15.TimerBean" %>
<jsp:useBean id="timer" class="TimerBean" scope="session" />
<html>
<body>
<jsp:setProperty name="timer" property="startTime" value="-1" />
Seu tempo online foi reiniciado...
</body>
</html>
Observe que o tag <jsp:setProperty> no pode ficar entre <jsp:useBean> e
</jsp:useBean>, pois se o Bean j tiver sido instanciado o mtodo setStartTime()
no ser executado.
6.2.2 Um Bean que Calcula Juros Compostos
O cdigo abaixo apresenta um componente para o clculo do valor futuro de um
investimento considerando uma determinada taxa de juros compostos. A frmula para
o clculo do valor futuro a seguinte:
fv = principal (1 + taxa/perodo) ^ (anos * perodo)
Este Bean necessita:
Do valor a ser investido.
Da taxa de juros.
O nmero de anos do investimento.
Com que freqncia os juros recebidos so acumulados ao principal.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 87
Estas informaes indicam a lista de propriedades que o usurio deve ser capaz de
modificar. Aps o usurio inicializar todas as propriedades relacionadas na tabela
abaixo, o Bean deve ser capaz de calcular o valor futuro da quantia principal. Ser
necessrio tambm, uma propriedade para refletir o valor futuro aps o clculo ter sido
executado.
Nome da Propriedade Modo Tipo
principal read/write double
anos read/write int
composio read/write int
taxaDeJuros read/write double
valorFuturo read-only double
Como os usurios provavelmente tero interesse em exibir os valores de entrada, alm
de configur-los, foram criados mtodos de acesso de leitura e escrita para estas
propriedades do Bean. E a propriedade valorFuturo possui apenas um mtodo de
acesso do tipo get para que ele possa refletir o resultado do clculo. (Uma outra
abordagem interessante seria: uma vez informados os valores de quatro propriedades
quaisquer, o Bean poderia calcular o valor da propriedade remanescente.) Neste
exemplo, as propriedades de inicializao foram criadas como variveis de instncia.
package jsp.aluno01.exercicio16;
public class JurosCompostosBean
{ private double taxaDeJuros;
private int anos;
private double principal;
private int composicao;
public JurosCompostosBean()// De acordo com a conveno
{ this(12); // Como os investimentos costumam render 12
// vezes por anos, este o valor default de
// composio.
}
public JurosCompostosBean(int composicao)
{ this.composicao = composicao;
this.taxaDeJuros = -1; // No possvel calcular o valor
this.anos = -1; // futuro sem que estes
this.principal = -1; // valores sejam informados.
}
/*
VF = Principal(1 + i/12)^(12 * anos)
Assumindo 12 perodos de composio por anos
*/

____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 88
public double getValorFuturo()
{ if ((composicao != -1) && (taxaDeJuros != -1 ) &&
(anos != -1)) // ou if (isInitialized())
return principal * Math.pow(1 + taxaDeJuros/composicao,
composicao * 12);
else throw new RuntimeException
("Bean requer configurao!");
}
/* private boolena isInitialized()
{ return (compostoSet && taxaDeJurosSet &&
anosSet && principalSet);
}
Neste caso o Bean estar inicializado apenas se os flags (variveis
boleanas) de todas as propriedades estiverem designadas para true.
Estes flags seriam inicializados para false no construtor e os mtodos
set seriam definidos assim:
public void setAnos (int anos)
{ anosSet = true;
if (anos >= 1)
this.anos = anos;
else
this.anos = 1;
*/
public void setTaxaDeJuros(double taxa)
{ if (taxa > 0)
this.taxaDeJuros = taxa;
else
this.taxaDeJuros = 0;
}
public double getTaxaDeJuros()
{ return this.taxaDeJuros;
}
public void setAnos(int anos)
{ if (anos >=1 ) // Dinheiro no pode ser investido no
this.anos = anos; // passado, logo anos deve ser um nmero
else // positivo.
this.anos = 1;
}
public int getAnos()
{ return this.anos;
}
public void setPrincipal(double principal)
{ this.principal = principal;
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 89
public double getPrincipal()
{ return this.principal;
}
public static void main(String[] args)
{ JurosCompostosBean bean = new JurosCompostosBean();
bean.setTaxaDeJuros(0.06);
bean.setAnos(30);
bean.setPrincipal(1200.00);
System.out.println("ValorFuturo = " +
bean.getValorFuturo());
}
}
Pgina HTML Inicial
<html>
<body>
<form action=jsp/aluno01/exercicio16/JurosCompostos.jsp>
Principal: <input type=text name=principal>
Taxa de Juros: <input type=text name=taxaDeJuros>
Anos: <input type=text name=anos>
<input type=submit value=Calcular Valor Futuro>
</form>
</body>
</html>
Pgina JSP denominada JurosCompostos.jsp
<%@ page import=jsp.aluno01.exercicio16.JurosCompostosBean %>
<jsp:useBean id=calculadora class=JurosCompostosBean >
<jsp:setProperty name=calculadora property=principal />
<jsp:setProperty name=calculadora property=taxaDeJuros />
<jsp:setProperty name=calculadora property=anos />
</jsp:useBean>
<html>
<body>
Se voc investir R$<jsp:getProperty name=calculadora
property=principal /> por
<jsp:getProperty name=calculadora property=anos />
anos a uma taxa de juros compostos de
<jsp:getProperty name=calculadora property=taxaDeJuros />, voc
receber R$<jsp:getProperty name=calculadora property=valorFuturo/>.
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 90
Exemplo de Resposta
Se voc investir R$1000,00 por 10 anos a uma taxa de juros compostos
de 0.15, voc receber R$87.541,99.
6.3 Interfaces Definidas para Beans
H uma srie de interfaces que podem ser implementadas por um Bean para aumentar
sua funcionalidade.
6.3.1 A Interface Serializable
Alguns servidores web suportam sesses por tempo indefinido escrevendo os dados da
sesso (inclusive os Beans) em disco entre shutdowns do servidor. Quando o servidor
reiniciado, os dados serializados so recuperados. O mesmo raciocnio se aplica a
servidores que suportam clustering em ambientes de trfego pesado. Muitos deles
utilizam serializao para replicar dados de sesses entre um grupo de servidores web.
Se um Bean no implementa a interface Serializable, o servidor no ser capaz de
armazenar ou transferir os dados do Bean numa situao deste tipo.
O atributo beanName do tag <jsp:useBean> utilizado para instanciar Beans
serializados em vez de criar uma nova instncia do Bean a partir de um arquivo de
classe.
6.3.2 A Interface HttpSessionBindingListener
O fato de um arquivo de classe JavaBean implementar esta interface, habilita suas
instncias a receber notificaes sobre eventos ocorridos com sesses do usurio.
Esta interface bastante simples e possui apenas dois mtodos:
public void valueBound (HttpSessionBindingEvent event)
public void valueUnbound (HttpSessionBindingEvent event)
O mtodo valueBound chamado quando o Bean armazenado em uma sesso do
usurio. Isto ocorre logo aps um Bean, com o escopo de sesso, ser instanciado
atravs do tag <jsp:useBean>.
E o mtodo valueUnbound chamado quando o Bean removido de uma sesso. Isto
ocorre quando o tempo de uma sesso expira. Neste caso o container JSP necessita
primeiramente remover cada item da sesso, disparando a notificao valueUnbound.
O container JSP ir automaticamente reconhecer que o Bean implementa a interface
HttpSessionBindingListener, logo, no h necessidade de registrar o Bean no
container como um listener. Este evento tambm ocorre se o Bean for intencionalmente
retirado de uma sesso atravs de cdigo Java.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 91
Implementando esta interface possvel reagir a eventos de sesso, por exemplo,
fechando conexes de banco de dados que no so mais necessrias, efetuar o log de
transaes, ou executar outras atividades de manuteno. Se o Bean armazena os dados
persistentes em um banco de dados, por exemplo, esta seria a hora de salvar estes
dados no banco.
6.4 Misturando Scriptlets e Bean Tags
6.4.1 Acessando Beans Atravs de Scriptlets
Como o tag <jsp:useBean> cria uma referncia para um objeto, o programador est
livre para acessar este objeto atravs de scriptlets e expresses, assim:
<jsp:useBean id=stocks classStockMarketBean scope=page />
O ndice Dow est em <jsp:getProperty name=stocks property=dow />
pontos.
Ou
<jsp:useBean id=stocks classStockMarketBean scope=page />
O ndice Dow est em <%= stocks.getDow() %> pontos.
Se um pouco de cdigo Java dentro da pgina no incomoda, esta uma forma
alternativa de se obter o valor de uma propriedade. No entanto, no se pode assumir
que uma propriedade de um Bean retorna sempre um String ou algo que possa ser
convertido em um String.
6.4.2 Acessando Objetos Criados Atravs de Scriptlets
O contrrio desta operao no verdade. Objetos criados atravs de scriptlets nem
sempre podem ser acessados atravs de tags de acesso a Beans, pois no h como
garantir que estes objetos faro parte do contexto de uma pgina. O cdigo abaixo, por
exemplo, no vlido na maioria dos containers JSP:
<html>
<body>
<% Carro carro = (Carro) request.getAttribute(Carro); %>
<% carro.atualizarRegistros(); %>
Este carro possui <jsp:getProperty name=carro
property=kilometragem /> kilmetros rodados.
</body>
</html>
Este exemplo no funcionar pois o tag <jsp:getProperty> no ter uma referncia
para o objeto carro uma vez que seu escopo no foi colocado dentro da pgina atravs
do tag <jsp:useBean>.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 92
O cdigo correto seria:
<html>
<body>
<jsp:useBean id=carro class=Carro scope=request />
<% carro.atualizarRegistros(); %>
Este carro possui <jsp:getProperty name=carro
property=kilometragem /> kilmetros rodados.
</body>
</html>
Note que possvel acessar o objeto atravs de scriptlets e de tags JSP, o que
possibilita a chamada direta do mtodo atualizarRegistros().
Tratando Propriedades indexadas
Esta tcnica particularmente til no trato de propriedades indexadas. JSP no prov
uma forma mais simples de lidar com estas propriedades, alm dos tags customizados
que sero apresentados mais adiante. Aqui foram aplicados os mesmos princpios:
objetos foram criados com o tag <jsp:useBean>, e referenciados atravs de scriptlets e
expresses. Neste exemplo, MusicCollectionBean contm um array de objetos
Album, aninhados na propriedade albums. Cada objeto Album, por sua vez possui uma
srie de propriedades. Observe que devemos declarar uma referncia ao objeto Album
atravs de um tag de acesso a Beans.
<jsp:useBean id=music class=MusicCollectionBean />
<jsp:useBean id=album class=Album />
<%
Album[] albuns = music.getAlbums();
For (int j = 0; j < albuns.length; j++)
{ album = albuns[j];
%>
Title: <jsp:getProperty name=album property=title /><BR>
Artist: <jsp:getProperty name=album property=artist /><BR>
Year: <jsp:getProperty name=album property=year /><BR>
<%
}
%>
Este cdigo percorrer todos os albuns retornados pelo mtodo getAlbums(). Cada um
destes albums atribudo varivel album. Esta varivel (que contm um objeto) ,
ento, tratada como um Bean. Para acessar as propriedades do Bean so utilizados tags
<jsp:getProperty>.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 93
Outros Mtodos de Beans
Nem todos os mtodos de um Bean necessitam seguir a conveno estipulada para
Beans, embora apenas os mtodos que podem ser encontrados atravs de introspeco
estaro disponveis para uso atravs de tags JSP. s vezes til prover o acesso
funcionalidade bsica de um Bean atravs de tags JSP, e uma funcionalidade mais
avanada atravs de scriptlet.
Removendo um Bean
Quando a vida de um Bean se encerra (em funo de seu escopo), todas as referncias
para o Bean so removidas e a rea de memria ocupada por ele recuperada pelo
coletor de lixo. H, no entanto, vrias situaes em que pode ser necessrio encerrar
prematuramente a vida de um Bean. A primeira situao ocorre quando necessrio
liberar memria por questes de desempenho. Quando um Bean no mais necessrio,
especialmente aqueles com escopo de sesso ou de aplicao, uma boa idia remov-
lo.
Uma outra razo para se remover um Bean decorre de questes de segurana. Um bom
exemplo deste tipo de situao seria a remoo de informaes de login de um usurio
de um objeto sesso quando o usurio informa que est se desconectando. Uma
abordagem tpica para autenticao do usurio com JSP colocar as credenciais de
login do usurio em um objeto sesso aps um login bem sucedido. A presena destas
credenciais no objeto sesso satisfaz os requisitos de login em futuras visitas a pginas
protegidas at que a sesso expire. Por razes de segurana, no entanto, interessante
remover estas credenciais de login do objeto sesso quando o usurio encerra sua
visita. possvel fazer isto simplesmente removendo suas credenciais da sesso,
retornando-as a um estado no autenticado. Os mtodos disponveis vm resumidos
abaixo:
Como discutido nos captulos anteriores, JSP define uma srie de objetos que refletem
informaes sobre o ambiente. O objeto request encapsula informaes sobre a
requisio e possui vrias propriedades que podem ser acessadas atravs de tags de
acesso a Beans. Como outros Beans, possvel acessar as propriedades do objeto
request atravs do tag <jsp:getProperty>. O valor id designado ao objeto request
implcito request.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 94
Por exemplo, possvel exibir o nome do usurio remoto assim:
<jsp:getProperty name=request property=remoteUser />
A tabela abaixo resume alguns dos mtodos mais teis do objeto request, que podem
ser expostos como propriedades.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 95
7. TRABALHANDO COM BANCOS DE DADOS
No faz parte do escopo deste captulo apresentar a API JDBC. Para quem no est
familiarizado com esta API, h uma srie de tutoriais sobre o assunto no site da Sun
Microsystems. Veja http://java.sun.com/products/jdbc.
O objetivo principal deste captulo apresentar o relacionamento existente entre JSP e
JDBC.
7.1 JSP e JDBC
Diferentemente de outras linguagens de script para a web como ColdFusion, Server
Side JavaScript e PHP, JSP no define seu prprio conjunto de tags para acesso a
bancos de dados. Em vez de desenvolver um outro mecanismo para acesso a bancos de
dados, os projetistas de JSP optaram por utilizar a API Java desenvolvida para este fim:
JDBC.
Quando uma aplicao JSP necessita se comunicar com um banco de dados, ela faz
isso atravs de uma classe driver, fornecida pelo vendedor do SGBD, escrita para a API
JDBC. Na prtica, geralmente se procura isolar o acesso a banco de dados dentro de um
servlet ou Bean, mantendo os detalhes escondidos dos aspectos de apresentao da
pgina JSP.
As classes JDBC fazem parte do package java.sql, e devem ser importadas por
qualquer classe java que as deseje utilizar, inclusive pginas JSP. Extenses opcionais
para a verso 2.0 da API JDBC podem ser encontradas no package javax.sql. Se o
driver JDBC no estiver no class path do container JSP, ser preciso import-lo na
pgina ou referenci-lo pelo seu nome completamente qualificado.
7.1.1 JNDI e Data Sources
No ColdFusion e em outros sistemas semelhantes, um banco de dados acessado
atravs de um nico identificador que corresponde a uma conexo de banco de dados
pr-configurada (ou a um pool de conexes) designada pelo administrador do sistema.
Isto faz com que informaes de conexo com o banco de dados sejam eliminadas do
cdigo, que se refere ao banco de dados atravs de um nome lgico, como
EmpregadosBD ou VendasBD. Os detalhes da conexo com o banco de dados no
aparecem no cdigo da aplicao. Se uma nova classe de driver se torna disponvel, ou
se o servidor de banco de dados modificado, ou informaes de login so
modificadas, apenas este nome lgico necessita ser reconfigurado. Nenhum
componente ou cdigo que faz referncia a este nome precisa ser alterado.
JSP no define seu prprio sistema de gerenciamento de recursos de banco de dados.
possvel utilizar a interface Datasource de JDBC 2.0 e a tecnologia Javas Naming
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 96
and Directory Interface (JNDI) para nomear e localizar servios. JNDI pode ser
utilizado para esconder do cdigo de uma aplicao os detalhes para o acesso a um
banco de dados como, a classe do driver, o nome do usurio, a password, e o URL de
conexo. Para criar uma conexo de banco de dados com JNDI preciso especificar o
nome de um recurso (ou nome de servio) que corresponda a uma entrada em um
banco de dados. Isto protege o cdigo JSP e os componentes suportados, em relao a
mudanas de configurao do banco de dados.
Mais informaes sobre JNDI podem ser encontradas no site da Sun em
http://java.sun.com/products/jndi.
Abaixo vem um exemplo de criao de uma conexo a partir de um data source
definido no registro do JNDI:
Context ctx = new InitialContext();
DataSource ds = (DataSource) ctx.lookup(jdbc/SalesBD);
Connection conn = ds.getConnection(username, password);
possvel melhorar esta abstrao, e simplificar ainda mais o acesso a bancos de
dados, atravs de tags customizados que utilizam JNDI para permitir acesso a recursos
de bancos de dados nomeados, de forma similar ao ColdFusion e outras linguagens
baseadas em tags.
7.2 Aplicaes de Banco de Dados com JSP
7.2.1 Criando Componentes JSP a partir de Dados de uma Tabela
Uma das reas mais comuns para a utilizao de bancos de dados com aplicaes JSP
a recuperao de dados armazenados em uma ou mais tabelas para criar um Bean que
utilizado em uma pgina. A configurao de componentes JSP a partir de informaes
armazenadas no banco de dados simples se o esquema da tabela (ou o resultado de
joins entre tabelas) corresponde s propriedades do Bean. Os mtodos de acesso a
linhas (da classe Resultset) so utilizados para configurar as propriedades do Bean
com os valores das colunas correspondentes. Se o result set possui mais de uma linha
preciso criar uma coleo de Beans, um para cada linha do resultado.
Beans de Banco de Dados a partir de Scriptlets
possvel utilizar scriptlets JSP para configurar as propriedades de um Bean quando
ele criado. Aps estabelecer a conexo, designe para cada propriedade os valores
armazenados no ResultSet. importante no esquecer de importar o package
java.sql com a diretiva <%@ page import=java.sql.* %>.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 97
Neste exemplo foi utilizada a classe ProdutoBean para representar um produto
particular de estoque, obtendo-se o nmero do produto a partir do objeto request.
<%@ page import="java.sql.*, jsp.aluno01.exercicio17.*" %>
<jsp:useBean id="produto" class="ProdutoBean">
<%
Connection connection = null;
Statement statement = null;
ResultSet results = null;
try
{ Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@sbd:1521:orcl";
String id = request.getParameter("id");
String query = "SELECT * FROM PRODUTOS WHERE ID = " + id;
connection = DriverManager.getConnection(url, "java01", "java01");
statement = connection.createStatement();
results = statement.executeQuery(query);
if (results.next())
{ produto.setId(results.getInt("ID"));
produto.setDescricao(results.getString("DESCRICAO"));
produto.setPreco(results.getDouble("PRECO"));
produto.setEstoque(results.getInt("QTD_ESTOQUE"));
}
connection.close();
}
catch (ClassNotFoundException e)
{ System.err.println("No conseguiu carregar o driver!");
}
catch (SQLException e)
{ System.err.println("No conseguiu conectar-se ao banco!");
}
finally
{ try
{ if (connection != null) connection.close();
}
catch (SQLException e){ }
}
%>
</jsp:useBean>
<html>
<body>
<table>
<tr><td>Nmero do Produto</td><td>
<jsp:getProperty name="produto" property="id"/></td></td>
<tr><td>Descrio</td><td>
<jsp:getProperty name="produto" property="descricao"/></td></td>
<tr><td>Preo</td><td>
<jsp:getProperty name="produto" property="preco"/></td></tr>
<tr><td>Qtd em Estoque</td><td>
<jsp:getProperty name="produto" property="estoque"/></td></tr>
</table>
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 98
Quando este cdigo encerrar sua execuo teremos um ProdutoBean que estar vazio
(Caso o SELECT no encontre nada) ou populado com dados da tabela de produtos.
Aps criar o Bean e utilizar o banco de dados para popul-lo, suas propriedades so
exibidas. Com esta abordagem h muito cdigo java e uma pequena quantidade de
cdigo HTML para suportar a apresentao. Se for necessrio construir diversas pginas
com necessidades semelhantes ser preciso reprogramar todo este cdigo diversas
vezes.
Beans Auto-Populados
possvel utilizar uma tcnica semelhante a esta utilizada no exemplo acima para criar
Beans que se populam a si prprios. No construtor do Bean pode-se estabelecer uma
conexo de banco de dados, executar a query, designar os valores das propriedades,
fechar a conexo, e pronto! Tambm possvel definir algumas das propriedades do
Bean como gatilhos que fazem com que o Bean recupere dados do banco de dados,
incluindo o cdigo de acesso ao banco de dados dentro do mtodo de acesso. Por
exemplo, a mudana da propriedade id do Bean ItemBean poderia provocar uma
busca no banco de dados objetivando popular as demais propriedades.
Influncias Externas
Como vamos aprender no captulo 8, geralmente desejvel manter o cdigo Java em
uma pgina JSP o menor possvel. Outra alternativa seria a utilizao de servlets para
empacotar em Beans, os dados recuperados do banco de dados que sero utilizados por
pginas JSP. A diferena que com um servlet possvel compartilhar e reutilizar
conexes de banco de dados. Assim possvel mover a gerncia de conexes de banco
de dados e de colees de dados para fora da pgina.
7.2.2 Tipos de Dados JSP e JDBC
Dados Inteiros
JDBC define quatro tipos SQL para tratar dados inteiros, mas a maioria dos SGBDs
suportam apenas dois: SMALLINT que representa nmeros inteiros de 16-bits tratados
por Java como short, e o tipo INTEGER mapeado em Java para int.
Nmeros Ponto-Flutuante
Existem dois tipos de dados ponto-flutuantes especificados por JDBC: DOUBLE e FLOAT.
Na prtica, so essencialmente a mesma coisa. A Sun recomenda que os
programadores utilizem o tipo SQL DOUBLE que mapeado para o tipo Java double.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 99
Tratando Nulos
Se uma coluna de uma tabela de banco de dados no possui um valor, ela ser
designada para null. O problema que no h uma boa forma de se representar um
valor vazio com os tipos primitivos int e double, que no so objetos e no podem ser
designados para null. Por exemplo, uma chamada a getInt() poderia retornar 0 ou
1 para indicar null, mas estes dois valores so vlidos. O problema tambm existe
para Strings. Alguns drivers retornam um String vazio (), alguns retornam null e
outros o String null. A soluo, que no particularmente elegante, mas funciona,
a utilizao do mtodo wasNull() de ResultSet.
Este mesmo problema existe quando so criados componentes JSP a partir de
Componentes JavaBeans. A interpretao de um valor null pelo tag <jsp:getProperty>
no consistente entre vendedores, logo, se no possvel a utilizao de um valor
literal para representar um null, a soluo est em se definir uma propriedade boleana
que ir indicar a validade do valor da propriedade em questo. Quando um null
encontrado no banco de dados, designamos esta propriedade para um valor no nulo, e
designamos uma outra propriedade para false, com a inteno de indicar que o valor
da primeira propriedade null. Exemplo:
init()
{ . . .
quantidade = results.getint(QTD_DISPONIVEL);
if (results.wasNull())
{ quantidade = 0;
quantidadeValida = false;
}
else
{ quantidadeValida = true;
}
. . .
}
isQuantidadeValida()
{ return quantidadeValida;
}
Naturalmente, isto significa que a verificao de validade da informao necessitar
ser efetuada antes de se utilizar o valor correspondente no cdigo JSP:
Quantidade Disponvel:
<% if (item.isQuantidadeValida()) %>
<jsp:getProperty name=item property=quantidade /> unidades
<% else %>
Desconhecida
Uma forma alternativa, caso o valor esteja sendo utilizado pela pgina JSP apenas para
exibio, a definio de uma propriedade String que retorne um valor apropriado,
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 100
independentemente do estado da propriedade. Esta abordagem, embora mais simples,
limita a flexibilidade do Bean.
getQuantidadeString()
{ if (quantidadeValida)
return new Integer(quantidade).toString();
else
return Desconhecido;
}
A forma mais simples de evitar este problema irritante impedir que valores nulos
sejam cadastrados no banco de dados.
7.2.3 Mantendo Conexes Persistentes
Em algumas situaes interessante utilizar uma mesma conexo de banco de dados
atravs de vrias requisies de um mesmo cliente. No entanto, preciso ser cuidadoso
ao se utilizar esta abordagem uma vez que o nmero de conexes de banco de dados
que um servidor pode suportar limitado. Em diversas situaes conveniente utilizar
uma mesma conexo para vrios usurios simultneos. A abordagem que utiliza uma
conexo para cada usurio no interessante, por exemplo, quando trfego alto.
Como o estabelecimento de uma conexo com um banco de dados talvez a parte mais
lenta de uma aplicao, sempre que possvel interessante compartilhar uma mesma
conexo com mais de um usurio simultneo.
H uma srie de solues para este problema. Pools de conexes implementados
atravs de drivers de banco de dados ou atravs de uma classe prpria mantm um
nmero fixo de conexes ativas, e as emprestam quando solicitadas por pginas JSP ou
Beans. Um pool de conexes um meio termo entre ter muitas conexes abertas, e se
pagar o preo das freqentes conexes e desconexes.
O cdigo abaixo cria um Bean que encapsula uma conexo de banco de dados. Atravs
da utilizao deste Bean os detalhes referentes conexo com o banco de dados ficam
escondidos da pgina JSP, e atravs do armazenamento do objeto connection em um
objeto session, possvel a reutilizao desta conexo por vrias pginas JSP.
package jsp.aluno01.exercicio18;
import java.sql.*;
import javax.servlet.http.*;
public class ConnectionBean implements HttpSessionBindingListener
{ private Connection connection;
private Statement statement;
private static final String
driver="oracle.jdbc.driver.OracleDriver";
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 101
private static final String dbURL =
"jdbc:oracle:thin:@sbd:1521:orcl";
private static final String login="carlos";
private static final String password="carlos";
public ConnectionBean()
{ try
{ Class.forName(driver);
connection =
DriverManager.getConnection(dbURL,login,password);
statement=connection.createStatement();
}
catch (ClassNotFoundException e)
{ System.err.println
("ConnectionBean: o driver no foi encontrado.");
connection = null;
}
catch (SQLException e)
{ System.err.println("ConnectionBean: erro na conexo.");
connection = null;
}
}
public Connection getConnection()
{ return connection;
}
public void commit() throws SQLException
{ connection.commit();
}
public void rollback() throws SQLException
{ connection.rollback();
}
public void setAutoCommit(boolean autoCommit)
throws SQLException
{ connection.setAutoCommit(autoCommit );
}
public ResultSet executeQuery(String sql)
throws SQLException
{ return statement.executeQuery(sql);
}
public int executeUpdate(String sql)
throws SQLException
{ return statement.executeUpdate(sql);
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 102
public void valueBound(HttpSessionBindingEvent event)
{ System.err.println
("ConnectionBean: executando o mtodo valueBound.");
try
{ if (connection == null || connection.isClosed())
{ connection = DriverManager.getConnection
(dbURL,login,password);
statement = connection.createStatement();
}
}
catch (SQLException e)
{ connection = null;
}
}
public void valueUnbound(HttpSessionBindingEvent event)
{ try
{ connection.close();
}
catch (SQLException e) { }
finally
{ connection = null;
}
}
protected void finalize()
{ try
{ connection.close();
}
catch (SQLException e) { }
}
}
A classe ConnectionBean implementa a interface HttpSessionBindingListener, o
que faz com que seu mtodo valueUnbound() seja executado se o Bean for removido
da sesso. Isto evita que a conexo viva por mais tempo do que o necessrio.
Vale observar ainda que este Bean poderia aceitar valores de configurao (url,
username, password e driver) como propriedades que a pgina JSP teria de designar
para ativar a conexo.
7.2.4 Manipulando Grandes Conjuntos de Resultados
Se uma query retorna uma grande quantidade de linhas, provavelmente no ser
interessante exibi-las todas de uma vez. Por exemplo, uma tabela de 15000 linhas
difcil de ler, e o download e exibio do cdigo HTML gerado pela pgina JSP pode
consumir um tempo considervel. Se o projeto da aplicao permite, interessante
limitar a quantidade de linhas que a query pode retornar.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 103
Uma soluo para este problema apresentar o resultado em uma pgina de cada vez.
H uma srie de abordagens para resolver este problema com JSP. A interface RowSet
foi introduzida em JDBC 2.0 para definir uma forma padro de acesso a dados cached
atravs de um componente Javabeans.
Criando um ResultSet Persistente
Quando se recupera um objeto ResultSet a partir de uma query, nem todo o resultado
armazenado na memria. O banco de dados mantm a conexo com o banco de
dados e transfere as linhas a medida que elas forem acessadas. Este comportamento
mantm o trfego e os requisitos de memria baixos, mas significa que a conexo com
o banco de dados ser mantida por mais tempo. O driver de banco de dados
determinar o nmero timo de linhas a serem recuperadas de cada vez, ou, com JDBC
2.0, possvel oferecer uma sugesto ao driver. A busca de novas linhas ocorre
automaticamente a medida que se avana no ResultSet.
Uma estratgia que pode ser utilizada para a exibio do resultado de uma query
pgina a pgina, o armazenamento do objeto ResultSet em um objeto session. A
cada nova solicitao do usurio este objeto ResultSet utilizado para retornar mais
20 linhas. A posio do cursor interna ao ResultSet no mudar entre requisies.
No necessrio manter uma referncia ao objeto Connection original, pois o objeto
ResultSet j armazena esta informao. Quando o ResultSet estiver fora de escopo e
o coletor de lixo o retirar da memria, a conexo com o banco ser fechada. Tambm
seria possvel embutir o ResultSet em um Bean e implementar
HttpSessionBindingListener para fechar a conexo com o banco de dados assim
que o ResultSet no for mais necessrio, isto , quando o Bean for removido da
sesso, ou definir um mtodo pblico de limpeza que seria chamado no final da pgina
JSP. Um problema com esta abordagem que a conexo com o banco de dados est
sendo mantida aberta por muito tempo. A seguir so apresentadas duas outras
abordagens nas quais a conexo com o banco no mantida aberta enquanto o usurio
examina cada pgina da resposta.
Executando a Query Diversas Vezes
A cada solicitao do usurio, a query original reexecutada. Nesta abordagem o
mtodo next() (ou o mtodo absolute() de JDBC 2.0) utilizado para desprezar
algumas linhas da tabela e comear a listar, digamos, as prximas 20 linhas, a partir da
posio solicitada. E para o usurio saber em que posio ele se encontra (por
exemplo, pgina 1 de 5), basta enviar tambm o tamanho do ResultSet. Um problema
com esta abordagem que o banco de dados pesquisado a cada nova solicitao do
usurio. Se os dados forem modificados entre requisies, a informao encaminhada
ao usurio poder mudar.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 104
Utilizando uma Query que se Imponha Limites
A estratgia aqui exibir uma pgina de dados e armazenar a chave primria do ltimo
item exibido. Logo, para cada pgina que se emitir uma nova query, a pesquisa poder
ser aperfeioada incluindo-se na clusula WHERE uma condio que limite o resultado
da busca quelas informaes que ainda no foram mostradas ao usurio.
Este mtodo funciona bem em situaes onde os dados so listados na ordem da chave
primria.
O Bean CachedRowset
Uma forma alternativa de se tratar resultados de queries no muito grandes aqueles
maiores do que uma pgina, mas no to grande a ponto de consumir toda a memria
atravs de CachedRowSet. No incio do ano 2000 a Sun estava desenvolvendo uma
implementao de uma interface JDBC 2.0 denominada RowSet, que encapsula uma
conexo de banco de dados e resultados de query associados em um componente
JavaBean denominado CachedRowset. Este Bean prov um container (desconectado
do banco) que pode ser percorrido (em uma pgina JSP ou em outro JavaBean) no
estilo de um result set. Esta uma ferramenta muito til para se trabalhar com bancos
de dados utilizando-se JSP. Diferentemente do ResultSet, CachedRowSet armazena
em um objeto todas as linhas resultantes da query emitida. Uma conexo ativa no
necessria pois todos os dados so recuperados do banco de dados. Se o resultado de
uma query muito grande, provavelmente mais interessante utilizar um result set
persistente.
Para se utilizar o CachedRowSet configure as propriedades como username,
password, e o URL do banco de dados e ento, designe um valor para a propriedade
command. Este valor deve ser uma query SQL. Isto ir popular o rowset com resultados
que podero ento ser percorridos. Tambm possvel popular CachedRowSet
utilizando um objeto RowSet, criado a partir de outra query.
Exemplo: Paginando Atravs de Resultados com um CahedRowSet
Vem abaixo um exemplo de paginao atravs de uma srie de resultados utilizando o
Bean CachedRowSet da Sun e JSP. Esta pgina JSP permite que o usurio visualize 5
linhas de cada vez, ou volte para a primeira linha se desejar. A mesma tcnica poderia
ser utilizada com um ResultSet persistente, no entanto seria necessrio recorrer a
scriptlets JSP ou empacotar o objeto ResultSet em um Bean.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 105
<%@ page import="java.sql.*,javax.sql.*,sun.jdbc.rowset.*" %>
<jsp:useBean id="crs" class="CachedRowSet" scope="session">
<% try { Class.forName("oracle.jdbc.driver.OracleDriver"); }
catch (ClassNotFoundException e)
{ System.err.println("Error" + e);
}
%>
<jsp:setProperty name="crs" property="url"
value="jdbc:oracle:thin:@sbd:1521:orcl"/>
<jsp:setProperty name="crs" property="username" value="carlos" />
<jsp:setProperty name="crs" property="password" value="carlos" />
<jsp:setProperty name="crs" property="command"
value="select * from voos order by id" />
<% try { crs.execute(); }
catch (SQLException e) { out.println("SQL Error: " + e); }
%>
</jsp:useBean>
<html>
<body>
<center>
<h2>Cached Query Results</h2>
<P>
<table border="2">
<tr bgcolor="tan">
<th>id</th><th>Airport</th><th>Departure</th><th>Seats</th></tr>
<% try {
if ("first".equals(request.getParameter("action")))
crs.beforeFirst();
for (int i=0; (i < 5) && crs.next(); i++) {
%>
<tr>
<td><%= crs.getString("id") %></td>
<td><%= crs.getString("airport") %></td>
<td><%= crs.getString("time") %></td>
<td><%= crs.getString("seats") %></td>
</tr>
<% } %>
</table>
</p>
<% if (crs.isAfterLast()) {
crs.beforeFirst(); %>
<br>At the end of the result set<br>
<% } }
catch (SQLException e) { out.println("SQL Error" + e); }
%>
<a href="<%= HttpUtils.getRequestURL(request) %>?action=first">
[Primeiros 5]</a>&nbsp;
<a href="<%= HttpUtils.getRequestURL(request) %>?action=next">
[Prximos 5]</a>&nbsp;
</center>
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 106
Este exemplo cria, atravs do tag <jsp:useBean>, um Bean com escopo de sesso, e
utiliza o corpo do tag para configur-lo e executar a query. importante saber que
preciso informar a classe do driver que ser utilizado antes de designar um valor para a
propriedade URL. Se o usurio clicar em um dos dois links na base da pgina, um
parmetro de requisio designado para indicar a ao desejada. Como o Bean
CachedRowSet armazenado dentro da sesso do usurio, a posio do cursor no
mudar entre requisies, e os dados sero recuperados a cada nova consulta a partir da
posio corrente do cursor. O loop se encerra aps cinco iteraes ou quando o mtodo
crs.next() retorna false.
Note o seguinte cdigo, perto do final do exemplo:
<a href=<%= HttpUtils.getRequestURL(request) %>?action=next>
O mtodo HttpUtils.getRequestURL(request) (parte do package javax.servlet,
que automaticamente importado pela pgina JSP) cria um link para a pgina corrente.
Isto faz com que no seja necessrio escrever o URL corrente.
7.3 Exemplo: Ferramenta para Controle de Reservas para Conferncias
Este captulo ser finalizado com um exemplo que engloba os aspectos abordados ao
longo deste captulo: recuperao de dados, conexes persistentes e o processamento
de transaes englobando vrias pginas. Neste exemplo, o enfoque principal o
cdigo utilizado para o acesso ao banco de dados. No prximo captulo ser abordada a
questo referente arquitetura da aplicao.
7.3.1 Resumo do Projeto
Este projeto foi construdo para suportar uma conferncia sobre JSP a ser realizada em
vrias cidades dos EUA. Primeiramente, preciso determinar a que conferncia
(cidade) o usurio planeja assistir para se poder reservar um lugar para ele. Em
segundo lugar, preciso tambm reservar um assento em um dos nibus que iro
transportar os participantes, de um aeroporto para a conferncia. Um participante, aps
reservar um ingresso para a conferncia, deve reservar um assento em um nibus que o
transportar do aeroporto at a conferncia. Enquanto o usurio no decide sobre o
horrio do nibus que deseja reservar, o sistema deve cuidar para que o ingresso
reservado por ele no seja vendido a outro. Esta situao bastante real se pensarmos
que milhares de pessoas espalhadas pelo mundo podem estar se registrando
simultaneamente.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 107
7.3.2 O Banco de Dados
Para este exemplo so necessrias duas tabelas: CONFERENCIAS e TRANSPORTES, com o
layout especificado abaixo.
CONFERENCIAS
ID NUMBER(5) PK
CIDADE VARCHAR2(80)
AEROPORTO CHAR(3)
ASSENTOS NUMBER(3)
TRANSPORTES
ID NUMBER(5) PK e FK
AEROPORTO CHAR(3) PK
DATA_HORA DATE PK
ASSENTOS NUMBER(3)
7.3.3 Resumo do Projeto
O processo de reserva em uma conferncia possui 4 passos bsicos: a escolha da
cidade, a escolha do horrio do nibus, a reviso das selees, e a confirmao da
transao.
apresentado a cada usurio uma lista das cidades onde a conferncia ir ocorrer. O
usurio poder escolher uma cidade onde ainda haja vagas. Uma vez realizada a
escolha, uma transao com o banco de dados se inicia, reservando uma vaga na
conferncia para a cidade escolhida. Isto ir garantir que o usurio no perder sua
vaga na conferncia enquanto escolhe que nibus o levar ao local da conferncia. A
escolha do nibus o segundo passo. Nos passos 3 e 4 o usurio rev suas opes,
quando ter a opo de confirm-las ou cancel-las. A confirmao faz com que estes
dados sejam comitados no banco, e o cancelamento aborta o processo, liberando o
assento reservado pelo usurio para a conferncia na cidade escolhida.
Para manter uma transao entre vrias pginas, como ocorre neste exemplo, preciso
utilizar a capacidade que JSP possui de manter a conexo com o banco de dados
armazenada no objeto sesso que ir empacotar o Bean ConnectionBean, construdo
anteriormente neste captulo. Tambm foi preciso criar uma pgina para tratamento de
erros que possam ocorrer ao longo da execuo da aplicao.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 108
Passo 1: Conferencia.jsp
A pgina abaixo apresenta ao usurio uma lista de cidades onde a conferncia ir
ocorrer. Esta lista extrada de uma tabela de banco de dados. Cabe ao usurio fazer a
sua escolha.
<%@ page import="java.sql.*, jsp.aluno01.exercicio18.ConnectionBean"
errorPage="error.jsp" %>
<jsp:useBean id="connection" class="ConnectionBean" scope="session"/>
<html>
<body>
<center>
<font size="+2" face="arial"><b>Registro em Conferncia</b></font>
<form action="transporte.jsp" method="post">
<table border=1 bgcolor="tan" width="50%" align="center">
<tr><td>
<table border="0" bgcolor="white" cellspacing=0 width="100%">
<tr bgcolor="tan">
<th>&nbsp;</th><th>Cidade</th><th>Vagas</th></tr>
<%
String sql = "SELECT * FROM CONFERENCIAS";
ResultSet resultados = connection.executeQuery(sql);
while (resultados.next())
{ if (resultados.getInt("ASSENTOS") > 0)
{ %> <td>
<input type="radio" name="idConferencia"
value="<%= resultados.getString("ID") %>">
</td>
<% }
else
{ %> <td>&nbsp;</td>
<% } %>
<td><%= resultados.getString("CIDADE") %></td>
<td align="center"><%=resultados.getString("ASSENTOS") %></td>
</tr>
<% } %>
</table>
</td>
</tr>
</table>
<p>
<input type="submit" value="Prxima (Escolha do nibus)">
</form>
</center>
</body>
</html>
Observe que esta pgina esconde informaes de conexo com o banco de dados
atravs do Bean ConnectionBean. No foi preciso fazer nada de especial para
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 109
configur-lo. De fato, cada pgina desta aplicao comea com um bloco de cdigo
que importa as classes de banco de dados utilizadas pela aplicao, e referencia o Bean
ConnectionBean armazenado na sesso, ou cria uma instncia de ConnectionBean e a
armazena no objeto sesso.
Uma vez estabelecida uma conexo com o banco de dados possvel construir o
formulrio utilizando-se dados provenientes da tabela de CONFERENCIAS atravs da
execuo da query apropriada e da utilizao de um loop para acessar as diversas
linhas da tabela.
E um clique no boto Escolher Transporte, faz com que a prxima pgina da
aplicao seja executada: transporte.jsp.
Passo 2: Transporte.jsp
A pgina de seleo do transporte possui dupla funo: primeiramente ela necessita
processar a seleo efetuada na pgina conferencia.jsp. preciso reservar para o
usurio um assento na conferncia selecionada. Em segundo lugar, preciso apresentar
ao usurio a lista de nibus disponveis (com respectivos horrios) em cada aeroporto
para que o usurio possa selecionar um assento em um destes nibus.
<%@ page import="java.sql.*, jsp.aluno01.exercicio18.ConnectionBean"
errorPage="error.jsp" %>
<jsp:useBean id="connection" class="ConnectionBean" scope="session"/>
<%
String idConferencia = request.getParameter("idConferencia");
connection.setAutoCommit(false);
String sql = "UPDATE CONFERENCIAS " +
"SET ASSENTOS=ASSENTOS - 1 " +
"WHERE ID = " + idConferencia;
connection.executeUpdate(sql);
%>
<html>
<body>
<center>
<font size="+2" face="arial"><b>Reserva do nibus</b></font>
<form action="confirmacao.jsp" method="post">
<table border=1 bgcolor="tan" width="50%" align="center">
<tr><td>
<table border="0" bgcolor="white" cellspacing=0 width="100%">
<tr bgcolor="tan"><th>&nbsp;</th>
<th>Aeroporto</th><th>Hora</th><th>Assentos Disponveis</th></tr>
<%
sql = "SELECT T.* FROM TRANSPORTES T, CONFERENCIAS C " +
"WHERE C.ID = " + idConferencia +
" AND T.AEROPORTO = C.AEROPORTO";
ResultSet resultados = connection.executeQuery(sql);
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 110
while (resultados.next())
{ if (resultados.getInt("ASSENTOS") > 0)
{ %> <td>
<input type="radio" name="idTransporte"
value="<%= resultados.getString("ID") %>">
</td>
<% }
else
{ %> <td>&nbsp;</td>
<% } %>
<td><%= resultados.getString("AEROPORTO") %></td>
<td><%= resultados.getTime("DATA_HORA") %></td>
<td align="center">
<%= resultados.getString("ASSENTOS") %></td>
</tr>
<%
}
%>
</table>
</td>
</tr>
</table>
<input type="hidden" name="idConferencia"
value="<%= idConferencia %>">
<input type="submit" value="Prxima (Rever Reservas)">
</form>
</center>
</body>
</html>
Agora, aps obter uma referncia para o Bean ConnectionBean atravs da sesso,
obtido o ID selecionado para a conferncia. Este ID necessrio para a atualizao da
tabela de TRANSPORTE, e ser transmitido para as pginas seguintes atravs de um
campo HIDDEN, para que o usurio possa confirmar suas selees:
<INPUT TYPE=HIDDEN NAME=SHOW VALUE=<%= showID %>>
Esta informao tambm poderia ser transmitida para outras pginas atravs da sua
incluso no objeto sesso.
Passo 3: Confirmacao.jsp
A funo desta pgina reservar o assento do usurio no nibus que o transportar do
aeroporto at a conferncia, exibir um sumrio de suas selees, e pedir ao usurio que
confirme ou cancele suas selees.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 111
<%@ page import="java.sql.*, jsp.aluno01.exercicio18.ConnectionBean"
errorPage="error.jsp" %>
<jsp:useBean id="connection" class="ConnectionBean" scope="session"/>
<%
String sql;
String idTransporte = request.getParameter("idTransporte");
String idConferencia = request.getParameter("idConferencia");
sql = "UPDATE TRANSPORTES " +
"SET ASSENTOS = ASSENTOS - 1 " +
"WHERE ID = " + idTransporte;
connection.executeUpdate(sql);
sql = "SELECT C.CIDADE, C.AEROPORTO, T.DATA_HORA " +
"FROM CONFERENCIAS C, TRANSPORTES T " +
"WHERE C.ID = " + idConferencia +
" AND T.ID = " + idTransporte;
ResultSet resultados = connection.executeQuery(sql);
resultados.next();
%>
<html>
<body>
<center>
<font size="+2" face="arial"><B>Confirmao de Reserva</b></font>
<form action="fim.jsp" method=post>
<table border=1 bgcolor="tan" width="50%" align="center">
<tr><td>
<table border="0" bgcolor="white" cellspacing=0 width="100%">
<tr bgcolor="tan"><th>Resumo</th></tr>
<tr><td>
Foram solicitadas reservas para a conferncia a se realizar em
<b><%= resultados.getString("CIDADE") %></b>, e para o nibus que o(a)
transportar do aeroporto <b><%= resultados.getString("AEROPORTO")
%></b>
ao local da conferncia. O nibus parte s
<b><%= resultados.getTime("DATA_HORA") %> horas.</b>.
<p>
Para confirmar suas reservas selecione (Confirmar Reservas) abaixo.
</td></tr>
</table>
</td></tr></table>
<p>
<input type="submit" name="commit" value="Confirmar Reservas">
<input type="submit" name="rollback" value="Cancelar Reservas">
</body>
</html>
Passo 4: fim.jsp
Nesta pgina, dependendo da seleo feita pelo usurio, a transao ser confirmada
atravs de um commit, ou desfeita atravs de um rollback no banco de dados.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 112
<%@ page import="java.sql.*, jsp.aluno01.exercicio18.ConnectionBean"
errorPage="error.jsp" %>
<html>
<body>
<%
ConnectionBean connection =
(ConnectionBean)session.getValue("connection");
if (request.getParameter("commit") != null)
connection.commit();
else
connection.rollback();
session.removeAttribute("connection");
%>
<center>
<%
if (request.getParameter("commit") != null)
{ %> <font size="+2" face="arial">
<b>Confirmao de Reservas</b></font>
<p> Suas reservas foram confirmadas, obrigado.
<%
}
else
{ %> <font size="+2" face="arial">
<b>Reservations Canceled</b></font>
<p> Suas reservas foram canceladas.
<%
} %>
<p>
<a href="conferencia.jsp">Efetuar Outra Reserva</a>
</body>
</html>
Aps salvar as modificaes preciso remover o Bean ConnectionBean do objeto
sesso para que seus recursos sejam liberados, especialmente a conexo com o banco
de dados.
session.removeattribute(connection);
E para finalizar, preciso enviar ao usurio uma pgina informando a atitude tomada
pelo sistema em funo do boto por ele selecionado, confirmando ou abortando a
reserva.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 113
A Pgina Error.jsp
Esta pgina responsvel por tratar qualquer erro detectado pela aplicao.
<%@ page import="java.sql.*, jsp.aluno01.exercicio18.ConnectionBean"
isErrorPage="true" %>
<html>
<body>
<%
if (exception instanceof SQLException)
{ try
{ ConnectionBean connection =
(ConnectionBean)session.getAttribute("connection");
connection.getConnection().rollback();
session.removeAttribute("connection");
}
catch (SQLException e) { }
}
%>
<center>
<font size="+2" face="arial"><b>Erro na Aplicao</b></font>
<p> Ocorreu o erro: <tt><%= exception %></tt>
<p>
<a href="conferencia.jsp">Efetuar Outra Reserva</a>
</center>
</body>
</html>
Caso ocorra um erro de banco de dados, ser efetuado o rollback da transao corrente,
e ser removida do objeto sesso a conexo com o bando de dados. Mais detalhes
sobre a criao de pginas de erro sero estudados mais adiante.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 114
8. PROJETANDO APLICAES JSP
O objetivo deste captulo discutir vrios modelos de arquitetura para o
desenvolvimento de aplicaes JSP. Sero analisadas as opes de arquitetura
disponveis levando-se em considerao a combinao de pginas JSP com servlets,
Enterprise JavaBeans, HTML, e outros elementos de software disponveis para a criao
de aplicaes para a web.
8.1 Aplicaes para a Web
Quando uma aplicao para a web de qualquer complexidade projetada,
interessante pensar na aplicao considerando as seguintes reas lgicas:
Camada de Apresentao O front-end que controla o look and feel e entrega os
resultados. Tambm conhecida como vista.
Camada de Controle Responsvel pelo controle do fluxo da aplicao.
Camada da Lgica da Aplicao Responsvel pela gerncia dos dados da
aplicao, execuo de clculos, e comunicao com recursos back-end. Tambm
conhecida como modelo.
Estas trs camadas no so necessariamente elementos ou componentes de software
separados, mas podem ser. Para quem est familiarizado com design patterns, uma
coleo de estratgias comuns utilizadas no desenvolvimento de software, deve
reconhecer nesta arquitetura de trs camadas, uma implementao do padro Model-
View-Controller, ou MVC. Este padro trata da separao da informao (modelo) da
sua apresentao (vista), tudo isso controlado por uma camada intermediria
(controle).
geralmente vantajoso tratar cada camada como uma poro independente da
aplicao.
A Camada da Apresentao
Esta camada inclui os elementos no lado cliente para a exibio de informaes, tais
como HTML, XML, ou Java Applets. Esta camada no se preocupa com a forma como a
informao foi obtida, ou de onde ela veio. Sua nica responsabilidade exibir a
informao. Ela utilizada na obteno de informaes do usurio e na apresentao
do resultado da aplicao.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 115
A Camada da Lgica da Aplicao
Esta camada o corao da aplicao. responsvel por fazer tudo que a aplicao
efetivamente necessita fazer. responsvel pela execuo de queries contra um banco
de dados, clculo de preo da entrega de produtos (incluindo frete, etc), processamento
de pedidos, etc. Esta camada modela os dados e o comportamento por trs dos
processos de negcios, para os quais a aplicao est sendo desenvolvida. o
encapsulamento de dados e comportamento, independente da sua apresentao.
Componentes projetados para trabalhar neste nvel podem ser reutilizados por outras
aplicaes, voltadas para a web ou no.
A Camada de Controle
A camada de controle determina o fluxo da aplicao, servindo como um intermedirio
entre a camada de apresentao e a camada da lgica da aplicao. Esta camada
funciona como uma conexo lgica entre a interao do usurio com o front-end e
servios de negcios no back-end. Esta camada tambm responsvel por tomar
decises entre vrias interfaces possveis, quando disponveis. Se a lngua do usurio,
local, ou nvel de acesso, determina uma apresentao diferente, esta deciso tomada
nesta camada. Por exemplo, um administrador pode ver todos os dados de uma
consulta a um banco de dados, enquanto um usurio final pode ver um resultado mais
restritivo.
Toda requisio entra na aplicao atravs da camada de controle, que decide como a
requisio deve ser tratada e que informao deve ser retornada.
Por exemplo, a camada de controle pode determinar que o URL requisitado protegido,
e neste caso a requisio encaminhada a uma pgina de logon, se o usurio ainda no
foi autenticado. Este um exemplo da lgica da apresentao controlando o fluxo da
aplicao de pgina para pgina. Se uma tarefa da aplicao necessita ser realizada, a
camada da lgica da apresentao responsvel por coletar os dados, enquanto a
camada da lgica da aplicao trata do seu processamento. Quando o processamento
termina, a camada de controle retorna a requisio ao usurio atravs da camada da
apresentao.
8.1.1 O Fluxo de Aplicaes para a Web
Aplicaes para a web so vulnerveis a irregularidades no fluxo da execuo. No se
trata de comportamento malicioso. Um usurio pode efetuar um bookmark no meio de
uma aplicao, ou pode clicar no boto back na tentativa de voltar um passo na
aplicao, ou pode abortar uma operao prematuramente ou tentar recarregar uma
pgina. Em qualquer destas situaes o fluxo da execuo quebrado.
responsabilidade da aplicao JSP garantir que informaes no sejam corrompidas
nestas situaes.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 116
8.1.2 Abordagens de Projeto
No projeto de aplicaes JSP h duas abordagens bsicas para se separar as
responsabilidades de apresentao, controle e lgica da aplicao: page-centric e
servlet-centric.
Na primeira abordagem a responsabilidade do controle e da lgica da aplicao recai
sobre as prprias pginas JSP; J na segunda abordagem um ou mais servlets
intermedirios so utilizados. Uma clara separao de uma aplicao JSP em
subsistemas de apresentao, controle e lgica da aplicao, tornam mais simples o
desenvolvimento e a manuteno da aplicao.
8.2 Projeto Page-Centric
Nesta abordagem a aplicao formada apenas por uma srie de pginas JSP
interrelacionadas que tratam todos os aspectos apresentao, controle e lgica da
aplicao. Nesta abordagem as requisies dos clientes so tratadas diretamente por
pginas JSP que executam todas as tarefas necessrias, como a comunicao com
fontes de dados back-end, execuo de operaes, e a gerao elementos de contedo
dinmico.
Toda a lgica da aplicao e decises de controle sobre que pgina deve ser visitada
em seguida codificada dentro da prpria pgina, ou expressa atravs de Beans,
scriptlets, e expresses em tempo de execuo. Geralmente, a prxima pgina a ser
visitada ser determinada por um clique do usurio em um hiperlink anchor, como por
exemplo, <A HREF=encerramento.jsp> ou atravs da submisso de uma ao de
um formulrio, como: <FORM ACTION=processaPesquisa.jsp>.
8.2.1 Pginas Baseadas em Funes
No modelo de projeto page-centric cada pgina JSP possui uma funo muito
especfica na aplicao. Uma pgina pode exibir um menu de opes, outra pode
apresentar um formulrio para a seleo de produtos de um catlogo, e outra seria
necessria para completar o processo de compra. A figura abaixo mostra como pode
ser o fluxo entre estas pginas.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 117
Esta abordagem combina a lgica da aplicao e as camadas do fluxo de programao
da aplicao a nvel de pgina. Isto no significa que a separao entre apresentao e
contedo seja perdida. A natureza dinmica das pginas JSP e o suporte a componentes
JavaBeans podem ser utilizados para manter as coisas separadas adequadamente. Esta
abordagem opta por utilizar pginas JSP como containers para o controle de fluxo e
lgica da aplicao.
Uma Aplicao Page-Centric Simples
A seguir vem um exemplo de uma aplicao em duas pginas utilizando scriptlets para
a lgica da aplicao. Esta aplicao recruta candidatos para treinamento Jedi. A
primeira pgina, jediform.jsp, contm um formulrio HTML que coleta as informaes
necessrias para efetuar o processamento, e a segunda pgina, jedi.jsp, calcula e exibe
o novo nome do recruta.
Cdigo fonte de jediform.html:
<html>
<body>
<b>Jedi Registration Center</b>
<form action="jediname.jsp" method="post">
<input type="text" name="firstName"> First Name<BR>
<input type="text" name="lastName"> Last Name<BR>
<input type="text" name="mother"> Mother's Maiden Name<BR>
<input type="text" name="hometown"> Hometown<BR>
<p>
<input type="submit" value="Signup Now!">
</form>
</body>
</html>
Cdigo fonte de jediname.jsp:
<html>
<body>
<%
String firstName = request.getParameter("firstName");
String lastName = request.getParameter("lastName");
String mother = request.getParameter("mother");
String hometown = request.getParameter("hometown");
String newFirst = lastName.substring(0,3) + "-" +
firstName.substring(0,2);
String newLast = mother.substring(0,2) +
hometown.substring(0,3).toLowerCase();
String jediname = newFirst + " " + newLast;
%>
<b>Jedi Registration Center</b>
<p>
<blockquote>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 118
<%= firstName %> <%= lastName %> of <%= hometown %>,
house of <%= mother %>, your Jedi name is <i><%= jediname %></i>.
<p>
Thank you for signing up to fight the empire.
Your training will begin soon. May the force be with you...
</blockquote>
<a href="jediform.html">Sign up another recruit</a>
</body>
</html>
O fluxo da aplicao mantido atravs de um form action na primeira pgina e de um
anchor tab na pgina de apresentao do resultado. Estas pginas possuem um forte
acoplamento. Elas necessitam sincronizar parmetros de requisio e cada pgina
necessita conhecer o URL da outra.
8.2.2 Construindo Pginas Compostas
A idia de se criar pginas compostas expande a abordagem de pgina nica ilustrada
anteriormente, mas no modifica o fato de que apresentao, lgica e controle de uma
aplicao esto confinados a uma srie de pginas JSP. No entanto, neste estilo de
projeto uma srie de pequenas pginas componentes, contendo HTML ou JSP, so
utilizadas na criao de cada tela da aplicao. Isto feito atravs do uso da ao
<jsp:include> e da diretiva <%@ include>.
A estrutura de pginas compostas uma boa abordagem quando as pginas que
formam a aplicao so compostas por uma srie de elementos dinmicos complexos.
Por exemplo, para exibir detalhes de um catlogo de produtos uma pgina pode ser
quebrada em vrios elementos um cabealho padro utilizado pelo site contendo
elementos de navegao, os detalhes de cada produto, e um rodap para fechar a
pgina. Cada um destes elementos pode conter cdigo esttico ou dinmico.
O cabealho e o rodap podem conter elementos HTML estticos. Neste caso seria
utilizada a diretiva <%@ include> para carregar o contedo dos arquivos em tempo de
compilao. O produto que se deseja exibir, no entanto, poderia constar de um modelo
de pgina JSP, que poderia ser reutilizado por todo o site. Isto permite que os detalhes
referentes apresentao de um produto sejam isolados em relao ao lay-out da
pgina que contm esta pgina. O projetista da pgina poderia optar por incluir
informaes sobre o produto em qualquer local da pgina e em qualquer contexto
desejado.
Utilizando apenas o tag <jsp:include>, no cabealho, no rodap e no corpo da
pgina, a pgina principal e nenhum de seus elementos dinmicos teriam de ser
recompilados (em tempo de execuo) pela mquina JSP a menos que fossem
modificados contedo esttico includo dinamicamente e no atravs do processo
de compilao. Por exemplo, uma modificao no arquivo de header apareceria em
tempo de execuo, mas no provoca uma recompilao da pgina JSP abaixo.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 119
Exemplo:
<html>
<body>
<jsp:include page=/headers/support_section.jsp flush=true/>
<center><h2>Catalog Item 7423</h2></center>
<jsp:include page=/headers/item7423.jsp flush=true/>
<hr>
<jsp:include page=/footers/stardard.html flush=true/>
</body>
</html>
Construindo Componentes de Pginas Dinmicas
Isto pode ser feito, por exemplo, especificando-se o ttulo de uma pgina atravs de um
parmetro de requisio, conforme vem abaixo:
<jsp:include page=/headers/basic.jsp flush=true>
<param name=titulo value=Sobre Nossa Empresa/>
<param name=corDeFundo value=#FFFFFF/>
</jsp:include>
Assim o arquivo /headers/basic.jsp pode recuperar os parmetros de requisio, e
utilizar expresses JSP para incluir no contedo retornado por esta pgina, os valores
de parmetros passados a ela.
<html>
<head><title><%= request.getParameter(titulo) %></title></head>
<body bgcolor=<%= request.getParameter(corDeFundo) %>>
<HR>
Revendo o exemplo de Item de Catlogo acima, seria possvel prover um componente
de pgina mais complexo que permita que seja passado a ele um parmetro que
determine que item de catlogo deve ser exibido.
<jsp:include page=/catalogo/recuperarProduto.jsp flush=true>
<param name=produto value=7423/>
</jsp:include>
Naturalmente, seria possvel configurar o parmetro produto em tempo de execuo,
atravs de parmetros de entrada de dados:
<param name=produto value=<%= request.getParameter(produto) %>/>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 120
8.2.3 Limitaes da Abordagem Page-Centric
Manuteno
Como as pginas JSP que compem a aplicao contm cdigo de controle e cdigo de
apresentao, a aplicao pode ser de difcil manuteno. Com esta abordagem
necessrio que projetistas e programadores interajam bastante na fase de manuteno.
Fluxo do Controle
A menos que se programe defensivamente, o recebimento de requisies fora de
seqncia pode provocar srios problemas. Como cada segmento de uma aplicao JSP
page-centric a prpria pgina representada pelo URL, no h realmente nada que
impea o usurio de executar as pginas fora de ordem. Cada pgina da aplicao deve
verificar se os parmetros de requisio so vlidos, verificar conexes abertas,
verificar as condies que mudam ao longo das pginas, e no assumir nada com
respeito ordem de execuo das operaes. Como se pode imaginar, esta abordagem
faz com que as aplicaes fiquem rapidamente muito difceis de gerenciar.
A abordagem servlet-centric, apresentada abaixo, ajuda a centralizar o fluxo do
controle e reduz a complexidade de cada pgina que compe a aplicao.
8.3 Abordagem Servlet-Centric
Uma outra abordagem para o desenvolvimento de aplicaes JSP a utilizao de
pginas JSP apenas para apresentao. O controle e a lgica da aplicao, nesta
abordagem, so gerenciados por um servlet ou por um conjunto de servlets. Nesta
abordagem as requisies so indiretamente roteadas para as pginas front-end JSP,
atravs de um servlet, que executa qualquer ao que a aplicao necessite. Este servlet
pode fazer as seguintes coisas:
Executar aes em nome da pgina JSP, como a submisso de um pedido.
Entregar dados a uma pgina JSP para exibio, como um registro de banco de
dados.
Controlar o fluxo entre pginas JSP de uma aplicao.
Aps efetuar uma ao solicitada por uma pgina JSP o servlet encaminha a requisio
a uma pgina JSP ou HTML. Esta abordagem ilustrada pela figura abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 121
Esta abordagem se baseia no mediator design pattern. Neste padro de projeto
criado um componente centralizado, neste caso um servlet, cujo trabalho controlar
como os outros componentes da aplicao interagem uns com os outros e com os
recursos da aplicao. Esta abordagem permite um menor acoplamento entre as
pginas permitindo que elas interajam sem ter que estar cientes da existncia uma das
outras, e melhora a abstrao entre apresentao e lgica da aplicao.
O objetivo desta abordagem diminuir a quantidade de trabalho que deve ser feito
pelas prprias pginas, recaindo sobre servlets a tarefa de tratar os demais aspectos da
aplicao. Esta abordagem elimina a complexidade do cdigo front-end JSP, que fica
responsvel apenas pela entrada e sada de dados. Da mesma forma eliminada a
necessidade de se incluir cdigo de apresentao dentro de um servlet. Os servlets,
nesta abordagem, devem se preocupar apenas com o fluxo da aplicao e com a
gerao dos dados que devem ser apresentados aos usurios atravs de pginas JSP.
8.3.1 O Exemplo Al Mundo com Servlets
A seguir ser apresentado o exemplo Al Mundo utilizando-se a abordagem servlet-
centic. A requisio encaminhada ao servlet, que por sua vez a encaminhar pgina
JSP abaixo:
<% String msg = (String) request.getAttribute(mensagem); %>
<html>
<body>
<%= msg %>
</body>
</html>
Como pode ser observado, nenhum Bean foi criado neste exemplo. O mtodo
getAttribute() do objeto request a chave. Ele similar ao mtodo
getParameter() que extrai informaes da requisio mas lida com qualquer
objeto em vez de apenas Strings. Mais adiante veremos como possvel utilizar o
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 122
mtodo getAttribute() (e o seu par setAttribute()) para passar Beans de um
servlet para uma pgina JSP.
No momento necessrio entender apenas que ele procura por um objeto com o
identificador mensagem e o recupera do objeto request. Mas como este objeto chegou
aqui? O servlet o ps l! Lembre-se que esta pgina no foi projetada para ser chamada
diretamente, mas atravs de um servlet. O cdigo do servlet :
package jsp.aluno01.exercicio21;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class AloMundoServlet extends HttpServlet
{ public void service(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{ String aMensagem = "Al Mundo!";
String alvo = "/jsp/aluno01/exercicio21/AloServletJsp.jsp";
req.setAttribute("mensagem", aMensagem);
RequestDispatcher rd =
getServletContext().getRequestDispatcher(alvo);
rd.forward(req, res);
}
}
E para execut-lo deve-se digitar no browser:
http://sbd:8100/servlet/jsp.aluno01.exercicio21.AloMundoServlet
Quando este servlet chamado, criado um objeto String Al Mundo! que
colocado em uma requisio com o identificador mensagem. criado tambm, um
objeto RequestDispatcher, um mecanismo utilizado para encontrar servlets e pginas
JSP. Aps ser localizada a pgina AloServletJsp.jsp, a requisio encaminhada
para esta pgina. Observe que o servlet no emitiu nenhum comando de apresentao.
No h nele um nico comando out.println()! A informao dinmica gerada
pelo servlet, mas a pgina JSP quem possui a responsabilidade de exibi-la. Toda a
lgica da aplicao foi removida da pgina JSP e movida para dentro do servlet.
8.3.2 JSP e a API Servlet
H uma srie de recentes adies API Servlet nos releases 2.1 e 2.2 que permitem o
desenvolvimento de aplicaes quem combinam pginas JSP e servlets.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 123
Controle de Fluxo: o RequestDispatcher
A API Servlet 2.1 introduziu a interface RequestDispatcher que permite que o
processamento de uma requisio seja transferido para uma pgina JSP ou para outro
servlet, ou ainda, a incluso da sada de um documento local (uma pgina JSP, um
servlet, ou uma pgina HTML) no output stream criado pelo servlet corrente. Um objeto
RequestDispatcher criado passando-se o URL da pgina JSP ou do servlet de
destino para o mtodo getRequestDispatcher() do objeto request de entrada, ou do
objeto ServletContext do servlet. O mtodo do objeto ServletContext requer um
URL absoluto, enquanto o mtodo do objeto request permite que seja utilizado um
caminho relativo. Neste caso o caminho relativo ao objeto request do servlet. Se o
servlet que chama o mtodo abaixo est mapeado para
/loja/recuperaPedidoServlet, ento os seguintes mtodos so equivalentes:
req.getRequestDispatcher(mostraPedidos.jsp);
getServletContext().getRequestDispatcher(/loja/mostraPedidos.jsp);
Porque utilizar um objeto RequestDispatcher se j se possui um URL? Muitas coisas
podem afetar o real destino de uma requisio. O caminho absoluto mapeado a nvel
de aplicao que no necessariamente o mesmo que a raiz do servidor web.
Uma vez criado o objeto RequestDispatcher correspondente pgina JSP (ou a outro
servlet) duas alternativas so possveis. possvel transferir o processamento da
requisio corrente para a pgina JSP associada ao RequestDispatcher com o mtodo
forward(), ou pode-se incluir seu contedo na resposta do servlet atravs do mtodo
include(). O mtodo include() pode ser chamado a qualquer momento, mas se o
servlet j gerou alguma sada (escrevendo no output stream) uma tentativa de chamar o
mtodo forward() gerar uma exceo. Ambos os mtodos necessitam de uma
referncia para os objetos request e response correntes. A assinatura destes dois
mtodos da classe RequestDispatcher a seguinte:
public void include (HttpServletRequest, HttpServletResponse)
public void forward (HttpServletRequest, HttpServletResponse)
a classe RequestDispatcher que permite que um servlet seja utilizado no papel de
controlador da aplicao. Se o cdigo do servlet necessita efetuar qualquer tipo de
sada, ele poder faz-lo, para ento encaminhar a requisio que ser tratada pela
pgina JSP. interessante observar que no se trata de um redirecionamento do
browser a informao de URL exibida pelo browser no ir mudar. O processamento
da pgina tratado inteiramente pelo servidor e o usurio no ver um reload da pgina
ou mesmo o URL da pgina JSP.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 124
Transferindo Dados Atravs de Atributos de Requisio
Atributos de requisio so atributos que so associados a uma requisio especfica.
Diferentemente de parmetros de requisio (que s trabalham com Strings), um
atributo de requisio podem ser qualquer objeto java. Eles so colocados na
requisio pelo container do servlet geralmente para passar informaes entre um
servlet e uma pgina JSP, ou outro servlet.
Para designar e recuperar atributos de requisio devem ser utilizados os mtodos
abaixo:
public void setAttribute (String name, Object o)
public Object getAttribute (String name)
So os atributos de requisio que permitem que os servlets cuidem da lgica de uma
aplicao, provendo um mecanismo para a troca de dados entre servlets e pginas JSP.
Os dados resultantes de uma operao de acesso a banco de dados podem ser
empacotados em um Bean (ou outro objeto) e colocados diretamente na requisio, de
onde a pgina JSP pode recuper-lo para a sua apresentao.
Os Efeitos de Despachar uma Requisio
importante entender que no momento que uma requisio transferida para uma
pgina JSP, o caminho o caminho no objeto request modificado para refletir o URL da
pgina de destino. Uma tentativa de ler a informao de caminho (como
HttpUtils.getRequestURL() ou getServletPath()) retornar apenas o URL da
pgina JSP, e no o URL do servlet como requisitado originalmente. H algumas
excees a esta regra. Se o mtodo include() for utilizado em vez do mtodo
forward(), o container do servlet criar os seguintes atributos de requisio para
refletir o caminho requisitado original:
javax.servlet.include.request_uri
javax.servlet.include.context_path
javax.servlet.include.servlet_path
javax.servlet.include.path_info
javax.servlet.include.query_string
possvel recuperar estes atributos de requisio caso seja necessrio determinar a
requisio original. Por esta razo se uma pgina JSP necessita se conectar de volta ao
servlet que recebeu a requisio ser necessrio utilizar o mtodo include() no
servlet, em vez passar o controle para a pgina JSP diretamente atravs do mtodo
forward().
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 125
8.3.3 Servlets para Controle de Aplicaes
Um papel importante que os servlets podem desempenhar nesta arquitetura o de
proxy transactions entre pginas JSP individuais que compem o front-end da
aplicao. Estando certos de que cada requisio HTTP primeiramente tratada por um
servlet controlador, possvel executar tarefas que ultrapassam o escopo de uma nica
pgina, como por exemplo a autenticao, e garantir que a aplicao mantm
corretamente o estado da informao e o controle de fluxo.
Garantindo Requisitos a Nvel de Aplicao
Por exemplo, possvel utilizar o servlet controlador para garantir a autenticao dos
usurios, em vez de tratar a autenticao em cada pgina da aplicao. Usurios no
autenticados seriam forados a passar por um subsistema de autenticao antes de
terem acesso a outras partes do sistema.
Nesta arquitetura o servlet mantm o fluxo atravs da aplicao, em vez do fluxo ser
determinado atravs de links HTML e forms digitados em cada pgina JSP. Isto elimina
alguns dos problemas de controle de fluxo inerentes comunicao HTTP. O projeto da
aplicao page-centric apresentado anteriormente poderia ser refeito com a abordagem
servlet-centric conforme vem na figura abaixo:
Controlando o Fluxo da Aplicao
possvel utilizar um servlet para prover um nico URL que ir servir como ponto de
entrada para uma aplicao e codificar a lgica do fluxo do programa dentro do servlet.
Aps ser chamado, o servlet determina a ao que deve ser executada e utiliza um
objeto RequestDispatcher para rotear dados para a pgina JSP apropriada. Por
exemplo, uma pgina denominada submitFeedback.jsp entrega seus dados ao servlet
controlador, e no precisa saber que o prximo passo enviar o usurio de volta
pgina principal da aplicao. A se comparar esta abordagem com a abordagem page-
centric (que permite que uma pgina passe o controle para outra), percebe-se que esta
abordagem no apenas deixa as pginas livre de lgica da aplicao, mas permite que
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 126
elas sejam reutilizadas em vrias situaes (inclusive por aplicaes diferentes), pois
foram reduzidas sua essncia como dispositivos de apresentao.
Uma tcnica para gerenciar este fluxo atravs da utilizao de um mapeador de telas,
uma estrutura de dados que associa um nome lgico a cada uma das telas que formam
a aplicao. Ento, o servlet trata o fluxo da aplicao como uma srie de nomes de
telas lgicos em vez de nomes de arquivos reais. Por exemplo, uma pgina que
implementa um formulrio de entrada de dados para cadastro de novos empregados
pode ser logicamente mapeada para o identificador NovoEmpregadoForm e pode
referenciar o URL /forms/empregados/novo.jsp. Se estes mapeamentos forem
colocados em um arquivo de propriedades, ou at em um banco de dados, possvel
fazer modificaes na configurao de um programa sem ter de editar o cdigo do
servlet. Embora um armazenamento centralizado permita o compartilhamento entre
aplicaes, mesmo algo simples como uma hash table, inicializada no mtodo init()
do servlet, ser uma boa ajuda no gerenciamento do mapeamento de nomes lgicos
para fsicos.
8.3.4 Servlets para o Tratamento da Lgica da Aplicao
Podem ser criados em uma aplicao tantos servlets quantos forem necessrios: um
para recuperar pedidos de clientes, um para recuperar dados de clientes e etc.
Alternativamente, toda a lgica de uma aplicao pode ser includa em um nico
servlet, e parmetros de requisio podem ser utilizados para se determinar que ao
deve ser realizada.
Servlets Provem Servios
No caso de uma aplicao que exibe informaes detalhadas a respeito de um pedido
de um cliente recuperado de um banco de dados, o servlet pode obter o nmero do
pedido a partir da requisio, recuperar as informaes a respeito do pedido
armazenadas em um banco de dados, e empacotar informaes sobre o pedido em um
Bean. Este Bean poderia ento ser adicionado requisio antes de passar o controle
adiante para a pgina JSP responsvel por exibir informaes sobre o pedido. Na
pgina JSP seria possvel recuperar o Bean armazenado na requisio, e exibir as
informaes sobre o pedido. Por exemplo, o cdigo abaixo obtm o Bean
PedidoDeCompraBean e o coloca no objeto request sob o nome pc. Neste exemplo
preciso assumir que o mtodo getPedidoDeCompra() utiliza o ID passado na
requisio inicial para recuperar as informaes sobre o pedido no banco de dados. O
mtodo service() do servlet seria assim:
String id = req.getParameter("id");
PedidoDeCompraBean bean = getPedidoDeCompra(id);
req.setAttribute("pc", bean);
RequestDispatcher rd =
getServletContext().getRequestDispatcher
("/jsp/aluno01/exercicio22/ExibirPedido.jsp");
rd.forward(req,res);
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 127
Para se obter uma referncia ao Bean PedidoDeCompraBean pode-se utilizar o tag
<jsp:useBean> especificando-se para ele um escopo de requisio, ou pode-se utilizar
o mtodo getAttribute() do objeto request para se obter uma referncia para o
objeto pc. Observe que neste caso o Bean possui escopo de pgina.
<jsp:useBean name=pc class=PedidoDeCompraBean scope=request />
Pedido de Compra Nmero: <jsp:getProperty name=pc property=id/>
ou
<% jsp:useBeanname=pc class=PedidoDeCompraBean />
<% pc = (PedidoDeCompraBean) request.getAttribute(pc); %>
Pedido de Compra Nmero: <jsp:getProperty name=pc property=id/>
O servlet neste caso est agindo como um servio para a pgina JSP.
Segue abaixo o cdigo completo do exemplo apresentado acima.
O Servlet PedidoDeCompraServlet
package jsp.aluno01.exercicio22;
import jsp.aluno01.exercicio22.PedidoDeCompraBean;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
public class PedidoDeCompraServlet extends HttpServlet
{ public void service(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{ String id = req.getParameter("id");
PedidoDeCompraBean bean = getPedidoDeCompra(id);
req.setAttribute("pc", bean);
RequestDispatcher rd =
getServletContext().getRequestDispatcher
("/jsp/aluno01/exercicio22/ExibirPedido.jsp");
rd.forward(req,res);
}
private PedidoDeCompraBean getPedidoDeCompra(String id)
{ int idd = Integer.parseInt(id);
Connection connection = null;
Statement statement = null;
ResultSet results = null;
PedidoDeCompraBean bean = new PedidoDeCompraBean();
try
{ Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@sbd:1521:orcl";
String query = "SELECT * FROM PEDIDODECOMPRA WHERE ID = "
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 128
+ idd;
connection = DriverManager.getConnection(url, "java01",
"java01");
statement = connection.createStatement();
results = statement.executeQuery(query);
if (results.next())
{ bean.setId(results.getInt("ID"));
bean.setDataEmissao(results.getDate("DATAEMISSAO"));
bean.setPrecoTotal(results.getDouble("PRECOTOTAL"));
}
connection.close();
}
catch (ClassNotFoundException e)
{ System.err.println("No conseguiu carregar o driver!");
}
catch (SQLException e)
{ System.err.println
("No conseguiu conectar-se ao banco!");
}
finally
{ try
{ if (connection != null) connection.close();
return bean;
}
catch (SQLException e)
{ return null;
}
}
}
}
O JavaBean PedidoDeCompraBean
package jsp.aluno01.exercicio22;
import java.sql.Date;
public class PedidoDeCompraBean
{ private int id;
private Date dataEmissao;
private double precoTotal;
public PedidoDeCompraBean() { }
public void setId(int id)
{ this.id = id;
}
public void setDataEmissao(Date dataEmissao)
{ this.dataEmissao = dataEmissao;
}
public void setPrecoTotal(double precoTotal)
{ this.precoTotal = precoTotal;
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 129
}
public int getId()
{ return this.id;
}
public Date getDataEmissao()
{ return this.dataEmissao;
}
public double getPrecoTotal()
{ return this.precoTotal;
}
}
A Pgina JSP ExibePedido.jsp
<%@ page import="jsp.aluno01.exercicio22.*" %>
<jsp:useBean id="pc" class="PedidoDeCompraBean" scope="request" />
<html>
<body>
Nmero do Pedido: <jsp:getProperty name="pc" property="id" /> <BR>
Valor Total: <jsp:getProperty name="pc" property="precoTotal" />
</body>
</html>
8.3.5 Servlets como Ponto nico de Entrada
Se todas as requisies so encaminhadas a um nico servlet necessrio indicar ao
servlet o que ele deve fazer. Esta indicao pode ser feita atravs de parmetros de
requisio, atravs de elementos de formulrios hidden, atravs de URL encoding, ou
adicionando ao final do caminho do servlet informaes adicionais.
Exemplo:
Se o URL para o servlet /servlet/catalogo, seria possvel indicar ao servlet que ele
deve pesquisar o produto 123 assim:
/servlet/catalogo?acao=pesquisa&produto=123
Uma vez determinada a ao que deve ser executada, o servlet poder decidir o que
fazer em seguida.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 130
Utilizando o Command Pattern
Muitas aplicaes JSP servlet-centric utilizam a arquitetura orientada a comandos.
Requisies de cada pgina JSP incluem algum tipo de identificador de comando que
dispara o comportamento no servlet ou direciona o fluxo do programa. O command
pattern, um design pattern familiar aos programadores de aplicaes GUI, pode
ser til na estruturao de um servlet, atravs da reduo da complexidade e de uma
melhor separao entre controle e lgica da aplicao.
Utilizando este design pattern cada comando que o servlet sabe tratar encapsulado
na sua prpria classe. Quando uma requisio vem de uma pgina JSP, o servlet
despacha a requisio para o objeto especfico associado execuo daquele comando.
Apenas o objeto comando conhece a lgica da aplicao relacionada a ele. O servlet
funciona apenas como um mediador da requisio entre a pgina JSP e o objeto
comando. Considere o exemplo abaixo extrado do mtodo service() de um servlet
que provoca a execuo de um comando definido em uma classe do tipo Comando, em
funo de um identificador de comando enviado ao servlet.
String cmd = req.getParameter(cmd);
if (cmd.equals(Salvar))
{ ComandoSalvar cmdSalvar = new ComandoSalvar();
cmdSalvar.salvar();
}
else if (cmd.equals(Editar))
{ ComandoEditar cmdEditar = new ComandoEditar();
cmdEditar.editar();
}
else if (cmd.equals(Remover))
{ ComandoRemover cmdRemover = new ComandoRemover();
cmdRemover.remover();
}
Sem a utilizao do command pattern, cada bloco if do servlet teria de conter toda a
lgica necessria para executar o comando requisitado. Utilizando o command pattern
temos cdigo reutilizvel que encapsula comportamento e torna o cdigo mais claro,
alm de permitir que o cdigo seja implementado e testado independentemente da
aplicao web. A utilidade desta abordagem mais clara quando o servlet manipula
dezenas de comandos diferentes.
possvel aperfeioar esta implementao eliminando a necessidade do servlet
entender o exato relacionamento existente entre um comando de requisio e o prprio
objeto comando. Se uma forma comum de tratar todos os objetos comando for criada,
o servlet poder tratar todos eles da mesma forma, em uma nica linha. Atravs de uma
interface pode ser criada uma forma comum para a execuo dos comandos. O
comando, na forma de um String, encaminhado atravs da requisio tratado como
um identificador nico para se obter um tipo particular de objeto comando. Uma vez
obtida a referncia para o comando apropriado, os mtodos definidos nesta interface
podem ser chamados para executar o comando. Considere o cdigo abaixo, onde
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 131
Command uma interface comum implementada por todos os objetos comando, e a
classe CommandFactory mapeia identificadores de comandos para objetos comando,
retornando o objeto apropriado do tipo Command.
Command cmd =
CommandFactory.getCommand(request.getParameter(comando));
cmd.execute();
Este cdigo o corao do servlet e pode tratar qualquer comando com apenas estas
linhas. Caso um comando desconhecido seja encaminhado ao servlet, a classe
CommandFactory pode: a) retornar um objeto command vlido que no faz nada,
b) gerar uma exceo, ou c) executa algum comportamento default.
Uma outra tcnica til a utilizao do mtodo Class.forName() para criar uma
instncia de Command dinamicamente utilizando o identificador comando. Observe o
cdigo abaixo:
String cmdID = request.getParameter(comando));
Command cmd = Class.forName(cmdID + Comando).newInstance();
No exemplo acima o string armazenado na varivel cmdID foi concatenado ao string
Comando para se tentar localizar a classe apropriada e instanciar um objeto desta
classe. Esta tcnica requer que se estabelea uma conveno de nomes e pode se tornar
complicada caso seja necessrio suportar diversos tipos de construtores.
Garantindo a Integridade de Transaes
Como discutido anteriormente, aplicaes para a web sofrem com a natureza das
requisies HTTP. A recarga de uma pgina ou um click no boto Back pode causar a
reemisso de requisies ou execut-las fora da seqncia algo que no pode ocorrer
em um sistema de misso crtica.
Uma forma de resolver este problema de continuidade atravs da gravao de um
token na sesso do usurio no momento que uma atividade (pr-requisito) se completa
e exigir este token no passo seguinte. Quando chega a requisio para se executar o
segundo passo da transao, o servlet pode verificar se o pr-requisito foi atendido
recuperando o token armazenado no objeto sesso. Uma vez completada a operao, o
token removido da sesso. O token permite que o servlet execute uma ao, mas
apenas uma vez. Requisies secundrias no encontraro o token correspondente e
podero gerar uma exceo. Dependendo dos requisitos de sua aplicao possvel
manter uma lista de tokens que daria suporte a vrias janelas (de um mesmo usurio)
simultneas do browser ou um nico token que sempre sobrescrito.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 132
Digamos que uma transao esteja comprando um produto de uma loja. Os passos
finais do processo de encerramento so tratados pela pgina encerramento.jsp, uma
pgina que contm um formulrio requisitando selees e pedindo por uma
confirmao final. O click no boto de confirmao faz com que seja cadastrado um
pedido para os diversos produtos selecionados e, em seguida, exibida a pgina
obrigado.jsp. O que acontece se o usurio clicar no boto reload neste momento, ou
no boto Back? Lembre-se que para o browser ele apenas est submetendo o contedo
de um formulrio. No vem ao caso se um servlet ou uma pgina JSP est recebendo a
ao. Clicando-se reload o processo ser repetido resultando na nova emisso de um
pedido.
Para que a aplicao acima possa ser controlada por tokens, preciso que ambas as
pginas sejam controladas por servlets (ou pelo mesmo servlet). Quando o usurio vai
para a pgina de confirmao, o servlet deve gerar um token de utilizao nica e
armazen-lo na sesso do usurio antes de direcionar a requisio para a pgina de
onde o token includo como um elemento hidden do formulrio. Quando o formulrio
submetido, o servlet verifica se o token no formulrio e o token no servidor so
iguais. Caso sejam iguais a ao executada, e o token no servidor removido antes
de encaminhar ao usurio a pgina obrigado.jsp.
Se o usurio clicar em Reload antes da pgina obrigado.jsp chegar, a ao do
formulrio seria submetida novamente, mas desta vez os tokens no corresponderiam
indicando ao servlet que a transao j foi encerrada e que o servlet pode ignorar a
transao atual e enviar novamente a pgina obrigado.jsp. Este processo ilustrado
na figura abaixo:
Uma tcnica para gerar um token de transao que nico para cada sesso e que no
se repete ao longo da aplicao, atravs da concatenao do identificador da sesso
do usurio com a hora do sistema.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 133
8.3.6 Tratando Erros no Servlet
Quando ao longo do processamento de um servlet ocorre um erro inesperado, pode-se
transferir o erro para uma pgina JSP de tratamento de erros. Isto faz com que todos os
tratamentos de excees fiquem consistentes ao longo da aplicao independentemente
do erro surgir em uma pgina JSP ou em um servlet. A exceo deve ser capturada e
colocada no objeto request sob o nome javax.servlet.jsp.jspException. Em
seguida deve ser utilizada uma instncia de RequestDispatcher para dar um forward
na requisio para a pgina de tratamento de erros. Por exemplo:
String nomeUsuario = req.getParameter(usuario);
if (nomeUsuario == null)
req.setAttribute(javax.servlet.jsp.jspException,
new Exception (Falta o nome do usurio!));
RequestDispatcher rd =
getServletContext().getRequestDispatcher(/trataErros.jsp);
rd.forward(req, res);
A pgina trataErros.jsp deve ser definida como uma pgina JSP para tratamento de
erros atravs da diretiva de pgina isErrorPage. Sempre que um objeto Exception
inserido no objeto request com o nome de atributo
javax.servlet.jsp.jspException, criado automaticamente um objeto exception
implcito que a pgina de erro poder referenciar no tratamento do erro. No h
nenhuma diferena entre uma exceo criada pelo servlet acima ou por uma pgina
JSP.
8.3.7 Exemplo: Uma Aplicao Servlet-Centric
Neste exemplo ser construda uma aplicao que percorre os empregados cadastrados
em um banco de dados. Neste exemplo, o usurio no pode alterar ou incluir novos
empregados no banco de dados.
Consideraes de Projeto
Sero necessrias duas interfaces para esta aplicao: uma para listar todos os
empregados cadastrados no banco de dados e outra para mostrar os detalhes relativos
aos empregados selecionados em uma lista. O componente central desta aplicao o
Bean EmpregadoBean, que ir encapsular as informaes necessrias aplicao. Ser
responsabilidade do servlet tratar toda a interao com o banco de dados. Veja o
modelo da aplicao na figura abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 134
O Banco de Dados
Esta aplicao trabalha com uma tabela denominada Empregados que possui o seguinte
lay-out:
Coluna Propsito Tipo
ID Id nico do Empregado Number(5)
PNOME Primeiro Nome Varchar2(80)
UNOME ltimo Nome Varcahr2(80)
DEPARTAMENTO Departamento Varchar2(80)
EMAIL Endereo de e-mail Varchar2(80)
IMAGE URL da foto do empregado Varchar2(80)
Em vez de incluir dentro do Bean EmpregadoBean o cdigo responsvel por recuperar
o empregado no banco de dados, optou-se por escrever um servlet responsvel pelo
acesso ao banco de dados e pelo controle da aplicao.
O JavaBean EmpregadoBean
A deciso sobre que nvel de acesso disponibilizar para cada propriedade depende de
como a aplicao dever utilizar o Bean. A propriedade id, por exemplo, nica para
cada registro e geralmente no modificada. preciso ser capaz de especificar o valor
do id em algum momento embora esta propriedade deva ser read-only. Para
especificar este valor inicial ser utilizado o construtor do Bean.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 135
public EmpregadoBean (int id)
{ this.id = id;
pNome = ;
uNome = ;
imagem=;
email=;
departamento=;
}
Naturalmente uma pgina JSP no ser capaz de passar argumentos para um
construtor, e tambm no ser capaz de instanciar um Bean sem a existncia de um
construtor com zero argumentos. Logo, a soluo est em prover um construtor que
passa um valor de id impossvel para o construtor principal. Nesta aplicao, no
entanto, no deve ser necessrio criar um Bean atravs de uma pgina JSP.
public EmpregadoBean()
{ this(0);
}
Desta forma um Bean pode ser criado e deixado em um estado que indica que o
identificador do Bean ainda no vlido. Se for necessrio construir um novo registro
de banco de dados a partir dos dados armazenados no Bean, ser preciso criar um
identificador vlido, geralmente solicitando ao banco de dados pelo prximo nmero
disponvel para este identificador.
Segue abaixo o cdigo do JavaBean EmpregadoBean:
package jsp.aluno01.exercicio23;
public class EmpregadoBean
{ private int id;
private String primeiroNome;
private String ultimoNome;
private String imagem;
private String email;
private String departamento;
public EmpregadoBean(int id)
{ this.id = id;
primeiroNome = "";
ultimoNome = "";
imagem = "";
email = "";
departamento = "";
}
public EmpregadoBean()
{ this(0);
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 136
public int getId()
{ return this.id;
}
public void setPrimeiroNome(String primeiroNome)
{ this.primeiroNome = primeiroNome;
}
public String getPrimeiroNome()
{ return this.primeiroNome;
}
public void setUltimoNome(String ultimoNome)
{ this.ultimoNome = ultimoNome;
}
public String getUltimoNome()
{ return this.ultimoNome;
}
public void setImagem(String imagem)
{ this.imagem = imagem;
}
public String getImagem()
{ return this.imagem;
}
public void setEmail(String email)
{ this.email = email;
}
public String getEmail()
{ return this.email;
}
public void setDepartamento(String departamento)
{ this.departamento = departamento;
}
public String getDepartamento()
{ return this.departamento;
}
}
O Servlet RecuperaEmpregadoServlet
O servlet RecuperaEmpregadoServlet sabe como fazer duas coisas. a) dado um nmero
de empregado, recupera informaes do empregado em um banco de dados e
encaminha estas informaes para uma pgina JSP para serem exibidas, ou b) retorna
um Vector para a pgina lista.jsp contendo um array de Beans representando cada
empregado no banco de dados.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 137
package jsp.aluno01.exercicio23;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.sql.*;
import java.util.*;
public class RecuperarEmpregadoServlet extends HttpServlet
{ private final static String driver =
"oracle.jdbc.driver.OracleDriver";
private final static String url =
"jdbc:oracle:thin:@sbd:1521:orcl";
private final static String usuario = "carlos";
private final static String senha = "carlos";
private final static String sql =
"select * from empregados where id = ?";
private Connection connection = null;
private PreparedStatement statement = null;
private ServletContext context;
public void init(ServletConfig config) throws ServletException
{ super.init(config);
context = config.getServletContext();
try
{ Class.forName(driver);
connection = DriverManager.getConnection
(url, usuario, senha);
statement = connection.prepareStatement(sql);
}
catch (ClassNotFoundException e)
{ System.err.println
("O driver de banco de dados no foi encontrado.");
throw new ServletException
("O driver de banco de dados no foi encontrado.");
}
catch (SQLException e)
{ System.err.println
("No foi possvel estabelecer uma conexo " +
"com o banco de dados.");
throw new ServletException
("No foi possvel estabelecer uma conexo " +
"com o banco de dados.");
}
}
public void service(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{ String jsp;
String cmd = req.getParameter("cmd");
String idString = req.getParameter("id");
int id;
try { id = Integer.parseInt(idString); }
catch(NumberFormatException e) { id=0; };
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 138
if ("get".equals(cmd))
{ EmpregadoBean bean = recuperaEmpregado(id);
req.setAttribute("empregado", bean);
jsp = "/jsp/aluno01/exercicio23/listaUmEmpregado.jsp";
}
else
{ Vector lista = recuperaTodos();
req.setAttribute("lista", lista);
jsp="/jsp/aluno01/exercicio23/listaTodosEmpregados.jsp";
}
RequestDispatcher dispatcher;
dispatcher = context.getRequestDispatcher(jsp);
dispatcher.forward(req, res);
}
public EmpregadoBean criaBean(ResultSet resultado)
throws SQLException
{ EmpregadoBean bean = new
EmpregadoBean(resultado.getInt("ID"));
bean.setPrimeiroNome(resultado.getString("PRIMEIRONOME"));
bean.setUltimoNome(resultado.getString("ULTIMONOME"));
bean.setEmail(resultado.getString("EMAIL"));
bean.setDepartamento(resultado.getString("DEPARTAMENTO"));
bean.setImagem(resultado.getString("IMAGEM"));
return bean;
}
public EmpregadoBean recuperaEmpregado(int id)
{ try
{ ResultSet resultado;
synchronized (statement)
{ statement.clearParameters();
statement.setInt(1, id);
resultado = statement.executeQuery();
}
EmpregadoBean bean = null;
if (resultado.next())
{ bean = criaBean(resultado);
}
if (resultado != null)
resultado.close();
return bean;
}
catch (SQLException se) { return null; }
}
public Vector recuperaTodos()
{ try
{ Vector lista = new Vector();
ResultSet resultado;
Statement st = connection.createStatement();
resultado = st.executeQuery("select * from empregados");
while (resultado.next())
{ lista.add(criaBean(resultado));
}
return lista;
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 139
}
catch (SQLException se) { return null; }
}
public void destroy()
{ try
{ if (connection != null)
connection.close();
}
catch (SQLException e) { }
}
}
O mtodo init() do servlet estabelece a conexo com o banco de dados que
permanecer aberta durante toda a vida do servlet. Sempre que o servlet recebe uma
requisio, o mtodo service() chamado. neste mtodo que se encontra o cdigo
referente lgica da aplicao e ao fluxo da execuo. O servlet suporta dois
comandos, get para recuperar um empregado especfico, ou qualquer outra coisa para
criar um Vector contento todos os empregados.
A varivel jsp recebe o valor do URL da prxima pgina JSP a ser visitada pela
aplicao. utilizado um RequestDispatcher para transferir o controle da execuo
para esta pgina.
Ambos os mtodos recuperarEmpregado() e recuperarTodos() baseiam-se no
mtodo criarBean() que extrai a linha corrente do resultSet a ele enviado e
recupera as colunas apropriadas para popular um novo Bean denominado
EmpregadoBean.
8.3.8 Retornando uma Lista de Empregados
A pgina abaixo recebe a lista de empregados do servlet, na forma de um Vector de
objetos EmpregadoBean. Esta pgina utiliza scriptlets para extrair cada Bean do
Vector, e constri um link de volta ao servlet para que o usurio possa consultar os
detalhes a respeito de cada empregado relacionado. O id do empregado enviado ao
servlet atravs de um parmetro de requisio do tipo GET, o que ir permitir que o
servlet recupere os dados do empregado desejado.
<%@ page import="java.util.*,
jsp.aluno01.exercicio23.EmpregadoBean" %>
<jsp:useBean id="empregado" class="EmpregadoBean" />
<html>
<body>
<b>Relao de Todos os Empregados</b>
<ul>
<%
Vector v = (Vector)request.getAttribute("lista");
int k = v.size();
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 140
for (int i = 0; i < v.size(); i++)
{ empregado = (EmpregadoBean)v.get(i);
/* No sei porque o cdigo com JavaBean abaixo
no funciona acho que um Bug do JRun.
Id = <jsp:getProperty name="empregado" property="id"/><BR>
*/
%>
<li>
<A
href=/servlet/jsp.aluno01.exercicio23.RecuperarEmpregadoServlet?cmd=ge
t&id=<%= empregado.getId() %>><%= empregado.getUltimoNome() %>, <%=
empregado.getPrimeiroNome() %>
</A><BR>
Id = <jsp:getProperty name="empregado" property="primeiroNome" />
<BR>
<% } %>
</ul>
</body>
</html>
8.3.9 Retornando um nico Empregado
Na pgina JSP abaixo, aps se obter uma referncia para o Bean, os valores das
propriedades do Bean so exibidos. Para capturar o Bean que foi colocado no objeto
request pelo servlet, especificado para ele escopo de requisio e um id com o
mesmo valor identificador utilizado pelo servlet, isto , empregado.
<jsp:useBean id=empregado class=EmpregaoBean scope=request />
Se o valor do id especificado na pgina JSP no for o mesmo identificador utilizado
pelo servlet quando pe o Bean na requisio, ou se a pgina requisitada diretamente
em vez de atravs do servlet, o Bean no ser encontrado. Uma vez tendo sido obtida
uma referncia para o Bean, ele pode ser utilizado para se exibir os dados extrados do
banco de dados.
<B>Departamento: <jsp:getProperty name=empregado
property=departamento />
Essencialmente, um registro de banco de dados encapsulado em um Bean JSP
evitando assim a utilizao de cdigo de acesso a banco de dados na pgina JSP. Esta
soluo tambm traz um alto nvel de abstrao para o projetista da pgina. Para a
pgina JSP no importa de onde veio a informao de um arquivo, de um formulrio
HTML, de um banco de dados, etc pois sua funo apenas exibir os dados
armazenados no Bean. Isto permite que a implementao no back-end mude ao longo
do tempo sem afetar o front-end e permite que este cdigo front-end seja reutilizado
pelo sistema.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 141
<jsp:useBean id="empregado"
class="jsp.aluno01.exercicio23.EmpregadoBean"
scope="request" />
<html>
<head><title>Registro de Empregado</title></head>
<body>
<table border="1" align="center">
<tr bgcolor="tan"><td colspan=2><font size=+3 face=arial><b>
<jsp:getProperty name="empregado" property="ultimoNome"/>,
<jsp:getProperty name="empregado" property="primeiroNome"/>
</b></font></td></tr>
<tr><td align=left valign=top>
<img height="150"
src="<jsp:getProperty name="empregado" property="imagem"/>"></td>
<td align=left valign=top>
<table border=0>
<tr><td><b>Nome Completo:</b></td><td>
<jsp:getProperty name="empregado" property="primeiroNome"/>
<jsp:getProperty name="empregado" property="ultimoNome"/>
</td></tr>
<tr><td><b>Nmero:</b></td><td>
<jsp:getProperty name="empregado" property="id"/>
</td></tr>
<tr><td><b>Departamento:</b></td><td>
<jsp:getProperty name="empregado" property="departamento"/>
</td></tr>
<tr><td><b>e-mail:</b></td><td>
<jsp:getProperty name="empregado" property="email"/>
</td></tr>
</table>
</td>
</tr>
</table>
</body>
</html>
8.4 Enterprise JavaBeans
As arquiteturas discutidas nos dois captulos anteriores no suportam facilmente o
gerenciamento de transaes complicadas e arquiteturas distribudas. A criao da
especificao de Enterprise JavaBeans pela Sun e a sua adoo por importantes
servidores de aplicativos tais como Netscape e IBM promete facilitar e agilizar o
desenvolvimento de aplicaes de misso crtica. A importncia do papel
desempenhado pelos componentes EJB tm crescido bastante, e casam muito bem com
JSP e servlets.
Est alm do escopo desta apostila ensinar os detalhes de EJB. O restante deste captulo
apresenta apenas como eles podem ser utilizados em um projeto de uma aplicao JSP.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 142
8.4.1 O que so Enterprise JavaBeans
EJB so componentes de lgica de negcio reutilizveis para utilizao em arquiteturas
de aplicaes multi-camadas e distribudas. A estrutura de EJB prov funcionalidade
que tradicionalmente tem representado o maior desafio na criao de aplicaes para a
web.
Por exemplo, no desenvolvimento de uma aplicao de comrcio eletrnico, pode-se
comprar um componente EJB que efetue a aprovao de um carto de crdito em
tempo real, um outro que gerencie os clientes, e outro que calcule os custos com
transporte da mercadoria. Seria preciso ento, aglutinar estes componentes no servidor
de aplicativos atravs da customizao de suas propriedades de execuo, e assim
estaria pronto um sistema de processamento de pedidos.
8.4.2 JavaBeans x EJBs
Qual a relao entre os componentes JavaBeans e os EJBs? Em uma perspectiva
tcnica eles no tm muito em comum. Os componentes EJBs seguem um conjunto de
convenes completamente diferente e no podem ser acessados diretamente atravs
de Bean containers e de tags JSP (pelo menos atravs dos tags padro). No paradigma
dos EJB, uma aplicao implementada como um conjunto de componentes para
controle da lgica do negcio. Estes componentes so configurados dentro de um
container de EJBs tal como um servidor de aplicativos. Clientes so ento escritos para
se comunicarem com componentes EJBs e manipular os resultados.
8.4.3 Projeto de Aplicaes com EJBs
Esta sesso trata de como desenvolver uma aplicao JSP utilizando EJBs. Como o
papel dos componentes EJBs tratar apenas o ncleo da lgica do negcio de uma
aplicao, necessrio que o cdigo JSP cuide da apresentao e um ou mais servlets
cuidem do controle de fluxo. Embora seja possvel construir aplicaes utilizando
apenas JSP e EJBs, esta abordagem no recomendada. Uma aplicao complexa o
suficiente para utilizar EJBs certamente dever empregar a abordagem servlet-centric.
De forma similar ao command pattern descrito anteriormente, EJBs tratam o
processamento dos comandos, liberando o servlet desta responsabilidade.
Por exemplo, em uma aplicao um servlet poderia utilizar os servios de componentes
EJB para tratar regras de negcio, enquanto outro servlet poderia ser utilizado para
direcionar os clientes a pginas JSP com a funo de lhes mostrar as informaes
solicitadas. Assim, a lgica da aplicao seria movida para fora do servlet, atravs de
componentes EJB.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 143
Nesta abordagem interessante esconder das pginas JSP o funcionamento interno dos
componentes EJB. Se as chamadas do servlet aos componentes EJBs retornam objetos
complexos, seria melhor empacotar os resultados das chamadas em Data Beans mais
simples, que contenham uma vista dos dados relevante para a pgina JSP.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 144
9. EXECUTANDO TAREFAS COMUNS COM JSP
9.1 Tratando Cookies
Cookies so um mecanismo padro do protocolo HTTP para que um servidor web (ou
um grupo de servidores web de um mesmo domnio) possa armazenar uma pequena
quantidade de dados persistentes no browser de um usurio para posterior recuperao.
Por default, um cookie expira assim que o usurio fecha o browser. No entanto, eles
podem ser configurados para persistir por vrias sesses de um browser, at uma data
de expirao especfica.
Os dados armazenados em um cookie so colocados l por um servidor web, e
consequentemente, podem conter apenas informaes que o servidor conhece. Por
razes de segurana um cookie pode ser recuperado:
Apenas pelo servidor web que o criou.
Opcionalmente, pelos servidores no mesmo domnio do servidor que o criou
Apenas por programas em uma hierarquia de diretrios URL especfica.
Um servidor pode criar vrios cookies, e cada cookie deve possuir um nome.
9.1.1 Gerenciando Cookies
Cookies so criados por servidores web atravs de cabealhos de respostas HTTP.
Sempre que um browser requisita um URL cujo servidor e diretrio casam com cookies
armazenados na mquina cliente, os cookies correspondentes so enviados de volta ao
servidor na forma de cabealho de requisio. Se o URL requisitado referencia uma
pgina JSP, a pgina pode acessar estes cookies atravs do mtodo getCookies() do
objeto implcito request. De forma similar, cookies so criados por uma pgina JSP
atravs do mtodo addCookie() do objeto implcito response.
9.1.2 A Classe Cookie
H um nico mtodo construtor para criar novas instncias de cookies. Este construtor
utiliza dois argumentos do tipo String. O primeiro representa o nome do cookie e o
segundo, o valor correspondente.
Cookie cookie = new Cookie(Favorito, Banana Caramelada);
A tabela abaixo apresenta um resumo dos mtodos utilizados para armazenar e
recuperar as propriedades de um cookie. Observe que o texto armazenado em um
cookie pode ser modificado aps a sua construo, atravs do mtodo setValue(),
mas o nome do cookie s pode ser designado atravs do seu construtor.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 145
importante salientar que aps a construo de uma nova instncia de um cookie, ou
aps a modificao de uma instncia recuperada atravs do mtodo getCookies(),
necessrio utilizar o mtodo addCokkie() do objeto response para atualizar a
informao armazenada no browser.
Embora aparentemente meio sem sentido, esta abordagem tambm necessria para se
deletar um cookie. Primeiramente deve ser chamado o mtodo setMaxAge() do objeto
cookie com um valor zero (indicando que o cookie deve ser deletado). Ento, deve
ser chamado o mtodo addCookie() para informar ao browser que o cookie deve ser
deletado (substituindo-se o cookie por um que deve expirar imediatamente).
Um cookie enviado a um browser atravs do cabealho de uma resposta HTTP, e
cabealhos de respostas devem ser designados antes que qualquer contedo de corpo
(body) seja enviado ao browser. Logo, para que um mtodo addCookie() seja bem
sucedido em uma pgina JSP, ele deve ser chamado antes que o buffer de sada da
pgina seja enviado ao browser. Isto pode ocorrer quando o buffer de sada da pgina
JSP enche (dependendo do valor designado para o atributo autoflush da diretiva de
pgina.) O buffer de sada tambm enviado sempre que a ao <jsp:include>
encontrada.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 146
9.1.3 Exemplo 1: Criando um Cookie
<html>
<head>
<title>Pgina do Cookie Vermelho</title>
</head>
<%@ page import="java.util.Date" %>
<%@ page import="java.net.*" %>
<% String nomeDoCookie = "CookieVermelho";
Date now = new Date();
String timestamp = now.toString();
Cookie cookie =
new Cookie(nomeDoCookie, URLEncoder.encode(timestamp));
// cookie.setDomain("taglib.com");
// cookie.setPath("/jsp/aluno01/exercicio24");
cookie.setMaxAge(7 * 24 * 60 * 60); // Uma semana
cookie.setVersion(0);
cookie.setSecure(false);
cookie.setComment
("Este cookie armazena o timeStamp de criao do cookie.");
response.addCookie(cookie);
%>
<body>
<font color="red">
<h1>Pgina do Cookie Vermelho</h1>
<p>
Esta a pgina do cookie <i>vermelho</i>.<br>
Para ver a pgina do cookie azul clique
<a href="CookieAzul.jsp">aqui</a>.
</p>
</font>
</body>
</html>
O protocolo HTTP impe certas restries nos tipos de caracteres que podem aparecer
no valor de um cookie, logo conveniente utilizar o mtodo esttico encode da classe
URLencoder para resolver este problema.
O domnio e o caminho (diretrio base), se especificados, garantem que os cookies
criados desta forma podero ser acessados apenas por pginas armazenadas no mesmo
domnio e caminho especificados. Cookies seguros s podem ser enviados atravs do
protocolo HTTPS, que criptografa as requisies e as respostas. O argumento false
para o mtodo setSecure() indica que o cookie deve ser enviado atravs do protocolo
padro HTTP (no criptografado).
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 147
Contedo do Cookie colocado na pasta Temporay Internet Files do Windows:
CookieVermelho
Fri+Jul+07+13%3A32%3A48+GMT-03%3A00+2000
sbd/jsp/aluno01/exercicio24/
0
625342464
29355441
598127936
29354034
*
9.1.4 Exemplo 2: Recuperando um Cookie
A funo da pgina JSP apresentada acima atualizar um cookie que armazena o dia e
a hora que o usurio visitou esta pgina. Este cookie pode ser recuperado por outras
pginas JSP que compartilhem o mesmo domnio e caminho originalmente designado
ao cookie.
A seguir vem o cdigo da pgina que recupera o cookie e exibe seu contedo.
<html>
<head>
<title>Pgina do Cookie Azul</title>
</head>
<%@ page import="java.util.Date" %>
<%@ page import="java.net.*" %>
<% String nomeDoCookie = "CookieVermelho";
Cookie cookies[] = request.getCookies();
Cookie cookieVermelho = null;
if (cookies != null)
{ for (int i = 0; i < cookies.length; ++i)
{ if (cookies[i].getName().equals(nomeDoCookie))
{ cookieVermelho = cookies[i];
break;
}
}
}
%>
<body>
<font color="blue">
<h1>Pgina do Cookie Azul</h1>
<p>
Esta a pgina do cookie <i>azul</i>.<br>
Voc visitou a pgina do cookie
<a href="CookieVermelho.jsp">vermelho</a>
<% if (cookieVermelho == null)
{ %> h mais de uma semana.
<% }
else
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 148
{ %> em <%= URLDecoder.decode(cookieVermelho.getValue()) %>.
<% } %>
</p>
</font>
</body>
</html>
O primeiro scriptlet na pgina percorre um array de cookies retornado pelo mtodo
getCookies() at encontrar um cookie denominado CookieVermelho. O contedo
dinmico exibido por esta pgina ento baseado no fato do cookie ser encontrado ou
no.
Aviso: A classe java.net.URLDecoder foi adicionada linguagem Java na verso 1.2.
Verses anteriores da linguagem no incluem esta classe. Nestas verses mais antigas
utilizada a classe java.net.URLEncoder.
Restries ao Uso de Cookies
Cada cookie pode ocupar, no mximo, 4K. Um browser s obrigado a armazenar 20
cookies por domnio, e 300 cookies ao todo. Se qualquer destes limites for alcanado o
browser poder apagar os cookies acessados a mais tempo. O domnio designado a um
cookie deve ter pelo menos dois pontos no seu nome, como quando utilizado um
nome de servidor completamente qualificado. Por exemplo www.exemplo.com. Se um
nome de domnio (sem o nome do servidor) for utilizado, dever ser utilizada a sintaxe
.exemplo.com para satisfazer a regra dos dois pontos. O objetivo desta regra evitar
que sejam criados cookies que possam ser lidos por todo um domnio top-level (isto ,
.com, .org, .net, etc). Se nenhum domnio for especificado para um cookie, ele
poder ser lido apenas pelo host que o criou.
9.2 Criando Pginas de Erro
JavaServer Pages prov o atributo errorpage da diretiva de pgina, que permite a
especificao de uma pgina JSP alternativa para a qual o controle ser transferido
sempre que o processamento de uma pgina causar um erro. E a exceo que gerada
quando o erro ocorre poder ser acessada pela pgina de erro especificada atravs do
objeto implcito exception.
Pginas de erro JSP tambm podem ser utilizadas para tratar erros em servlets. Uma
pgina de erro JSP espera encontrar o objeto Throwable, representando o erro, em um
atributo do objeto implcito request associado ao nome
java.servlet.jsp.jspException. O cdigo de um servlet capaz de gerar uma
exceo pode utilizar um bloco try/catch para captur-la. Em seguida o servlet deve
armazenar a exceo no objeto request (atravs do mtodo setAttribute(String,
Object) e dar um forward para a pgina de erro JSP. A pgina de erro ser
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 149
responsvel por exibir o erro para o usurio e por logar o erro para o administrador do
sistema.
Nesta sesso, ser apresentada uma pgina de erro que pede desculpas ao usurio pelo
erro ocorrido enquanto constri uma mensagem de erro detalhada que enviada ao
webmaster via email. A API JavaMail da Sun utilizada para entregar o email.
9.2.1 Uma Pgina com Erro
Para que se possa testar a pgina de erro, preciso que uma pgina gere um erro. A
pgina abaixo produz um erro atravs de uma diviso por zero.
<html>
<head>
<%@ page errorPage="erro.jsp" session="false" %>
<title>Erro Aritmtico</title>
</head>
<body bgcolor="white">
<h1>Arithmetic Error</h1>
<% int x = 5; %>
<P>
Em Java, uma diviso por zero causa uma exceo:
<tt>25/0 = <%= 25/(5-x) %></tt>
</P>
</body>
</html>
Como o compilador reconhece que uma diviso por zero invlida, a varivel local x
foi introduzida para tornar a compilao bem sucedida.
9.9.2 Mtodos para a Coleta de Dados sobre o Erro
Sero examinados a seguir uma srie de mtodos que so utilizados para a
recuperao de informaes sobre o erro ocorrido. Como o controle transferido para
a pgina de erro, como se a ao <jsp:forward> tivesse sido utilizada, a pgina de
erro tem acesso ao objeto request implcito, assim como possui acesso ao objeto
exception implcito representando o erro que ocorreu na pgina original.
O primeiro mtodo makeErrorReport(). Este mtodo recebe como argumentos
valores correspondentes a estes dois objetos implcitos:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 150
public String makeErrorReport (HttpServletRequest req, Throwable e)
{ StringBuffer buffer = new StringBuffer();
reportException(buffer, e);
reportRequest(buffer, req);
reportParameters(buffer, req);
reportHeaders(buffer, req);
reportCookies(buffer, req);
return buffer.toString();
}
Este mtodo serve como uma rotina de controle para coletar informaes sobre a
requisio e sobre o erro ocorrido. Uma instncia de java.lang.StringBuffer
construda para armazenar esta informao, que ento passada para uma srie de
outros mtodos que armazenam vrias categorias de dados neste StringBuffer. Uma
vez coletados todos os dados, o contedo do buffer utilizado para gerar um objeto
String.
A pilha de trace, acrescentada ao StringBuffer pelo mtodo reportException(),
contm toda a informao disponvel sobre o erro ocorrido, incluindo uma mensagem
resumida do erro e a pilha de chamada aos mtodos que estavam sendo executados
quando a exceo ocorreu. Logo, os demais mtodos para a coleta de dados no esto
focados no erro, mas no contexto no qual ele ocorreu.
Informaes bsicas sobre a requisio so obtidas atravs do mtodo
reportRequest(). Este mtodo reconstri o URL utilizado para recuperar a pgina
original, assim como informaes sobre a sesso do usurio (se aplicvel).
public void reportRequest (StringBuffer buffer,
HttpServletRequest req)
{ buffer.append("Request: ");
buffer.append(req.getMethod());
buffer.append(' ');
buffer.append(HttpUtils.getRequestURL(req));
String queryString = req.getQueryString();
if (queryString != null)
{ buffer.append('?');
buffer.append(queryString);
}
buffer.append("\nSession ID: ");
String sessionId = req.getRequestedSessionId();
if (sessionId == null)
{ buffer.append("none");
}
else if (req.isRequestedSessionIdValid())
{ buffer.append(sessionId);
buffer.append(" (from ");
if (req.isRequestedSessionIdFromCookie())
buffer.append("cookie)\n");
else if (req.isRequestedSessionIdFromURL())
buffer.append("url)\n");
else
buffer.append("unknown)\n");
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 151
}
else
{ buffer.append("invalid\n");
}
}
Para reconstruir o URL, so recuperados do objeto
javax.servlet.http.HttpServletRequest as seguintes informaes: o mtodo
HTTP (GET ou POST) e o query string. No entanto, o protocolo, o nome do host, e
nmero da porta no so acessados diretamente a partir deste objeto. O mtodos
getRequestURL() da classe javax.servlet.http.HttpUtils utilizado para recriar
a base do URL.
As informaes sobre a sesso tambm so recuperadas do objeto request. Se existir
uma sesso no objeto request, ser includo em StringBuffer o cdigo identificador da
sesso do usurio e uma indicao de como a informao de sesso est sendo
transmitida do servidor para o browser do usurio (i., atravs de cookies ou URL
rewriting).
O mtodo reportParameters(), lista os parmetros de requisio que acompanharam
a requisio da pgina original. Note que a classe HttpServletRequest no faz
distino entre parmetros fornecidos no URL atravs de um query string e aqueles
fornecidos no corpo de uma requisio HTTP do tipo POST. De fato, ambos podem estar
presentes na mesma requisio, e sero combinados em um nico conjunto de
parmetros. Se vrios valores so fornecidos para um nico parmetro, todos os
valores so armazenados. O cdigo deste mtodo vem abaixo:
public void reportParameters (StringBuffer buffer,
HttpServletRequest req)
{ Enumeration names = req.getParameterNames();
if (names.hasMoreElements())
{ buffer.append("Parameters:\n");
while (names.hasMoreElements())
{ String name = (String) names.nextElement();
String[] values = req.getParameterValues(name);
for (int i = 0; i < values.length; ++i)
{ buffer.append(" ");
buffer.append(name);
buffer.append(" = ");
buffer.append(values[i]);
buffer.append('\n');
}
}
}
}
No cdigo acima, o mtodo getParameterNames() chamado para se obter uma
enumerao de todos os parmetros conhecidos pela requisio. Se existir pelo menos
um parmetro, o prximo passo imprimir o nome de cada parmetro e seus valores.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 152
Como um parmetro pode possuir vrios valores, um loop necessrio para se obter
todos os valores.
Aps listar os parmetros de requisio, o prximo passo listar o header da
requisio, utilizando-se o mtodo reportHeaders() abaixo:
public void reportHeaders (StringBuffer buffer,
HttpServletRequest req)
{ Enumeration names = req.getHeaderNames();
if (names.hasMoreElements())
{ buffer.append("Headers:\n");
while (names.hasMoreElements())
{ String name = (String) names.nextElement();
String value = (String) req.getHeader(name);
buffer.append(" ");
buffer.append(name);
buffer.append(": ");
buffer.append(value);
buffer.append('\n');
}
}
}
Headers contm informaes sobre o browser que originou a requisio, assim como
os cookies que o browser est enviando junto com a requisio. O mtodo
getHeaderNames() da classe HttpServletRequest chamado para gerar uma
enumerao dos nomes de cabealhos existentes na requisio. So adicionados ao
objeto StringBuffer (utilizado para gerar o relatrio de erros) o nome do cabealho e
seu valor correspondente recuperado atravs do mtodo getHeader() da classe
HttpServletRequest.
Infelizmente, embora o protocolo HTTP permita que requisies especifiquem vrios
headers com o mesmo nome, a classe HttpServletRequest prov mtodos para
recuperar um nico header para um determinado nome. Na prtica, a maioria dos
headers so apenas especificados uma vez, mas h uns poucos que regularmente
aparecem vrias vezes em uma nica requisio. Em particular, quando uma requisio
inclui vrios cookies, apenas um dos headers de cookies sero listados pelo mtodo
reportHeaders() descrito acima.
Por esta razo, o mtodo reportCookies() garante que todos os cookies que so
relevantes para a requisio so includos no relatrio de erros. O cdigo deste mtodo
vem a seguir:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 153
public void reportCookies (StringBuffer buffer,
HttpServletRequest req)
{ Cookie[] cookies = req.getCookies();
int l = cookies.length;
if (l > 0)
{ buffer.append("Cookies:\n");
for (int i = 0; i < l; ++i)
{ Cookie cookie = cookies[i];
buffer.append(" ");
buffer.append(cookie.getName());
buffer.append(" = ");
buffer.append(cookie.getValue());
buffer.append('\n');
}
}
}
Este mtodo lista os nomes dos cookies e seus valores.
9.2.3 Enviando Correio Eletrnico
Aps a utilizao de todos estes mtodos para se construir uma descrio do erro e da
requisio que o gerou, preciso uma forma de se entregar este texto para algum que
saiba corrigir o problema. Neste exemplo, o mecanismo utilizado uma mensagem de
correio eletrnico. Os mtodos descritos anteriormente sero utilizados para gerar o
corpo desta mensagem, que ser enviada atravs da API JavaMail. Esta API,
desenvolvida pela Sun MicroSystems, define um conjunto de classes Java para a
interao com servidores de correio, isto , para enviar e receber mensagens de correio
eletrnico.
Uma descrio completa da API JavaMail est alm do escopo desta apostila. Neste
exemplo, ser apresentado o mtodo sendEmail(), que encapsula todas as chamadas
JavaMail necessrias para efetuar a conexo com um servidor SMTP e enviar uma
simples mensagem de texto. A API JavaMail inclui, por exemplo, suporte para
recuperar mensagens de servidores POP e IMAP, assim como suporte para enviar
mensagens com arquivos anexados.
Em uma pgina JSP de tratamento de erro, no entanto, o envio de simples mensagens
de texto suficiente. Para este fim, o mtodo sendEmail() definido assim:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 154
public void sendEmail (String mailServer, String subject,
String to[], String from, String messageText)
throws AddressException, MessagingException
{ // Create session
Properties mailProps = new Properties();
mailProps.put("mail.smtp.host", mailServer);
//mailProps.put("mail.debug", true);
Session mailSession = Session.getDefaultInstance
(mailProps, null);
//mailSession.setDebug(true);
// Construct addresses
int toCount = to.length;
InternetAddress[] toAddrs = new InternetAddress[toCount];
for (int i = 0; i < toCount; ++i)
{ toAddrs[i] = new InternetAddress(to[i]);
}
InternetAddress fromAddr = new InternetAddress(from);
// Create and initialize message
Message message = new MimeMessage(mailSession);
message.setFrom(fromAddr);
message.setRecipients(Message.RecipientType.TO, toAddrs);
message.setSubject(subject);
message.setContent(messageText.toString(), "text/plain");
// Send message
Transport.send(message);
}
Todos os argumentos deste mtodo so instncias da classe String, exceto o argumento
to (os destinatrios) que um array de strings. O parmetro mailServer o nome de
um host de rede executando um servidor SMTP que ir efetivamente enviar a
mensagem. O argumento subject representa a linha de assunto da mensagem. O
parmetro from identifica o endereo de email do remetente. A validade deste
endereo de retorno pode ou no ser confirmada, dependendo de como o servidor SMTP
foi configurado. E o argumento messageText deve ser um string contento o corpo do
texto da mensagem que se deseja enviar.
Um conceito central da API JavaMail o de mail session, representando um
conjunto de interaes com o servidor de e-mail. Mail sessions so representadas
por uma instncia da classe javax.mail.Session, que inicializada a partir de uma
instncia da classe java.util.Properties. Para o objetivo que se pretende aqui, a
nica informao que necessita estar na lista de propriedades para que se possa
instanciar uma mail session a identificao do host SMTP, representada pela
propriedade denominada mail.smtp.host. O prximo passo a converso do
endereo de email passado como um String atravs dos argumentos to e from em
instncias da classe javax.mail.internet.InternetAdress. A seguir, contruda
uma instncia da classe javax.mail.Message. Esta uma classe abstrata, no entanto,
logo o objeto que realmente criado uma instncia de
javax.mail.internet.MimeMessage, cujo construtor utiliza uma instncia de
MailSession como seu nico argumento. As propriedades desta mensagem so
designadas, ento, para identificar o remetente, o assunto, os destinatrios, e o corpo da
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 155
mensagem. Observe que na chamada ao mtodo setContent() o tipo MIME da
mensagem designado para text/plain, indicando que o texto da mensagem
ASCII padro. E finalmente chamado o mtodo esttico send() da classe
javax.mail.Transport para enviar a mensagem.
Dentro do corpo deste mtodo, vrios chamadas a mtodos da API JavaMail podem
gerar excees. Como ser visto na prxima sesso, para esta aplicao (uma pgina
JSP para tratamento de erros) mais conveniente passar estas excees para os
mtodos chamadores do mtodo sendEmail(), em vez de tentar tratar estes
erros localmente. Por esta razo o mtodo sendEmail() foi declarado
gerando duas classes de excees, javax.mail.internet.AddressException e
javax.mail.MessagingException.
9.2.4 A pgina de Erro
Estes mtodos para a coleta de dados e para o envio de e-mail podem ser combinados
em uma pgina JSP para o tratamento de erros, de forma a informar usurios finais e
desenvolvedores quanto aos erros ocorridos. Segue abaixo o contedo desta pgina:
<html>
<head>
<%@ page isErrorPage="true" %>
<%@ page import="java.util.*, java.io.*" %>
<%@ page import="javax.mail.*, javax.mail.internet.*" %>
<title>Erro!</title>
</head>
<body bgcolor="white">
<p>Infelizmente ocorreu um erro:<br>
<center> <b><%= exception %></b> </center>
</p>
<% try
{ // Os parmetros abaixo so configurados e fornecidos como
// argumentos do mtodo sendEmail(), juntamente com a mensagem
// de texto gerada pelo mtodo makeErrorReport(). Se uma
// exceo for gerada pelo cdigo JavaMail, ento uma
// indicao deste fato aparecer na sada JSP.
String mailServer = "mailhost.mandic.com.br";
String subject = "Notificao de erro JSP";
String [] to = { "carlosar@osite.com.br" };
String from = "JSP Engine <carlosar@osite.com.br>";
sendEmail(mailServer, subject, to, from,
makeErrorReport(request, exception)); %>
<p>No se preocupe! As partes envolvidas j foram notificadas.</p>
<% }
catch (AddressException e)
{ %> <p>Endereo de e-mail invlido para a notificao de erro.</p>
<% }
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 156
catch (MessagingException e)
{ %> <p>Incapaz de enviar e-mail para a notificao de erro.</p>
<% } %>
</body>
</html>
<%!
public String makeErrorReport (HttpServletRequest req, Throwable e)
{ StringBuffer buffer = new StringBuffer();
reportException(buffer, e);
reportRequest(buffer, req);
reportParameters(buffer, req);
reportHeaders(buffer, req);
reportCookies(buffer, req);
return buffer.toString();
}
public void reportException (StringBuffer buffer, Throwable e)
{ StringWriter writer = new StringWriter();
e.printStackTrace(new PrintWriter(writer));
buffer.append(writer.getBuffer());
buffer.append('\n');
}
public void reportRequest (StringBuffer buffer,
HttpServletRequest req)
{ buffer.append("Request: ");
buffer.append(req.getMethod());
buffer.append(' ');
buffer.append(HttpUtils.getRequestURL(req));
String queryString = req.getQueryString();
if (queryString != null)
{ buffer.append('?');
buffer.append(queryString);
}
buffer.append("\nSession ID: ");
String sessionId = req.getRequestedSessionId();
if (sessionId == null)
{ buffer.append("none");
}
else if (req.isRequestedSessionIdValid())
{ buffer.append(sessionId);
buffer.append(" (from ");
if (req.isRequestedSessionIdFromCookie())
buffer.append("cookie)\n");
else if (req.isRequestedSessionIdFromURL())
buffer.append("url)\n");
else
buffer.append("unknown)\n");
}
else
{ buffer.append("invalid\n");
}
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 157
public void reportParameters (StringBuffer buffer,
HttpServletRequest req)
{ Enumeration names = req.getParameterNames();
if (names.hasMoreElements())
{ buffer.append("Parameters:\n");
while (names.hasMoreElements())
{ String name = (String) names.nextElement();
String[] values = req.getParameterValues(name);
for (int i = 0; i < values.length; ++i)
{ buffer.append(" ");
buffer.append(name);
buffer.append(" = ");
buffer.append(values[i]);
buffer.append('\n');
}
}
}
}
public void reportHeaders (StringBuffer buffer,
HttpServletRequest req)
{ Enumeration names = req.getHeaderNames();
if (names.hasMoreElements())
{ buffer.append("Headers:\n");
while (names.hasMoreElements())
{ String name = (String) names.nextElement();
String value = (String) req.getHeader(name);
buffer.append(" ");
buffer.append(name);
buffer.append(": ");
buffer.append(value);
buffer.append('\n');
}
}
}
public void reportCookies (StringBuffer buffer,
HttpServletRequest req)
{ Cookie[] cookies = req.getCookies();
int l = cookies.length;
if (l > 0)
{ buffer.append("Cookies:\n");
for (int i = 0; i < l; ++i)
{ Cookie cookie = cookies[i];
buffer.append(" ");
buffer.append(cookie.getName());
buffer.append(" = ");
buffer.append(cookie.getValue());
buffer.append('\n');
}
}
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 158
public void sendEmail (String mailServer, String subject,
String to[], String from,
String messageText)
throws AddressException, MessagingException
{ // Create session
Properties mailProps = new Properties();
mailProps.put("mail.smtp.host", mailServer);
//mailProps.put("mail.debug", true);
Session mailSession = Session.getDefaultInstance
(mailProps, null);
//mailSession.setDebug(true);
// Construct addresses
int toCount = to.length;
InternetAddress[] toAddrs = new InternetAddress[toCount];
for (int i = 0; i < toCount; ++i)
{ toAddrs[i] = new InternetAddress(to[i]);
}
InternetAddress fromAddr = new InternetAddress(from);
// Create and initialize message
Message message = new MimeMessage(mailSession);
message.setFrom(fromAddr);
message.setRecipients(Message.RecipientType.TO, toAddrs);
message.setSubject(subject);
message.setContent(messageText.toString(), "text/plain");
// Send message
Transport.send(message);
}
%>
9.3 Misturando JSP e JavaScript
JSP pode trabalhar em conjunto com JavaScript (e outras tecnologias client-side) para
adicionar processamento server-side a operaes tipicamente limitadas a atividades
client-side. Como exemplo, ser construdo um simples formulrio para reportar
problemas de sistema. Como requisito adicional, decidiu-se verificar a validade do
nome do host especificado pelo usurio antes de permitir que ele submeta o problema.
Tambm requerido que o host problemtico seja identificado por seu endereo IP, e
no pelo seu nome. O formulrio resultante vem na figura abaixo:
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 159
Quando o usurio digita um nome de host no campo Sistema Afetado do formulrio,
este valor alterado para o correspondente endereo IP no momento que o usurio
aperta a tecla TAB para mudar de campo. Se o endereo IP j for fornecido pelo
usurio, no ser modificado. Se o usurio digitar um nome de host invlido, uma
janela de alerta ir notific-lo deste fato e o formulrio no poder ser submetido
enquanto este problema no for corrigido. Tudo isto ocorre no cliente, antes de se
submeter o formulrio, e sem a necessidade do usurio recarregar manualmente a
pgina. Na verdade, a pgina que contm o formulrio, exibida acima, no sequer
uma pgina JSP. apenas uma pgina HTML com cdigo JavaScript embutido. Segue
abaixo o cdigo desta pgina.
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
resolvido=false;
function resolver(elemento)
{ top.oculto.document.location="resolver.jsp?host=" + elemento.value;
}
function estaResolvido()
{ alert(resolvido);
return resolvido;
}
</SCRIPT>
</HEAD>
<BODY>
<B>Relatrio de Problema de Sistema</B>
<P>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 160
<FORM NAME="info" ACTION="/servlet/problem"
onSubmit='return estaResolvido()'>
<TT>
Sistema Afetado: <INPUT type="text" name="host"
onChange='resolver(this)'> <BR>
Operador do Sistema: <INPUT type="text" name="usuario"> <BR>
Problemas do Sistema: <INPUT type="text" name="problema"> <BR>
</TT>
<P>
<INPUT type="submit" value="Enviar">
</FORM>
</BODY>
</HTML>
Examinando-se o cdigo HTML acima verifica-se que ele faz referncia a um outro
frame denominado resolver, onde a pgina resolver.jsp carregada. esta
segunda pgina que uma pgina JSP que efetivamente efetua a resoluo do nome
do host. Ela aparece na base da pgina em um frame escondido, utilizando o cdigo
frameset abaixo:
<HTML>
<HEAD><TITLE>Formulrio para a Submisso de Problemas</TITLE></HEAD>
<FRAMESET ROWS="100%, 0%" BORDER=0 FRAMEBORDER="no">
<FRAME SRC="form.html" NAME="visivel">
<FRAME NAME="oculto">
</FRAMESET>
</HTML>
Quando o usurio modifica o campo Sistema Afetado, o manipulador onChange()
no tag <INPUT> deste campo chama a funo resolve() uma funo JavaScript
client-side para carregar a pgina JSP no frame escondido. Esta funo tambm
concatena o valor do campo requisio, passando para a pgina JSP o nome do host
que precisa ser verificado. A pgina JSP tenta resolver o nome do host. Se a pgina
tiver sucesso, h duas coisas a fazer: modificar o valor do campo Sistema Afetado
para o endereo IP verificado, e alertar o documento que um nome de host vlido foi
informado. Isto feito atravs de cdigo JavaScript cross-frame.
<SCRIPT>
top.visivel.document.info.host.value="<%= ip %>";
top.visivel.resolvido=true;
</SCRIPT>
Se o nome do host for invlido, o usurio alertado limpando-se o contedo do campo,
conforme vem abaixo:
<SCRIPT>
alert("Nome de Host Invlido: <%= host %>");
top.visivel.document.info.host.value="";
top.visivel.resolvido=false;
top.visivel.document.info.host.focus();
</SCRIPT>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 161
Note que possvel embutir comandos JSP no meio do cdigo JavaScript. O cdigo
fonte completo da pgina resolver.jsp vem abaixo:
<%@ page import="java.net.*" %>
<HTML>
<HEAD>
<%
String host = request.getParameter("host");
String ip = host;
if (host != null)
{ try
{ ip = java.net.InetAddress.getByName(host).getHostAddress();
%>
<SCRIPT>
top.visivel.document.info.host.value="<%= ip %>";
top.visivel.resolvido=true;
</SCRIPT>
<%
}
catch (UnknownHostException e)
{ %> <SCRIPT>
alert("Nome de Host Invlido: <%= host %>");
top.visivel.document.info.host.value="";
top.visivel.resolvido=false;
top.visivel.document.info.host.focus();
</SCRIPT>
<%
}
}
%>
</BODY>
</HTML>
Observe que o mtodo getHostAddress() gera uma UnknownHostException se ele
no for capaz de resolver o nome corretamente. Por esta razo ele executado dentro
de um bloco try/catch, que possui o efeito colateral de determinar que cdigo
JavaScript deve ser executado.
9.4 Construindo Interfaces Interativas
Utilizando JSP possvel criar aplicaes para a web com um look and feel similar
ao das aplicaes desktop.
Quando uma pgina HTML contendo um formulrio carregada no browser o estado dos
seus elementos est codificado no HTML. Se o formulrio preenchido uma vez, e em
seguida revisitado, o estado e contedo de todos os elementos na pgina so perdidos e
o formulrio reverte para a sua condio original especificada no cdigo HTML.
Requisies HTTP, a menos que cookies estejam sendo utilizados, no possuem
memria. A nica forma dos elementos de uma pgina manterem o estado da
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 162
informao entre requisies atravs da gerao dinmica de HTML visando controlar
o layout e o contedo do formulrio. Desta forma possvel representar o estado que
se deseja apresentar.
Por exemplo, se um usurio seleciona um checkbox ou um radio button antes de
submeter o formulrio, este elemento deve aparecer selecionado quando o formulrio
for reexibido. Se uma caixa de texto tinha texto antes da pgina ser submetida, da
mesma forma, deveria aparecer com o mesmo texto ao ser reexibida. Logo, para cada
elemento da interface preciso ter um valor que represente o seu estado logo antes do
usurio pressionar o boto submit. Estes valores so submetidos como parmetros de
requisio.
9.4.1 Mtodos Utilitrios
Para ajudar no processo de extrao de valores de parmetros de requisies, sero
apresentados alguns mtodos que sero utilizados no exemplo de interface interativa. O
primeiro mtodo, getParam(), vem definido a seguir:
public String getParam (HttpServletRequest request, String param)
{ if (request.getParameter(param) == null)
return "";
else
return request.getParameter(param);
}
Este mtodo extrai da requisio o valor do parmetro cujo nome fornecido. Se o
parmetro no existe na requisio, um String vazio retornado (em vez de null).
Para aqueles parmetros que podem possuir vrios valores, foi criado um mtodo
denominado getParamValues().
public String getParamValues (HttpServletRequest request,
String param)
{ String values[] = request.getParameterValues(param);
if (values == null) return "";
int count = values.length;
switch (count)
{ case 1:
return values[0];
default:
StringBuffer result = new StringBuffer(values[0]);
int stop = count - 1;
if (stop > 1) result.append(", ");
for (int i = 1; i < stop; ++i)
{ result.append(values[i]);
result.append(", ");
}
result.append(" and ");
result.append(values[stop]);
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 163
return result.toString();
}
}
Assim como o mtodo getParam(), este mtodo tambm retorna um String vazio
quando o parmetro no especificado. No entanto, quando um ou mais valores so
especificados, este mtodo retorna um String contendo os valores separados por
vrgulas e seguido da palavra and no final.
O prximo mtodo, requestContains(), utilizado para se determinar se um valor
especfico foi fornecido ou no em um parmetro de requisio.
public boolean requestContains (HttpServletRequest request,
String param, String test)
{ String rp[] = request.getParameterValues(param);
if (rp == null)
return false;
for (int i=0; i < rp.length; i++)
if (test.equals(rp[i]))
return true;
return false;
}
E os dois ltimos mtodos estendem a funcionalidade do mtodo requestContains()
para retornar valores de String especficos quando se constata que um valor especfico
foi fornecido em um parmetro de requisio.
public String isChecked (HttpServletRequest request,
String param, String test)
{ if (requestContains(request, param, test))
return "checked";
else
return "";
}
public String isSelected (HttpServletRequest request,
String param, String test)
{ if (requestContains(request, param, test))
return "selected";
else
return "";
}
Estes dois ltimos mtodos sero particularmente teis na inicializao de botes de
rdio, caixas de confirmao, e caixas de seleo.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 164
9.4.2 O Formulrio Exemplo
O formulrio que ser utilizado neste exemplo vem na figura abaixo.
Quando um dos dois botes de submisso do formulrio clicado, o formulrio chama
a si prprio para processar os dados do formulrio e reexibe o formulrio. O resultado
do processamento do formulrio neste caso, uma sentena construda a partir dos
valores selecionados exibido na base da pgina. Toda vez que o formulrio
exibido, os valores default para todos os campos de entrada de dados so baseados nos
valores recm informados pelo usurio.
9.4.3 Criando o Formulrio
A seguinte expresso JSP pode ser utilizada para se criar um formulrio que chama ele
prprio, independentemente do URL utilizado para cham-lo. Isto ir permitir que a
aplicao seja movida para qualquer lugar sem que seja necessrio modificar qualquer
cdigo.
<form action="<%= HttpUtils.getRequestURL(request) %>" method="post">
Esta tcnica funciona apenas se a pgina JSP chamada diretamente. Se, por exemplo,
a pgina JSP for carregada atravs de um servlet utilizando o mtodo forward() da
classe RequestDispatcher, a informao de caminho pode estar incorreta, uma vez
que RequestDispatcher automaticamente muda a informao de caminho no objeto
request para refletir o novo endereo de destino. Isto pode ser um problema se a
requisio original foi intencionalmente direcionada a um servlet, logo as requisies
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 165
subsequentes necessitaro ser chamadas atravs do mesmo servlet. Neste caso,
possvel obter um URL local (sem o nome de host, protocolo e porta) para a pgina
corrente chamando-se o mtodo getServletPath() do objeto request.
9.4.4 Campos de Texto e Escondidos
O contedo inicial de um campo de texto (text field) armazenado no atributo value
do tag <INPUT> que define este campo. Campos escondidos (hidden fields) so
inicializados da mesma forma, mas seus contedos no so exibidos e
consequentemente no podem ser editados pelo usurio. Para fazer com que um destes
tipos de elementos reflitam o estado de um parmetro de requisio, deve-se utilizar
uma expresso JSP contendo uma chamada ao mtodo getParam() entre as aspas do
atributo value. Quando o formulrio recriado aps o processamento da requisio ele
deve reter o valor original.
<B>Nome: </B><INPUT type=text name=cliente
value=<%= getParam(request, cliente) %>>
Supondo que o valor digitado no campo acima seja Vinicius, quando a pgina JSP
for processada em funo da submisso do formulrio, ela ir gerar a seguinte sada
para o tag <INPUT>:
<B>Nome: </B><INPUT type=text name=cliente value=Vinicius>
Como resultado, o valor default para este campo de entrada de dados especificado
atravs do atributo value ser Vinicius. O tag <INPUT> foi reescrito para conter um
valor default igual ao ltimo valor digitado pelo usurio. Esta a forma de se manter o
estado de um formulrio entre requisies.
Observao: preciso efetuar o escape de quaisquer aspas existentes no string
utilizado para popular o atributo value do campo de texto, caso contrrio, as aspas iro
causar o trmino prematuro deste string, resultando em um comando HTML invlido.
9.4.5 reas de Texto
Para se determinar o valor inicial de uma rea de texto (campo do tipo Text Area)
ainda mais simples: um par de tags <textarea> definem a rea de texto, e o corpo
entre estes dois tags definem seu contedo.
<textarea cols="40" rows="5" name="message">
<%= getParam(request, "message") %>
</textarea>
Assim como os demais elementos do formulrio, o nome do parmetro de requisio
corresponde ao identificador (atributo name) do elemento no formulrio.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 166
Uma rea de texto pode conter qualquer texto. O nico problema se esta rea contiver
o literal </textarea>. Neste caso ser necessrio proteger o campo do formulrio
convertendo os smbolos < e > em entidades equivalentes: &lt e &gt.
9.4.6 Botes de Rdio
Botes de rdio possuem um conjunto fixo de valores possveis. Geralmente existem
vrios botes de rdio com o mesmo nome, formando um grupo. Para especificar que
um destes elementos de formulrio deve aparecer habilitado quando a pgina
carregada, preciso incluir a palavra chave checked dentro do tag <input>. Apenas
um elemento no grupo de botes deve ser marcado como checked.
<input type="radio" name="gender" value="his"
<%= isChecked(request, "gender", "his") %>><i>male</i><BR>
<input type="radio" name="gender" value="her"
<%= isChecked(request, "gender", "her") %>><i>female</i><BR>
O mtodo isChecked utilizado para comparar o valor designado a cada boto de
rdio com o valor armazenado no parmetro de requisio. Se estes valores forem
iguais (este foi o boto de rdio selecionado), a palavra chave checked inserida no
tag <input>, caso contrrio inserido um String vazio.
9.4.7 Caixas de Seleo
Caixas de seleo (Select Boxes) permitem que um usurio faa uma seleo a partir
de um conjunto existente de opes. A seleo inicial para o grupo indicada pela
palavra chave select dentro do tag <option>. Consequentemente, possvel a
utilizao de uma tcnica similar utilizada com botes de rdio.
<select name="device">
<option value="tank" <%= isSelected(request, "device", "tank") %>>Tank
<option value="disk" <%= isSelected(request, "device", "disk") %>>Disk
<option value="light cycle" <%= isSelected(request, "device", "light
cycle") %>>Light Cycle
</select>
A nica diferena em relao aos botes de rdio que aqui foi utilizado o mtodo
isSelected() que reflete a mudana de palavra chave para identificar que item foi
selecionado.
9.4.8 Caixas de Confirmao
Caixas de confirmao (Check Boxes) podem ser utilizadas para se selecionar vrias
opes a partir de um conjunto de valores possveis para um parmetro de requisio.
Para se especificar que uma caixa de confirmao deve aparecer habilitada, preciso
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 167
incluir a palavra chave checked dentro do tag <input>. No caso das caixas de
confirmao, no entanto, no um problema se mais de uma for selecionada.
<input type="checkbox" name="colors" value="red"
<%= isChecked(request, "colors", "red") %>><i>red</i><BR>
<input type="checkbox" name="colors" value="yellow"
<%= isChecked(request, "colors", "yellow") %>><i>yellow</i><BR>
<input type="checkbox" name="colors" value="blue"
<%= isChecked(request, "colors", "blue") %>><i>blue</i><BR>
No exemplo acima note que o mesmo identificador colors foi especificado para
todas as trs caixas de confirmao atravs do atributo name do tag <INPUT>. Como
resultado, todos os valores selecionados sero designados como valores mltiplos do
parmetro de requisio correspondente (tambm denominado colors).
9.4.9 Cdigo Fonte do Formulrio
Uma tabela HTML utilizada para controlar o layout do formulrio. Para o formulrio
foram criados dois botes Submit. O cdigo JSP na base da pgina, que implementa o
manipulador do formulrio, pode distinguir entre estes botes verificando o valor do
parmetro de requisio denominado submittedVia, que corresponde ao identificador
designado a estes dois botes atravs do atributo name do tag <INPUT>. O cdigo
manipulador do formulrio pode deduzir a partir da ausncia deste parmetro de
requisio, que o formulrio ainda tem que ser submetido, como indicado pelo scriptlet
que checa o resultado da chamada ao mtodo getParam() para este parmetro, para
verificar se ele est vazio.
<html>
<body>
<%!
public String getParam (HttpServletRequest request, String param)
{ if (request.getParameter(param) == null)
return "";
else
return request.getParameter(param);
}
public String getParamValues (HttpServletRequest request,
String param)
{ String values[] = request.getParameterValues(param);
if (values == null) return "";
int count = values.length;
switch (count)
{ case 1:
return values[0];
default:
StringBuffer result = new StringBuffer(values[0]);
int stop = count - 1;
if (stop > 1) result.append(", ");
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 168
for (int i = 1; i < stop; ++i)
{ result.append(values[i]);
result.append(", ");
}
result.append(" and ");
result.append(values[stop]);
return result.toString();
}
}
public boolean requestContains (HttpServletRequest request,
String param, String test)
{ String rp[] = request.getParameterValues(param);
if (rp == null)
return false;
for (int i=0; i < rp.length; i++)
if (test.equals(rp[i]))
return true;
return false;
}
public String isChecked (HttpServletRequest request,
String param, String test)
{ if (requestContains(request, param, test))
return "checked";
else
return "";
}
public String isSelected (HttpServletRequest request,
String param, String test)
{ if (requestContains(request, param, test))
return "selected";
else
return "";
}
%>
<form action="<%= HttpUtils.getRequestURL(request) %>" method="post">
<table bgcolor="lightgrey" align="center" border="1" cellpadding="5">
<tr align="left" valign="top">
<td valign="top" rowspan="2">
<b>Name</b>&nbsp;
<input type="text" name="character"
value="<%= getParam(request, "character") %>">
<P>
<b>Device</b>
<select name="device">
<option value="tank" <%= isSelected(request, "device", "tank") %>>Tank
<option value="disk" <%= isSelected(request, "device", "disk") %>>Disk
<option value="light cycle" <%= isSelected(request, "device", "light
cycle") %>>Light Cycle
</select>
</td>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 169
<td><b>Gender</b></td>
<td><b>Color</b></td></tr>
<tr>
<td>
<input type="radio" name="gender" value="his"
<%= isChecked(request, "gender", "his") %>><i>male</i><BR>
<input type="radio" name="gender" value="her"
<%= isChecked(request, "gender", "her") %>><i>female</i><BR>
</td>
<td>
<input type="checkbox" name="colors" value="red"
<%= isChecked(request, "colors", "red") %>><i>red</i><BR>
<input type="checkbox" name="colors" value="yellow"
<%= isChecked(request, "colors", "yellow") %>><i>yellow</i><BR>
<input type="checkbox" name="colors" value="blue"
<%= isChecked(request, "colors", "blue") %>><i>blue</i><BR>
</td>
</tr>
<tr>
<td colspan="3" align="center" valign="center">
<b>Message</b><br>
<textarea cols="40" rows="5" name="message">
<%= getParam(request, "message") %>
</textarea>
</td>
</tr>
</table>
<P>
<center>
<input type="submit" name="submittedVia" value="Declare">
&nbsp;
<input type="submit" name="submittedVia" value="Taunt">
</center>
</P>
<hr width="75%">
<%-- FORM HANDLING CODE --%>
<h2>Result</h2>
<% String submission = getParam(request, "submittedVia");
if (submission.equals("")) { %>
The form has not yet been submitted.
<% } else {
String verb = (submission.equals("Taunt")) ? "taunts" :
"declares";
%>
<%= getParam(request, "character") %>, manning
<%= getParam(request, "gender") %>&nbsp;
<%= getParamValues(request, "colors") %>&nbsp;
<%= getParam(request, "device") %>,
<%= verb %> "<b><%= getParam(request, "message") %></b>"
<% } %>
</form>
</body>
</html>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 170
9.5 Validando Dados de Formulrio
9.5.1 Validao de Dados nos Lados Cliente e Servidor
A validao de dados no lado cliente efetuada com JavaScript. E quem garante que
o cdigo JavaScript ser executado o browser. Mas quem garante que o usurio
est utilizando um browser? A verdade que os usurios podem submeter o que eles
quiserem construindo seus prprios formulrios, criando seu prprio software cliente
ou conectando-se ao servidor HTTP diretamente.
J a validao no lado servidor est sob o controle completo do programador da
aplicao. Esta validao pode ser efetuada pelo servlet ou pela pgina JSP responsvel
pelo processamento da informao.
Ao se detectar um erro no preenchimento de um formulrio preciso reenviar o
formulrio (com os campos preenchidos) para que o usurio possa fazer as correes.
Se for utilizada uma pgina JSP para coletar os dados atravs de um formulrio, o
servlet pode passar os valores dos campos do formulrio de volta pgina JSP para
que ela seja enviada novamente ao cliente, para as correes devidas.
Para que o desempenho de uma aplicao no fique prejudicado com a validao no
lado servidor, recomenda-se que ela seja efetuada em ambos os lados: cliente e
servidor.
9.5.2 Exemplo de Validao no Lado Servidor
Este exemplo efetua a validao de nome, endereo de email e CPF.
O FormBean
package jsp.aluno01.exercicio28;
public class FormBean
{ private String nome;
private String email;
private String cpf;
public FormBean()
{ nome = "";
email = "";
cpf = "";
}
public void setNome(String nome)
{ this.nome = nome;
}
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 171
public String getNome()
{ return nome;
}
public void setEmail(String email)
{ this.email = email;
}
public String getEmail()
{ return email;
}
public void setCpf(String cpf)
{ this.cpf = cpf;
}
public String getCpf()
{ return cpf;
}
}
O Formulrio JSP
Esta pgina JSP possui vrias funes. Primeiro deve popular um objeto FormBean
utilizando os dados existentes na requisio. Se o servlet FormHandlerServlet tiver
problemas na validao dos dados, a requisio ser redirecionada de volta para esta
pgina. Toda vez que esta pgina acessada diretamente (quando o usurio digita o
URL da pgina no browser) um novo objeto FormBean criado com valores default
vazios. Se esta pgina acessada indiretamente (atravs do servlet
FormHandlerServlet) um novo objeto FormBean criado com os valores informados
pelo usurio. Se quaisquer erros de uma submisso anterior forem detectados, a pgina
deve exibi-los.
<jsp:useBean id="form" class="jsp.aluno01.exercicio28.FormBean">
<jsp:setProperty name="form" property="*"/>
</jsp:useBean>
<html>
<body bgcolor="white">
<%
String[] erros = (String[])request.getAttribute("erros");
if (erros != null && erros.length > 0)
{
%>
<b>Por Favor Corrija os Seguintes Erros</b>
<ul>
<% for (int i=0; i < erros.length; i++)
{ %> <li> <%= erros[i] %>
<% } %>
</ul>
<% } %>
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 172
<form action="<%= request.getContextPath() %>
/servlet/jsp.aluno01.exercicio28.FormHandlerServlet" method="post">
<input type="text" name="nome"
value="<jsp:getProperty name="form" property="nome"/>">
<b>Nome</b> (ltimo, Primeiro)<br>
<input type="text" name="email"
value="<jsp:getProperty name="form" property="email"/>">
<b>E-Mail</b> (usuario@host)<br>
<input type="text" name="cpf"
value="<jsp:getProperty name="form" property="cpf"/>">
<b>CPF</b> (123456789)<br>
<p>
<input type="submit" value="Submit Form">
</form>
</body>
</html>
O Manipulador do Formulrio
O servlet responsvel por validar os dados informados pelo usurio, e por
redirecionar o usurio para a pgina seguinte.
package jsp.aluno01.exercicio28;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
public class FormHandlerServlet extends HttpServlet
{ public void service(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{ Vector erros = new Vector();
String nome = req.getParameter("nome");
String cpf = req.getParameter("cpf");
String email = req.getParameter("email");
if (! isValidNome(nome))
erros.add("Por favor informe: ltimo nome, primeiro nome.");
if (! isValidEmail(email))
erros.add("Endereo de email deve conter um smbolo @.");
if (! isValidCPF(cpf))
erros.add("Escecifique um CPF vlido, sem traos.");
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 173
String proximo;
if (erros.size() == 0)
{ // Se os dados esto corretos pode prosseguir.
proximo = "obrigado.jsp";
}
else
{ // Dados com erros. Tente novamente.
String[] errorArray =
(String[])erros.toArray(new String[0]);
req.setAttribute("erros", errorArray);
proximo = "formulario.jsp";
}
String base = "/jsp/aluno01/exercicio28/";
RequestDispatcher rd;
rd = getServletContext().getRequestDispatcher(base + proximo);
rd.forward(req, res);
}
private boolean isValidCPF(String cpf)
{ // verifica se h 11 caracteres, sem traos.
return (cpf.length() == 11 && cpf.indexOf("-") == -1);
}
private boolean isValidEmail(String email)
{ // Verifica se h um "@" em algum lugar aps o 1 caracter.
return (email.indexOf("@") > 0);
}
private boolean isValidNome(String nome)
{ // Deve ser: ultimo nome, primeiro nome
// Verifica a existncia da vrgula.
return (nome.indexOf(",") != -1);
}
}
O servlet extrai do objeto request os parmetros (nome, cpf e email) e os valida. Para
cada validao que falha, o servlet adiciona uma nova mensagem ao Vector erros, que
contm uma lista de todos os erros encontrados durante o processo de validao. Se
nenhum erro encontrado, o servlet despacha a requisio para a pgina
obrigado.jsp.
Quando erros so encontrados, eles so empacotados como um atributo de requisio
antes de serem despachados de volta para a pgina formulario.jsp. Quando esta
requisio processada pela pgina JSP, os parmetros de requisio originais e a lista
de mensagens de erro esto presentes no objeto request. O tag <jsp:useBean> cria
uma instncia de FormBean e utiliza um caracter curinga para popul-lo com os dados
originais do formulrio. Logo antes de exibir o formulrio preciso verificar a
presena da lista de erros.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 174
<%
String[] erros = (String[])request.getAttribute("erros");
if (erros != null && erros.length > 0)
{
%>
<b>Por Favor Corrija os Seguintes Erros</b>
<ul>
<% for (int i=0; i < erros.length; i++)
{ %> <li> <%= erros[i] %>
<% } %>
</ul>
<% } %>
A Pgina Obrigado
Quando o formulrio submetido com sucesso, um novo Bean populado com os
dados da requisio bem sucedida. Isto permite que estes dados sejam exibidos ao
usurio com uma mensagem que indica que o formulrio foi processado com sucesso.
<jsp:useBean id="form" class="jsp.aluno01.exercicio28.FormBean">
<jsp:setProperty name="form" property="*"/>
</jsp:useBean>
<html>
<body bgcolor="white">
<b>Obrigado! Seu formulrio foi recebido.</b>
<ul>
<b>Nome: </b><jsp:getProperty name="form" property="nome"/><br>
<b>Email: </b><jsp:getProperty name="form" property="email"/><br>
<b>CPF: </b><jsp:getProperty name="form" property="cpf"/><br>
</ul>
</body>
</html>
9.6 Tarefas Variadas
9.6.1 Determinando a ltima Data de Modificao de uma Pgina
preciso, inicialmente, mapear o caminho da pgina para um arquivo em disco. O
mtodo getServletPath() do objeto implcito request pode ser utilizado para se
determinar seu caminho relativo aplicao, e ento utilizar o objeto implcito
application (uma instncia de ServletContext) para determinar o caminho real da
pgina JSP. Isto permite que seja criada um objeto Date, baseado na ltima data de
modificao do arquivo JSP.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 175
<%@ page import=java.io.*, java.util.* %>
<% File f = new
File(application.getRealPath(request.getServletPath()));
%>
<% Date dataModificacao = new Date(f.getLastModified()); %>
<HTML>
<BODY>
Esta pgina foi modificada em: <%= dataModificacao %>
</BODY>
</HTML>
Considerando a brevidade deste cdigo e sua utilidade, seria interessante empacotar
esta funcionalidade para facilitar seu reuso. Um mecanismo seria a criao de uma
pequena pgina JSP que possa ser incorporada em outras pginas JSP atravs da
diretiva include. (Note que o tag <jsp:include> no deve ser utilizado aqui, pois
resultaria no clculo da ltima data de modificao do arquivo includo.
Alternativamente, poderia ser criado um tag customizado para este fim.
9.6.2 Executando Comandos de Sistema
Assim como outros programas Java, possvel utilizar pginas JSP para executar
comandos externos. possvel inclusive utilizar uma Interface Nativa Java para
executar cdigo nativo armazenado dentro de bibliotecas ou DLLs. ( preciso no
esquecer, evidentemente, que se trata de cdigo nativo da plataforma servidora, e no
cliente, j que pginas JSP so executadas no servidor).
O cdigo abaixo mostra como exibir a sada de um comando executado no servidor.
Neste exemplo o comando executado retorna o nome do host.
<%@ page import="java.io.*" %>
<%!
public String run(String cmd)
{ try
{ Runtime rt = Runtime.getRuntime();
Process p = rt.exec(cmd);
InputStreamReader in =
new InputStreamReader(p.getInputStream());
BufferedReader reader = new BufferedReader(in);
StringBuffer buf = new StringBuffer();
String line;
String newline = "\n";
while ((line = reader.readLine()) != null)
{ buf.append(line);
buf.append(newline);
}
reader.close();
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 176
p.waitFor();
return buf.toString();
}
catch (Exception e)
{ return (e.getMessage());
}
}
%>
<html>
<body>
O nome do host : <%= run("c://winnt//system32//hostname.exe") %>
</body>
</html>
Neste exemplo foi utilizada uma instncia de java.io.BufferedReader para ler uma
linha de cada vez.
9.6.3 Gerando XML
Gerar sada XML a partir de uma pgina JSP to simples quanto gerar HTML. Os
elementos JSP podem ser adicionados a um documento contendo tags XML.
necessrio, no entanto, utilizar a diretiva de pgina para indicar o tipo de contedo do
documento, como no exemplo abaixo:
<%@ page contentType=text/xml %>
<jsp:useBean id=book class=com.taglib.wdjsp.commontasks.BookBean
scope=request />
<?xml version=1.0 encoding=ISSO-8859-1 ?>
<!DOCTYPE book
PUBLIC -//Manning Publications Co.//DTD Book Catalog//EN
http://www.manning.com/dtds/catalog.dtd>
<book>
<title><jsp:getProperty name=book property=title/></title>
<author><jsp:getProperty name=book property=author/></author>
<publisher><jsp:getProperty name=book property=publisher/>
</publisher>
<ISBN><jsp:getProperty name=book property=ISBN/></ISBN>
</book>
Aqui os dados que populam este documento XML so obtidos das propriedades de um
BookBean hipottico. Tags JSP para JavaBeans foram utilizados para carregar
informaes sobre um livro especfico nos campos correspondentes dos tags XML do
documento.
____________________________________________________________________________________
____________________________________________________________________________________
Apostila de JSP 177
10. BIBLIOGRAFIA
Duane K. Fields e Mark A. Kolb, Web Development with Java Server Pages, Ed.
Manning, 2000.

Você também pode gostar