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

____________________________________________________________________________________

ndice
1. INTRODUO .................................................................................................................................. 5 1.1 1.2 1.3 Desempenho ............................................................................................................................. 5 Separando a Apresentao da Implementao.......................................................................... 7 Diviso do Trabalho ................................................................................................................. 8

2. FUNDAMENTOS............................................................................................................................... 9 2.1 2.2 2.3 2.4 2.5 Primeiro Exemplo de Pgina JSP ............................................................................................ 9 Segunda Verso do Exemplo Al Mundo ................................................................................ 9 Verso do Exemplo Al Mundo com Bean ............................................................................ 10 Convenes sobre Tags .......................................................................................................... 12 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 2

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

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

____________________________________________________________________________________

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 5

____________________________________________________________________________________

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 6

____________________________________________________________________________________

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 7

____________________________________________________________________________________

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 8

____________________________________________________________________________________

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 9

____________________________________________________________________________________

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 traduzilos 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 10

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

____________________________________________________________________________________

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 12

____________________________________________________________________________________

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 13

____________________________________________________________________________________

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 prcompilada pelo container JSP antes de qualquer usurio requisitar por esta pgina.
____________________________________________________________________________________ Apostila de JSP 14

____________________________________________________________________________________

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 15

____________________________________________________________________________________

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 16

____________________________________________________________________________________

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 17

____________________________________________________________________________________

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 18

____________________________________________________________________________________

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 19

____________________________________________________________________________________

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 20

____________________________________________________________________________________

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 21

____________________________________________________________________________________

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 22

____________________________________________________________________________________

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 23

____________________________________________________________________________________

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 24

____________________________________________________________________________________

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 25

____________________________________________________________________________________ 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 { // } public { // } %> void jspInit() Cdigo de inicializao aparece aqui! 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 26

____________________________________________________________________________________

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 27

____________________________________________________________________________________

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 28

____________________________________________________________________________________

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) } else { } %> %>

%>

<p> Argumentos maiores do que 20 causam um erro de overflow.</p> <p align=center><%= x %>! = <%=fatorial(x) %></p>

____________________________________________________________________________________ Apostila de JSP 29

____________________________________________________________________________________

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 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 x! 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 479001600 6227020800 87178291200 1307674368000 20922789888000 355687428096000 6402373705728000 121645100408832000 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 30

____________________________________________________________________________________

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 31

____________________________________________________________________________________

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 32

____________________________________________________________________________________

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 33

____________________________________________________________________________________

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 34

____________________________________________________________________________________

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 35

____________________________________________________________________________________

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 36

____________________________________________________________________________________

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 request objeto 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 37

____________________________________________________________________________________

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 38

____________________________________________________________________________________

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 39

____________________________________________________________________________________

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 40

____________________________________________________________________________________

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 41

____________________________________________________________________________________ <% 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 42

____________________________________________________________________________________

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 43

____________________________________________________________________________________

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 44

____________________________________________________________________________________

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 45

____________________________________________________________________________________

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 46

____________________________________________________________________________________

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 47

____________________________________________________________________________________

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 48

____________________________________________________________________________________

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 49

____________________________________________________________________________________

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 50

____________________________________________________________________________________

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 51

____________________________________________________________________________________

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 52

____________________________________________________________________________________

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 53

____________________________________________________________________________________

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 54

____________________________________________________________________________________

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 55

____________________________________________________________________________________

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 56

____________________________________________________________________________________

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 obtmse 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 readonly. 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 57

____________________________________________________________________________________

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

____________________________________________________________________________________

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 59

____________________________________________________________________________________

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 60

____________________________________________________________________________________

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 61

____________________________________________________________________________________

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 62

____________________________________________________________________________________

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 63

____________________________________________________________________________________

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 64

____________________________________________________________________________________ <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 65

____________________________________________________________________________________ <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 66

____________________________________________________________________________________

Folha de propriedades do Bean Nome principal taxaDeJuros anos valorFuturo Acesso read/write read/write read/write read-only Tipo Java double double int String Exemplo 100.50 .10 10 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 67

____________________________________________________________________________________

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 68

____________________________________________________________________________________

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 69

____________________________________________________________________________________

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 70

____________________________________________________________________________________ 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 71

____________________________________________________________________________________

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 elapsedMillis elapsedSeconds elapsedMinutes startTime Acesso read-only read-only read-only read/write Tipo Java long long long long Exemplo 180000 180 3 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 72

____________________________________________________________________________________

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 73

____________________________________________________________________________________

pgina dependente necessitar acessar o Bean. Tambm seria possvel serializar o Bean pr-configurado para disco, e restaur-lo quando necessrio.

____________________________________________________________________________________ Apostila de JSP 74

____________________________________________________________________________________

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 75

____________________________________________________________________________________

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 76

____________________________________________________________________________________ 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 77

____________________________________________________________________________________

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 78

____________________________________________________________________________________

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 79

____________________________________________________________________________________

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 80

____________________________________________________________________________________ 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 81

____________________________________________________________________________________ </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 82

____________________________________________________________________________________

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 83

____________________________________________________________________________________

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 84

____________________________________________________________________________________ } 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 85

____________________________________________________________________________________

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 86

____________________________________________________________________________________

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 principal anos composio taxaDeJuros valorFuturo Modo read/write read/write read/write read/write read-only double int int double double Tipo

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 87

____________________________________________________________________________________ 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 88

____________________________________________________________________________________ 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 89

____________________________________________________________________________________

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 90

____________________________________________________________________________________

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 91

____________________________________________________________________________________

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 92

____________________________________________________________________________________

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

____________________________________________________________________________________

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 94

____________________________________________________________________________________

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 95

____________________________________________________________________________________

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 96

____________________________________________________________________________________

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 97

____________________________________________________________________________________

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 98

____________________________________________________________________________________

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 99

____________________________________________________________________________________

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 100

____________________________________________________________________________________ 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 101

____________________________________________________________________________________ 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 102

____________________________________________________________________________________

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 103

____________________________________________________________________________________

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 104

____________________________________________________________________________________ <%@ 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 105

____________________________________________________________________________________

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 106

____________________________________________________________________________________

7.3.2

O Banco de Dados

Para este exemplo so necessrias duas tabelas: CONFERENCIAS e TRANSPORTES, com o layout especificado abaixo.
ID CIDADE AEROPORTO ASSENTOS CONFERENCIAS NUMBER(5) VARCHAR2(80) CHAR(3) NUMBER(3) PK

ID AEROPORTO DATA_HORA ASSENTOS

TRANSPORTES NUMBER(5) CHAR(3) DATE NUMBER(3)

PK e FK PK PK

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 107

____________________________________________________________________________________

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 108

____________________________________________________________________________________

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 109

____________________________________________________________________________________ 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 110

____________________________________________________________________________________ <%@ 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 111

____________________________________________________________________________________ <%@ 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 112

____________________________________________________________________________________

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 113

____________________________________________________________________________________

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 ModelView-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 114

____________________________________________________________________________________

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 115

____________________________________________________________________________________

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 116

____________________________________________________________________________________

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

firstName = request.getParameter("firstName"); lastName = request.getParameter("lastName"); mother = request.getParameter("mother"); 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 117

____________________________________________________________________________________ <%= 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 118

____________________________________________________________________________________

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 119

____________________________________________________________________________________

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 120

____________________________________________________________________________________

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

____________________________________________________________________________________

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 122

____________________________________________________________________________________

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 123

____________________________________________________________________________________

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 124

____________________________________________________________________________________

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 pagecentric (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 125

____________________________________________________________________________________

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 126

____________________________________________________________________________________

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 import import import import jsp.aluno01.exercicio22.PedidoDeCompraBean; java.io.*; javax.servlet.*; javax.servlet.http.*; 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 127

____________________________________________________________________________________ + 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 128

____________________________________________________________________________________ } 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 129

____________________________________________________________________________________

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 130

____________________________________________________________________________________

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 131

____________________________________________________________________________________

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 132

____________________________________________________________________________________

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 request inserido no objeto 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 133

____________________________________________________________________________________

O Banco de Dados Esta aplicao trabalha com uma tabela denominada Empregados que possui o seguinte lay-out: Coluna
ID PNOME UNOME DEPARTAMENTO EMAIL IMAGE

Propsito
Id nico do Empregado Primeiro Nome ltimo Nome Departamento Endereo de e-mail URL da foto do empregado

Tipo
Number(5) Varchar2(80) Varcahr2(80) Varchar2(80) Varchar2(80) 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 134

____________________________________________________________________________________ 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 135

____________________________________________________________________________________ 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 136

____________________________________________________________________________________ package jsp.aluno01.exercicio23; import import import import import javax.servlet.*; javax.servlet.http.*; java.io.*; java.sql.*; 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 137

____________________________________________________________________________________ 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 138

____________________________________________________________________________________ } 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 139

____________________________________________________________________________________ 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 140

____________________________________________________________________________________ <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 141

____________________________________________________________________________________

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 142

____________________________________________________________________________________

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 143

____________________________________________________________________________________

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 144

____________________________________________________________________________________

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 145

____________________________________________________________________________________

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 146

____________________________________________________________________________________

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 147

____________________________________________________________________________________ { %> <% } %> </p> </font> </body> </html> em <%= URLDecoder.decode(cookieVermelho.getValue()) %>.

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 request atributo do objeto implcito 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 148

____________________________________________________________________________________

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 149

____________________________________________________________________________________ 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 150

____________________________________________________________________________________ } else { }

buffer.append("invalid\n");

Para

URL, reconstruir o 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 151

____________________________________________________________________________________

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 152

____________________________________________________________________________________ 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 153

____________________________________________________________________________________ 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 154

____________________________________________________________________________________

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.

<% } catch (AddressException e) { %> <p>Endereo de e-mail invlido para a notificao de erro.</p> <% }

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>

____________________________________________________________________________________ Apostila de JSP 155

____________________________________________________________________________________ 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 156

____________________________________________________________________________________ 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 157

____________________________________________________________________________________ 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 158

____________________________________________________________________________________

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 159

____________________________________________________________________________________ <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 160

____________________________________________________________________________________

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 161

____________________________________________________________________________________

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 162

____________________________________________________________________________________ } 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 163

____________________________________________________________________________________

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 164

____________________________________________________________________________________

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 165

____________________________________________________________________________________

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 166

____________________________________________________________________________________

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 167

____________________________________________________________________________________ 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 168

____________________________________________________________________________________ <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 169

____________________________________________________________________________________

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 170

____________________________________________________________________________________ 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 171

____________________________________________________________________________________ <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 import import import java.io.*; javax.servlet.*; javax.servlet.http.*; 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 172

____________________________________________________________________________________ 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 173

____________________________________________________________________________________ <% 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 9.6.1

Tarefas Variadas 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 174

____________________________________________________________________________________ <%@ 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 175

____________________________________________________________________________________ p.waitFor(); return buf.toString();

} %> <html> <body> O nome do host : <%= run("c://winnt//system32//hostname.exe") %> </body> </html>

} catch (Exception e) { return (e.getMessage()); }

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 176

____________________________________________________________________________________

10. BIBLIOGRAFIA

Duane K. Fields e Mark A. Kolb, Web Development with Java Server Pages, Ed. Manning, 2000.

____________________________________________________________________________________ Apostila de JSP 177

Você também pode gostar