Escolar Documentos
Profissional Documentos
Cultura Documentos
Curso de JSP
Roberto Hartke Neto
Sumrio a
1 Introduo ca 1.1 O que JSP? . . . . . . . . . . . . . . . . . . . . . . e 1.1.1 Por que usar JSP se j existe PHP, ASP, etc? a 1.2 Como JSPs funcionam . . . . . . . . . . . . . . . . . 1.3 Instalando e congurando o Tomcat . . . . . . . . . . 1.3.1 Obtendo o Tomcat . . . . . . . . . . . . . . . 1.3.2 Instalando o Tomcat . . . . . . . . . . . . . . 1.3.3 Executando o Tomcat . . . . . . . . . . . . . 1.3.4 Disponibilizando a aplicao . . . . . . . . . . ca 1.3.5 Estrutura de diretrios da aplicao . . . . . . o ca 2 Release 1 2.1 Java Beans . . . . . . . . . . . . . . . . 2.1.1 O que faz de um Bean um Bean? 2.1.2 Convenes de um Bean . . . . . co 2.2 JSP Tags . . . . . . . . . . . . . . . . . 2.2.1 Aes JSP . . . . . . . . . . . . . co 2.2.2 Diretivas . . . . . . . . . . . . . . 2.2.3 Declaraoes . . . . . . . . . . . . c 2.2.4 Expresses . . . . . . . . . . . . . o 2.2.5 Scriptlets . . . . . . . . . . . . . 2.2.6 Comentrios . . . . . . . . . . . . a 2.3 Objetos impl citos . . . . . . . . . . . . . 2.4 Construindo a aplicao . . . . . . . . . ca 2.4.1 Construindo o formulrio . . . . . a 2.4.2 Criando um JavaBean . . . . . . 2.4.3 Primeiro arquivo JSP . . . . . . . 2.4.4 Formulrio para tratar erros . . . a 2.4.5 Pgina de sucesso . . . . . . . . . a 2.4.6 Disponibilizando a aplicao . . . ca 3 3 3 4 4 4 4 5 5 5 6 6 6 6 7 7 10 11 11 11 11 12 14 14 15 18 19 21 21 22 22 22 22 23 23 23 24
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . .
3 Release 2 3.1 Servlets . . . . . . . . . . . . . . . . . . . 3.1.1 O que so servlets? . . . . . . . . . a 3.2 Usando Java JDBC . . . . . . . . . . . . . 3.2.1 Acesso ao banco de dados . . . . . 3.2.2 Especicando o driver JDBC . . . . 3.2.3 Estabelecendo a conexo . . . . . . a 3.2.4 Encontrando dados em uma tabela 1
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
3.3
3.2.5 Fazendo consultas com JDBC Interface RequestDispatcher . . . . . 3.3.1 Criando tabelas . . . . . . . . 3.3.2 Escrevendo um servlet . . . . 3.3.3 Pgina de erro . . . . . . . . . a
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
24 24 28 29 30 32 32 32 32 33 34 34 34 37 37 38 40 40 40 40 42 42 45 46 46 46 47
4 Release 3 4.1 Tag Libraries . . . . . . . . . . . 4.1.1 O que uma Tag Library? e 4.1.2 O que uma Tag? . . . . e 4.1.3 Tag Handlers? . . . . . . 4.1.4 Descritor de Tag Libraries 4.2 Construindo a aplicao . . . . . ca 4.2.1 Escrevendo uma BodyTag 4.2.2 TagExtraInfo . . . . . . . 4.2.3 Descritor . . . . . . . . . . 4.2.4 Pgina JSP . . . . . . . . a
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
5 Release 4 5.1 Tags com parmetros . . . . . . . . . . . . . a 5.2 Construindo a aplicao . . . . . . . . . . . ca 5.2.1 Pgina de pesquisa . . . . . . . . . . a 5.2.2 Descritor das Tags . . . . . . . . . . 5.2.3 Modicando o arquivo TagMidia.java 5.2.4 Passando parmetros pela URL . . . a
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
6 Descritor da aplicao ca 6.1 Construindo a aplicao . . . . . . . . . . . . . . . . . . . . . ca 6.1.1 Web.xml . . . . . . . . . . . . . . . . . . . . . . . . . . 6.1.2 Pgina de erro . . . . . . . . . . . . . . . . . . . . . . . a
7 Release 6 49 7.1 Construindo a aplicao . . . . . . . . . . . . . . . . . . . . . 49 ca 8 Release 7 57 8.1 Passando objetos para outras partes da aplicao . . . . . . . 57 ca 8.2 Construindo a aplicao . . . . . . . . . . . . . . . . . . . . . 57 ca 9 Release 8 60 9.1 Carrinho de compras . . . . . . . . . . . . . . . . . . . . . . . 60 9.2 Pgina JSP . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 a 10 Release 9 Referncias Bibliogrcas e a 65 67
JSP signica Java Server Pages. Esta tecnologia usada para servir e contedo dinmico para o usurio, usando lgica e dados no lado do servidor. u a a o JSP faz parte da plataforma J2EE (Java 2 Enterprise Edition) e juntamente com os Java Servlets e Java Beans pode ser usada para desenvolver aplicaes co web ecientes, escalveis e seguras rapidamente. a
1.1.1
Existem vrias linguagens usadas para criar aplicaes web. Entre elas a co ASP, PHP, ColdFusion e Perl. Por que usar JSP ento? a JSP usa Java. Java uma das linguagens mais populares atualmente e interpretada, e e portanto o cdigo escrito em uma arquitetura pode ser portado para o qualquer outra. JSP parte do pacote J2EE e J2EE um dos modelos mais usados para contruir aplicaes de grande e co porte, e suportado por vrias gigantes da computao como IBM, e a ca Oracle, Sun, etc. Programao em rede inerente a Java ca e O suporte inerente de Java para a rea de redes faz dela uma tima a o linguagem para a Internet. JSP x ASP Uma das diferenas que pode ser fundamental para a escolha entre c estas duas tecnologias que ASP da Microsoft e s roda em ambiente e e o Windows, e tambm todo software necessrio pago. JSP, feito pela e a e Sun, roda em qualquer plataforma que tenha a mquina virtual de a Java, e tem vrios softwares gratuitos para disponibilizar a aplicao a ca (Tomcat por exemplo).
1.2
A nalidade de JSP fornecer um mtodo de desenvolvimento de servlets e e declarativo e centrado na apresentao. A especicao de JSP denida ca ca e como uma extenso da API de Servlets. Conseqentemente, no de se a u a e admirar que por trs dos panos, servlets e pginas JSP tem muito em comum. a a Tipicamente, pginas JSP esto sujeitas a uma fase de traduo e outra a a ca de processamento da requisio. A fase de traduo feita apenas uma vez, ca ca e a menos que a pgina JSP mude, e no caso traduzida novamente. Supondo a e que no houve nenhum erro de sintaxe na pgina, o resultado uma pgina a a e a JSP que implementa a interface Servlet. A fase de traduo tipicamente realizada pela engine JSP, quando ela ca e recebe uma requisio para a pgina JSP pela primeira vez. A especicao ca a ca JSP 1.1 tambm permite que pginas JSP sejam pr-compiladas em arquivos e a e class. Isto pode ser util para evitar a demora para carregar a pgina JSP na a primeira vez que ela acessada. Vrias informaes da fase de traduo, como e a co ca a localizao de onde armazenado o pgina JSP j compilada (portanto o ca e a a servlet correspondente a esta pgina) so dependentes da implementao da a a ca engine JSP. A classe que implementa uma pgina JSP estende a classe HttpJspBase, a que implementa a interface Servlet. O mtodo de servio desta classe, jspService(), e c essencialmente encapsula o contedo da pgina JSP. Ainda que o mtodo u a e jspService() no pode ser sobrescrito, o desenvolvedor pode descrever evena tos de inicializao e destruio fornecendo implementaes dos mtodos jsca ca co e pInit() e jspDestroy dentro da pgina JSP. a Uma vez que a classe carregada no recipiente, o mtodo jspService() e e e responsvel por responder `s requisies do cliente. a a co
1.3
Primeiro voc precisa ter a mquina virtual java (JDK 1.3 ou mais atual) e a instalada na sua mquina. Esta pode ser obtida gratuitamente no endereo a c http://java.sun.com.
1.3.1
Obtendo o Tomcat
Tomcat um servidor de pginas JSP e Servlets. Desenvolvido pela e a fundao Apache, no projeto Jakarta, seu cdigo aberto e o programa ca o e e gratuito. Pode ser obtido em http://jakarta.apache.org.
1.3.2
Instalando o Tomcat
Instale ou descompacte o arquivo que voc baixou em algum diretrio. e o Depois voc ter que criar duas variveis de ambiente, CATALINA HOME e a a e JAVA HOME, onde CATALINA HOME o diretrio base do Tomcat e e o JAVA HOME o diretrio base da plataforma Java. e o Por exemplo, se o Tomcat foi instalado em c:\tomcat e a JVM (Java Virtual Machine) est em c:\java, estas variveis devem ser: a a
CATALINA HOME = c:\tomcat JAVA HOME = c:\java Nos Windows 95/98 adicione os comandos SET CATALINA HOME = c:\tomcat e SET JAVA HOME = c:\java no arquivo c:\autoexec.bat. No Windows 2000 v em Painel de Controle, Sistema, Avanado, a c Variveis de Ambiente e entre com as informaes. a co No caso do UNIX, use o comando export (ou set, dependendo da sua distribuio). ca
1.3.3
Executando o Tomcat
V no diretrio CATALINA HOME\bin (onde CATALINA HOME o a o e diretrio base do Tomcat), e execute o arquivo startup.bat para iniciar o o Tomcat e shutdown.bat para encerr-lo. a No caso dos UNIX, v no mesmo diretrio e digite ./tomcat4 start para a o iniciar e ./tomcat4 stop para naliz-lo. a Para visualizar as pginas acesse http://localhost:8080/ (localhost ou o ena dereo da mquina). c a
1.3.4
Disponibilizando a aplicao ca
Crie um diretrio dentro do diretrio CATALINA HOME/webapps, ou o o coloque o arquivo da sua aplicao (.WAR) neste diretrio. Para ver a ca o aplicao acesse a URL http://localhost:8080/(nome do diretrio ou arquivo ca o da aplicao)/ no navegador. ca Exemplo: Para acessar a aplicao localizada em CATALINA HOME/webapps/app, ca acesse http://localhost:8080/app.
1.3.5
As aplicaes JSP seguem um padro. Devem ter um diretrio WEBco a o INF (letras maisculas). Dentro desse, crie outro diretrio chamado classes u o (letras minsculas). Neste voc deve colocar todos as classes que voc usa na u e e aplicao (arquivos .class), inclusive servlets e beans. Pacotes (arquivos .jar) ca podem ser colocados no diretrio WEB-INF/lib/. Os arquivos JSP podem ser o postos no diretrio raiz ou em qualquer outro diretrio, menos no WEB-INF o o e sub-diretrios! o
Java Beans
O que faz de um Bean um Bean?
Um Bean simplesmente uma classe de Java que segue um conjunto e de convenes simples de design e nomeao delineado pela especicao de co ca ca JavaBeans. Os Beans no precisam estender uma determinada classe ou a implementar uma determinada interface.
2.1.2
Convenes de um Bean co
As convenes de JavaBean so o que nos permitem desenvolver Beans, co a porque elas permitem que o container Bean analise um arquivo de classe Java e interprete seus mtodos como propriedades, designando a classe como e um Bean de Java. Beans so simplesmente objetos Java. Mas como seguem um padro a a ca mais fcil trabalhar com eles. a Uma boa prtica colocar Bean no nome de uma classe que um Bean, a e e para que seja melhor identicado. Assim uma classe que representa uma pessoa caria PessoaBean ou BeanPessoa. O construtor Bean A primeira regra da criao do Bean JSP que voc tem que implemenca e e tar um construtor que no tenha argumentos. Este construtor usado por a e exemplo para instanciar um Bean atravs da tag <jsp:useBean> visto mais e adiante. Se a classe no especicar um construtor sem argumentos, ento a a um construtor sem argumentos e sem cdigo ser assumido. o a public Bean() { } Propriedades de um Bean Coloque os atributos como privados, e faa mtodos get e set para acessc e a los, e este mtodos ento sero pblicos. e a a u
private String nome; public String getNome() { return nome;} public void setNome(String novo) { nome = novo; }
Uma boa conveno de nome de propriedades, comear com letra minscula ca e c u e colocar em maiscula a primeira letra de cada palavra subseqente. Assim u u como nos mtodos de ajuste, a palavra set ou get comea em minscula e a e c u primeira letra da propriedade ser maiscula. a u
private String corCarro; public String getCorCarro();"
Propriedades indexadas Caso a propriedade seja um conjunto de valores (array), uma boa prtica e a criar mtodos para acessar o conjunto inteiro de valores e para acessar uma e posio espec ca ca.
private String[] telefone; public String[] getTelefone() { return telefone; } public String getTelefone(int index) { return telefone[index]; }
Propriedades booleanas Para propriedades booleanas, voc pode substituir a palavra get por is. e
private boolean enabled; public boolean isEnabled() { return enabled; }
2.2
JSP Tags
Numa olhada rpida, JSP parece com HTML (ou XML), ambos contm a e texto encapsulado entre tags, que so denidas entre os s a mbolos < e >. Mas enquanto as tags HTML so processadas pelo navegador do cliente para a mostrar a pgina, as tags de JSP so usadas pelo servidor web para gerar a a contedo dinmico. u a A seguir esto os tipos de tags vlidos em JSP: a a
2.2.1
Aes JSP co
Executam diversas funes e estendem a capacidade de JSP. Usam sintaxe co parecida com XML, e so usadas (entre outras coisas) para manipular Java a Beans. Existem seis tipos de aes: co 7
<jsp:forward> Este elemento transfere o objeto request contendo informao da reca quisio do cliente de uma pgina JSP para outro arquivo. Este pode ser um ca a arquivo HTML, outro arquivo JSP ou um servlet, desde que faa parte da c mesma aplicao. ca Sintaxe:
<jsp:forward page="(URL relativa | <%= express~o %>)" /> a ou <jsp:forward page="(URL relativa | <%= express~o %>)" > a <jsp:param name="nome do par^metro" a value="(valor do par^metro| <%= express~o %>)" /> a a </jsp:forward>
<jsp:getProperty> Este elemento captura o valor da propriedade de um bean usando o mtodo get da propriedade e mostra o valor na pgina JSP. E necessrio criar e a a ou localizar o bean com <jsp:useBean> antes de usar <jsp:getProperty>. Sintaxe:
<jsp:getProperty name="nome do objeto (bean)" property="nome da propriedade" />
<jsp:include> Este elemento permite incluir um arquivo esttico ou dinmico numa a a pgina JSP. Os resultados de incluir um ou outro so diferentes. Se o arquivo a a esttico, seu contedo inclu quando a pgina compilada num servlet. e a u e do a e Se for dinmico, funciona como uma requisio para o arquivo e manda o a ca resultado de volta para a pgina. Quando estiver terminada a ao do include a ca continua-se processando o restante da pgina. a Sintaxe:
<jsp:include page="{URL relativa | <%= express~o %>}" a flush="true" /> ou <jsp:include page="{URL relativa | <%= express~o %>}" a flush="true" > <jsp:param name="nome do par^metro" a value="{nome do par^metro | <%= express~o %>}" /> a a </jsp:include>
<jsp:plugin> Executa ou mostra um objeto (tipicamente um applet ou um bean) no navegador do cliente, usando o plug-in Java que est embutido no navegador a ou instalado na mquina. No ser explicado o funcionamento deste elemento a a a no curso. <jsp:useBean> Localiza ou instancia um componente. Primeiro tenta localizar uma instncia do bean. Se no existe, instancia ele a partir da classe especia a cada. Para localizar ou instanciar o bean, so seguidos os seguintes passos, a nesta ordem: 1. Tenta localizar o bean com o escopo e o nome especicados. 2. Dene uma varivel de referncia ao objeto com o nome especicado. a e 3. Se o bean for encontrado, armazena uma referncia ao objeto na varivel. e a Se foi especicado o tipo, converte o bean para este tipo. 4. Se no encontrar, instancia-o pela classe especicada, armazenando a uma referncia ao objeto na nova varivel. e a 5. Se o bean tiver sido instanciado (ao invs de localizado), e ele tem tags e de corpo (entre <jsp:useBean> e </jsp:useBean>), executa estas tags. Sintaxe:
<jsp:useBean id="nome da instancia" scope="page|request|session|application" { class="package.class" | type="package.class" | class="package.class" type="package.class" | beanName="{package.class | <%= express~o %>}" a type="package.class" } { /> | > outros elementos (tags de corpo) </jsp:useBean> }
<jsp:setProperty> O elemento <jsp:setProperty> ajusta o valor de uma ou mais proprie dades em um bean, usando os mtodos de ajuste (set) dele. E necessrio e a declarar o bean com <jsp:useBean> antes de ajustar uma propriedade. Estas duas aes trabalham juntas, portanto o nome de instncia usada nas co a duas deve ser igual. Sintaxe:
<jsp:setProperty name="nome de inst^ncia do bean" a { property="*" | property="nome da propriedade" [ param="nome do par^metro" ] | a property="nome da propriedade" value="{string | <%= express~o %>}" a } />
2.2.2
Diretivas
So instrues processadas quando a pgina JSP compilada em um a co a e servlet. Diretivas so usadas para ajustar instrues no n a co vel da pgina, a inserir dados de arquivos externos, e especicar tag libraries. Diretivas so a denidas entre <%@ e %>. Existem trs tipos de diretivas: e Include Inclui um arquivo esttico em uma pgina JSP. a a Sintaxe:
<%@ include file="relativeURL" %>
Page Dene atributos que so aplicados a todo o arquivo JSP, e a todos os seus a arquivos inclu dos estaticamente. Sintaxe:
<%@ page [ language="java" ] [ extends="package.class" ] [ import="{package.class | package.*}, ..." ] [ session="true|false" ] [ buffer="none|8kb|sizekb" ] [ autoFlush="true|false" ] [ isThreadSafe="true|false" ] [ info="text" ] [ errorPage="URL relativa" ] [ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] [ isErrorPage="true|false" ] %>
Taglib Dene uma tag library e seu prexo a ser usado na pgina JSP. a Sintaxe:
10
2.2.3
Declaraes co
So similares com as declaraes de variveis em Java, e denem variveis a co a a para uso subseqente em expresses ou scriptlets. So denidas entre <%! e u o a %>. Sintaxe:
<%! int x = 0; declara~o; ca ... %>
2.2.4
Expresses o
Contm um comando vlido da linguagem Java que avaliado, convertido e a e para um String, e inserido onde a expresso aparece no arquivo JSP. No a a e usado ponte e v rgula para terminar a expresso, e s pode haver uma entre a o <%= e %>. Sintaxe:
<%= pessoa.getNome() %>
2.2.5
Scriptlets
So blocos de cdigo Java embutidos numa pgina JSP. O cdigo do a o a o denido scriptlet inserido literalmente no servlet gerado pela pgina. E e a entre <% e %>. Sintaxe:
<% int x = 0; x = 4 * 9; String str = "PET"; ... %>
2.2.6
Comentrios a
So similares aos comentrios HTML, mas so tirados da pgina quando a a a a o arquivo JSP compilado em servlet. Isto signica que os comentrios e a JSP no aparecem no cdigo fonte da pgina visualizada pelo navegador a o a do usurio. Comentrios em HTML so feitos entre <! e >, enquanto a a a comentrios em JSP so entre <% e %>. a a
11
2.3
Como uma caracter stica conveniente, o container JSP deixa dispon vel objetos impl citos que podem ser usados nos scriptlets e expresses, sem que o o autor tenha que cri-los. Estes objetos instanciam classes denidas na API a (application program interface) de Servlets. So nove objetos: a Tabela 2.1: Objetos Impl citos Objeto page Classe ou Interface javax.servlet.jsp.HttpJspPage Descrio ca Instncia de servlet da a pgina a Dados de congurao ca do Servlet Dados de solicitao ca incluindo parmetros a
cong
javax.servlet.ServletConfig
request
javax.servlet.http.HttpServletRequest
response out
javax.servlet.http.HttpServletResponse Dados da resposta javax.servlet.jsp.JspWriter Fluxo de sa para o da contedo da pgina u a Dados de sesso esa pec cos de usurio a Dados compartilhados por todas as pginas a da aplicao ca Dados de contexto para execuo da ca pgina a Erros no pegos ou a exceo ca
session
javax.servlet.http.HttpSession
application
javax.servlet.ServletContext
pageContext
javax.servlet.jsp.PageContext
exception
javax.lang.Throwable
Objeto page O objeto page representa a prpria pgina JSP ou, mais especicamente, o a uma instncia da classe de servlet na qual a pgina foi traduzida. a a Objeto cong O objeto cong armazena dados de congurao de servlet na forma ca de parmetros de inicializao para o servlet no qual uma pgina JSP a ca a e 12
compilada. Pelo fato das pginas JSP raramente serem escritas para interagir a com parmetros de inicializao, este objeto impl a ca cito raramente usado na e prtica. a Objeto request O objeto request representa a solicitao que acionou o processamento da ca pgina atual. Para solicitaes de HTTP, este objeto fornece acesso a todas a co as informaes associadas com uma solicitao, incluindo sua fonte, a URL co ca solicitada e quaisquer cabealhos, cookies ou parmetros associados com a c a solicitao. Dentre os usos mais comuns para o objeto request, encontra-se ca a procura por valores de parmetros e cookies. a Objeto response O objeto response representa a resposta que ser enviada de volta para o a usurio como resultado do processamento da pgina JSP. a a Objeto out Este objeto impl cito representa o uxo de sa para a pgina, cujo da a contedo ser enviado para o navegador como o corpo de sua resposta. u a Objeto session Este objeto impl cito de JSP representa a sesso atual de um usurio a a individual. Todas as solicitaes feitas por um usurio, que so parte de co a a uma unica srie de interaes com o servidor da web, so consideradas parte e co a de uma sesso. Desde que novas solicitaes por aqueles usurios continuem a co a a ser recebidas pelo servidor, a sesso persiste. Se, no entanto, um certo a per odo de tempo passar sem que qualquer nova solicitao do usurio seja ca a recebida, a sesso expira. a O objeto session, ento armazena informaes a respeito da sesso. Os a co a dados espec cos de aplicao so tipicamente adicionados ` sesso atravs de ca a a a e atributos, usando os mtodos da interface javax.servlet.http.HttpSession. e O objeto session no est dispon para todas as pginas JSP, seu uso a a vel a restrito `s pginas que participam do gerenciamento da sesso. Isto e a a a e indicado atravs do atributo session da diretiva page. O padro que todas e a e as pginas participem do gerenciamento de sesso. Se o atributo estiver a a denido para false, o objeto no estar dispon e seu uso resultar em um a a vel a erro de compilao quando o recipiente JSP tentar traduzir a pgina para ca a um servlet. Objeto application Este objeto impl cito representa a aplicao ` qual a pgina JSP pertence. ca a a Ela uma instncia da interface javax.servlet.ServletContext. As pginas JSP e a a esto agrupadas em aplicaes de acordo com suas URLs. a co Este objeto permite acessar informaes do container, interagir com o co servidor e fornece suporte para logs.
13
Objeto pageContext O objeto pageContext uma instncia da classe javax.servlet.jsp.PageContext, e a e fornece acesso programtico a todos os outros objetos impl a citos. Para os objetos impl citos que aceitam atributos, o objeto pageContext tambm fore nece mtodos para acessar aqueles atributos. Alm disso, o objeto pageCone e text implementa mtodos para transferir controle da pgina atual para uma e a outra pgina, temporariamente, para gerar output a ser inclu no output a do da pgina atual, ou permanentemente para transferir todo o controle. a Objeto exception O objeto exception uma instncia da classe java.lang.Throwable. O e a objeto exception no est automaticamente dispon em todas as pginas a a vel a JSP. Ao invs disso, este objeto est dispon apenas nas pginas que tee a vel a nham sido designadas como pginas de erro, usando o atributo isErrorPage a da diretiva page.
2.4
Construindo a aplicao ca
Iniciando a construo da aplicao, vamos criar um formulrio de cadasca ca a tro para a m dia, um bean que representa a m dia, e um arquivo JSP que processa o formulrio. Criaremos tambm um formulrio idntico ao pria e a e meiro mas que mostra poss veis erros ocorridos no cadastro. E por ultimo, uma pgina HTML simples que indica se o cadastro foi realizado ou no. a a
2.4.1
Construindo o formulrio a
Aqui iremos criar o formulrio para o cadastro de tas. Ele puramente a e feito em HTML, no tem cdigo jsp. a o
<html> <head> <style> p, td { font-family:Tahoma,Sans-Serif; font-size:11pt; padding-left:15; } </style> <title>Cadastro de Mídia</title> </head> <body bgcolor="#FFFFFF" text="#000000">
Especicamos o arquivo que processar o formulrio no atributo action a a da tag form: <form action=ProcessarMidia.jsp... >
<form action="ProcessarMidia.jsp" method=post name="midias"> <center> <table cellpadding=4 cellspacing=2 border=0> <th bgcolor="#CCDDEE" colspan=2> <font size=5>Cadastro de Mídias</font>
14
<br> <font size=1><sup>*</sup> Campos necessários</font> </th> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Título<sup>*</sup></b> <br>
O atributo name dos campos do formulrio devem preferencialmente ter o a mesmo nome que seu atributo correspondente no bean usado para armazenar as informaoes do formulrio. c a
<input type="text" name="titulo" value="" size=30 maxlength=40></td> <td valign=top> <b>Ano<sup>*</sup></b> <br> <input type="text" name="ano" value="" size=8 maxlength=8> </td> </tr> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Descri~o ca <br> <TEXTAREA NAME="descricao" ROWS="6" COLS="30"> </textarea> </td> <td valign=top> <b>Tipo<sup>*</sup></b></b> <br> <input type="radio" name="tipo" value="vhs" checked> VHS <br> <input type="radio" name="tipo" value="dvd"> DVD </td> </tr> <tr bgcolor="#F7F7F7"> <td align=center colspan=2> <input type="submit" value="Confirma"> <input type="reset" value="Limpar"> </td> </tr>
2.4.2
Criando um JavaBean
Vamos criar nosso bean que ter as informaes da M a co dia. Ele deve ter todos os atributos do formulrio que constru a mos, e todos os mtodos set e e get para acess-los. Alm disso, teremos outro atributo, para controle a e 15
de eventuais erros no processamento do formulrio (dados necessrios no a a a digitados por exemplo). Usaremos uma tabela de hash (java.util.Hashtable) que ter como chave o nome do atributo e como valor a mensagem de erro a que desejarmos. Chamaremos a Hashtable de erros, e ela tambm ter seus e a mtodos set e get. e Por m, criaremos um mtodo para vericar se todos os dados necessrios e a foram digitados, validando ou no o formulrio. a a Abaixo est o cdigo fonte do BeanMidia, veja os comentrios para maia o a ores detalhes.
package beans; import java.util.Hashtable; /** * Implementar a classe Serializable requisito para ser um e * Enterprise Bean. Um objeto de uma classe que implementa * esta interface pode ser escrito em disco ou enviado pela rede. * Na aplica~o do curso n~o far diferena. ca a a c */ public class BeanMidia implements java.io.Serializable {
/** * Nomes dos atributos preferencialmente iguais aos usados * no formulrio a */ private String titulo; private String ano; private String tipo; private String descricao; /* Este atributo serve para o controle de erros no formulrio */ a private Hashtable erros; public BeanMidia() { /* Iniciamos os atributos com o String nulo */ titulo = ""; ano = ""; descricao = ""; tipo = ""; erros = new Hashtable(); } /** * Mtodos para acessar os atributos. e * getNome() para ver ser valor, e setNome() para ajustar seu valor */ public String getTitulo() { return titulo; } public String getAno() { return ano; } public String getTipo() { return tipo;
16
} public String getDescricao() { return descricao; } public void setTitulo(String valor) { titulo = valor; } public void setAno(String valor) { ano = valor; } public void setTipo(String valor) { tipo = valor; } public void setDescricao(String valor) { descricao = valor; }
/** * Verifica se todos os dados exigidos foram digitados, * alm de outras condi~es desejadas. e co */ public boolean ehValido() { boolean volta = true; if ((titulo == null) || titulo.equals("")) { erros.put("titulo", "Por favor, digite um ttulo."); volta = false; } if ((ano == null) || ano.equals("") ) { erros.put("ano", "Por favor, digite o ano da mdia ."); volta = false; } if ((tipo == null) || tipo.equals("") ) { erros.put("tipo", "Por favor, selecione o tipo da mdia ."); volta = false; } return volta; } /** *Usado para ver as mensagens de erro armazenados na tabela de Hash */ public String getErros (String s) { String msg = (String) erros.get(s); return (msg == null) ? "" : msg; }
17
/** * Usado para colocar algum erro na tabela */ public void setErros (String chave, String msg) { erros.put(chave,msg); } }
2.4.3
Agora vamos construir o arquivo que processa o formulrio, este, at que a e enm, feito em JSP. O atributo import da diretiva page estende o conjunto de classes Java que podem ser referenciadas um uma pgina JSP sem ter que explicitamente a especicar os nomes de pacote de classes.
<%@ page import="beans.BeanMidia" %>
A tag <jsp:useBean> diz ` pgina que voc quer disponibilizar um Bean a a e para a pgina. a O atributo id especica um nome para o Bean, que ser o nome usado a para referenciar o Bean ao longo da pgina e de sua vida na aplicao. a ca O atributo class especica o nome de classe do prprio Bean. o O atributo scope controla o escopo do Bean, ou seja, para quem e quanto tempo ele permanecer dispon a vel. Os valores podem ser page, request, session e application.
<jsp:useBean id="midia" class="beans.BeanMidia" scope="request">
Mostramos abaixo trs maneiras de ajustar os atributos de um bean. A e primeira diz-se o nome do atributo do bean no parmetro property e ento a a especica-se o valor no parmetro value. a Nas outras duas o atributo do bean tem o mesmo nome do valor colocado em property. Pode-se tambm ajustar os valores dos atributos usando os mtodos set e e do bean, usando o ambiente dos scriptlets.
<jsp:setProperty name="midia" property="titulo" value=<%=request.getParameter("titulo")%> /> <jsp:setProperty name="midia" property="ano" /> <jsp:setProperty name="midia" property="descricao" /> <% midia.setTipo(request.getParameter("tipo")); %> </jsp:useBean>
18
Verica-se se todos os atributos necessrios foram digitados e ento redirecionaa a se para a pgina de sucesso ou para o formulrio que trata erros. a a
<% if (midia.ehValido()) { %> <jsp:forward page="/sucesso.jsp"/> <% } else { %> <jsp:forward page="RetryMidia.jsp" /> <% } %>
2.4.4
Este arquivo visualmente idntico ao formulrio anterior, mas ele um e e a e arquivo JSP que mostra poss veis erros ocorridos durante o cadastro. Declaramos o bean usado no arquivo nas primeiras linhas. E necessrio a que ele tenha o mesmo nome dos arquivos antecessores (no caso, ProcessarMidia.jsp).
<%@ page import="beans.BeanMidia" %> <jsp:useBean id="midia" class="beans.BeanMidia" scope="request"/> <html> <head> <style> p, td { font-family:Tahoma,Sans-Serif; font-size:11pt; padding-left:15; } </style> <title>Cadastro de Mídia</title> </head> <body bgcolor="#FFFFFF" text="#000000"> <form action="ProcessarMidia.jsp" method=post name="midias"> <center> <table cellpadding=4 cellspacing=2 border=0> <th bgcolor="#CCDDEE" colspan=2> <font size=5>Cadastro de Mídias</font> <br> <font size=1><sup>*</sup> Campos necessários</font> </th> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Título<sup>*</sup></b> <br>
Colocamos em value o que tem no atributo titulo do BeanMidia, para que o formulrio que igual ao que foi digitado anteriormente. Isto poupa a trabalho ao usurio que no precisa digitar tudo novamente. a a
19
Se houve algum erro na digitao do t ca tulo, o comando midia.getErros(titulo) retornar o String de erro que colocamos na tabela de hash associado a chave a titulo, caso contrrio no retornar nada e no aparecer nada na pgina. a a a a a a
<font color=#FF0000><%=midia.getErros("titulo")%></font> </td> <td valign=top> <b>Ano<sup>*</sup></b> <br> <input type="text" name="ano" value=<%= midia.getAno() %> size=8 maxlength=8><br> <font color=#FF0000><%=midia.getErros("ano")%></font> </td> </tr> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Descri~o ca <br> <TEXTAREA NAME="descricao" ROWS="6" COLS="30"> <%= midia.getDescricao() %> </textarea><br> <font color=#FF0000><%=midia.getErros("descricao")%></font> </td> <td valign=top> <b>Tipo<sup>*</sup></b></b> <br>
O comando midia.getTipo().equals(String) verica se o valor do atributo tipo igual ao String. Se for, ele imprime checked no cdigo fonte da pgina, e o a fazendo com que o checkbox que marcado. Isto serve, novamente, para deixar o formulrio como o usurio digitou anteriormente. a a
<input type="radio" name="tipo" value="VHS" <% if (midia.getTipo() != null && midia.getTipo().equals("VHS")) out.print("checked"); %> > VHS <br> <input type="radio" name="tipo" value="DVD" <% if (midia.getTipo() != null && midia.getTipo().equals("DVD")) out.print("checked"); %> > DVD <br> <font color=#FF0000><%=midia.getErros("tipo")%></font> </td> </tr> <tr bgcolor="#F7F7F7"> <td align=center colspan=2> <input type="submit" value="Confirma">
20
2.4.5
Pgina de sucesso a
Vamos fazer uma pgina que nos indica se a operao foi realizada com a ca sucesso. Sempre que houve xito, redirecionaremos a aplicao para esta e ca pgina. a
<html> <head> <title>Sucesso</title> <style> p, td { font-family:Tahoma,Sans-Serif; font-size:11pt; padding-left:15; } </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table align="center" border="0" cellspacing="2" cellpadding="2"> <tr> <td bgcolor="#CCDDEE" align=center> <h3>Sucesso</h3> </td> </tr> <tr> <td bgcolor="#F7F7F7" align=center> Operação realizada com sucesso. </td> </tr> <td> </table> </body> </html>
2.4.6
Disponibilizando a aplicao ca
Crie um diretrio chamado locadora no diretrio webapps do Tomcat. o o Dentro do diretrio locadora, crie um diretrio cadastro e coloque os arquivos o o ProcessarMidia.jsp, CadastroMidia.html e RetryMidia.jsp. No diretrio raiz da aplicao (../locadora) coloque o arquivo sucesso.jsp, o ca e no diretrio WEB-INF/classes/beans coloque os arquivos BeanMidia.java o e BeanMidia.class Agora, inicie o Tomcat, acesse no navegador a URL http://localhost:8080/locadora e teste a aplicao. ca 21
Servlets
O que so servlets? a
Servlets so programas simples feitos em Java os quais rodam em um a Servlet Container. Um Recipiente (Container) Servlet como um servidor e Web que trata requisies do usurio e gera respostas. Recipiente Servlet co a diferente de Servidor Web porque ele feito somente para Servlets e no e e a para outros arquivos (como .html etc). O Recipiente Servlet responsvel e a por manter o ciclo de vida do Servlet. Pode ser usado sozinho (standalone) ou conjugado com um servidor Web. Exemplo de Recipiente Servlet o e Tomcat, e de servidor Web o Apache. Servlets so na verdade simples classes Java as quais necessitam implea mentar a interface javax.servlet.Servlet. Esta interface contm cinco mtodos e e que precisam ser implementados. Na maioria das vezes voc no precisa ime a plementar esta interface. Por qu? Porque o pacote javax.servlet j prov e a e duas classes que implementam esta interface i.e. GenericServlet e HttpServlet. Ento tudo que voc precisa fazer estender uma dessas classes e soa e e brescrever o mtodo que voc precisa para seu Servlet. GenericServlet uma e e e classe muito simples que somente implementa a interface javax.servlet.Servlet e fornece apenas funcionalidades bsicas. Enquanto HttpServlet uma classe a e mais util que fornece mtodos para trabalhar com o protocolo HTTP. As e sim se seu servlet usa o protocolo HTTP (o que ocorrer na maioria dos a casos) ento ele deveria estender a classe javax.servlet.http.HttpServlet para a construir um servlet e isto o que faremos na nossa aplicao. e ca Servlets uma vez iniciados so mantidos na memria. Ento toda rea o a quisio que chega, vai para o Servlet na memria e este gera uma resposta. ca o Esta caracter stica de manter na memria faz com que usar Java Servlets o seja um mtodo extremamente rpido e eciente para construir aplicaes e a co Web.
3.2
JDBC (Java DataBase Connectivity) a API Java para comunicao com e ca bancos de dados. JDBC especica a interface necessria para conectar a um a
22
banco de dados, executar comandos SQL e queries, e interpretar resultados. Esta interface independente do banco de dados e da plataforma. e As classes JDBC esto no pacote java.sql, que precisa ser importado para a a classe Java que faz uso de alguma classe desta API.
3.2.1
A API JDBC no pode comunicar-se diretamente com o banco de dados. a O acesso fornecido por um driver JDBC, que uma classe espec e e ca para o banco de dados e implementa a interface denida pela API. Este driver e fornecido pelo vendedor do banco de dados ou por outro provedor de servio. c
3.2.2
No seu programa, voc tem que especicar o driver JDBC que vai usar. e Faz-se isso com uma simples, talvez estranha, operao: ca Class.forName(JDBC-driver-class-name) O mtodo Class.forName() faz com que a JVM carregue o driver na e memria. Voc pode pensar que tem que instanciar a classe do driver e usar a o e referncia a ele para acessar o banco de dados, mas JDBC no funciona desta e a maneira. Quando o driver carregado na memria da JVM, ele se registra e o com a classe java.sql.DriverManager. Ento voc usa mtodos estticos da a e e a classe DriverManager para obter referncia ao objeto Connection, que ento e a fornecer acesso ao banco de dados. a
3.2.3
Estabelecendo a conexo a
JDBC segue o paradigma de usar uma URL para conectar a um recurso. O exato formato da URL depende do driver usado. Mas normalmente a URL segue um formato parecido com este: jdbc:driver-id://host/database ou jdbc:driver-id:database-id Exemplo de como conectar a um banco de dados MySQL (usado no curso):
Connection connection; try { Class.forName("org.gjt.mm.mysql.Driver"); connection = DriverManager.getConnection( "jdbc:mysql://servidor/database", user , password ); } catch (ClassNotFoundException ex) { System.out.println("N~o foi possvel encontrar a a classe do Driver do MySQL"); } catch (SQLException ex) { System.out.println("N~o foi possvel conectar a ao servidor"); } finally { try { if (connection != null) connection.close(); } catch (SQLException e) { } }
23
3.2.4
Antes de poder fazer consultas ao banco de dados com JDBC, voc precisa e criar um objeto Statement. Um objeto Statement pode ser reutilizado atravs e de mltiplas requisies SQL. E criado pelo objeto Connection e portanto u co e dependente do driver que voc est usando para conectar ao banco de dados. e a muito simples, como voc pode ver: E e
Statement statement = connection.createStatement();
3.2.5
Fazer uma consulta com JDBC fcil uma vez que voc tenha o objeto e a e Statement: voc simplesmente passa a consulta como parmetro do mtodo e a e executeQuery(). A tabela de resultados retornada pelo mtodo como uma e e instncia da classe ResultSet da API de JDBC. Abaixo est um exemplo de a a consulta:
String query = SELECT * FROM TABELA; ResultSet resultset = statement.executeQuery(query);
Estes mtodos lanam excees, portanto no seu programa deve estar e c co dentro de um bloco try/catch. O objeto ResultSet revela o contedo da tabela uma linha por vez e foru nece mtodos para acessar dados de cada coluna da tabela da linha corrente, e indicada por um cursor interno. Quando o ResultSet criado, o cursor de e linha no est na primeira linha, mas sim antes dela. Chamando o mtodo a a e next(), o ResultSet avana o cursor em uma linha, retornando valor verdade c se a chamada foi bem sucedida. Por exemplo, para passar por todas linhas do ResultSet far amos o seguinte:
while (resultset.next()) { System.out.println ("Mais uma linha!"); }
Quando o cursor est posicionado em uma linha que voc gostaria de a e examinar, voc pode chamar vrios mtodos suportados pelo objeto ResultSet e a e para restaurar dados das colunas e obter informaes sobre os resultados. co
3.3
Interface RequestDispatcher
Esta interface est presente no pacote javax.servlet e contm dois mtodos: a e e forward(ServletRequest request, ServletResponse response) transfere uma requisio para outro recurso no mesmo servidor. Este ca recurso pode ser um servlet, uma pgina JSP ou uma simples pgina a a HTML.
24
include(ServletRequest request, ServletResponse response) atua no lado do servidor, inclui a resposta do recurso dado (Servlet, pgina JSP ou HTML) dentro da resposta de quem chamou o recurso. a Para obter uma referncia a interface RequestDispatcher temos duas fore mas: ServletContext.getRequestDispatcher(String resource) ServletRequest.getRequestDispatcher(String resource) Se o servlet subclasse de HttpServletRequest, simplesmente chama-se o e mtodo getRequestDispatcher(String resource) para pegar uma referncia ao e e objeto RequestDispatcher.
RequestDispatcher rd; rd = request.getRequestDispatcher("caminho do recurso"); rd.forward(request, response);
25
private Connection connection; private Statement statement; public Conexao (String servidor,String database,String user, String password) throws SQLException { try { Class.forName("org.gjt.mm.mysql.Driver"); connection = DriverManager.getConnection( "jdbc:mysql://"+servidor+"/"+database,user,password); } catch (ClassNotFoundException ex) { System.out.println("N~o foi possvel encontrar a classe do "+ a "Driver do MySQL"); } catch (SQLException ex) { System.out.println("N~o foi possvel conectar ao servidor"); a throw ex; } try { statement = connection.createStatement(); } catch (SQLException ex) { System.out.println("N~o foi possvel criar a statement"); a throw ex; } } public Conexao() { try { Class.forName("org.gjt.mm.mysql.Driver"); connection = DriverManager.getConnection("jdbc:mysql://"+ "/locadora", "", ""); } catch (ClassNotFoundException ex) { System.out.println("N~o foi possvel encontrar a classe "+ a "do Driver do MySQL"); } catch (SQLException ex) { System.out.println("N~o foi possvel conectar ao servidor"); a
} try { statement = connection.createStatement(); } catch (SQLException ex) { System.out.println("N~o foi possvel criar a statement"); a
} }
/** * Executa um update na base de dados * @param update String SQL a ser executado * @throws SQLException se n~o for possvel executar a * o update (Erro de SQL).
26
*/ public synchronized void executeUpdate(String update) throws SQLException { try { statement.executeUpdate(update); } catch (SQLException ex) { System.out.println("N~o foi possvel executar o update"); a throw ex; } } /** * Executa uma consulta na base de dados * @param query String SQL a ser executado * @return Um objeto do tipo ResultSet contendo o * resultado da query * @throws SQLException se n~o for possvel executar a query a * (Erro de SQL). */ public synchronized ResultSet executeQuery(String query) throws SQLException { try { return statement.executeQuery(query); } catch (SQLException ex) { System.out.println("N~o foi possvel executar a query"); a throw ex; } } /** * Fecha a conexao com a base de dados. */ public void fecharConexao() { try { statement.close(); } catch (SQLException ex) { ex.printStackTrace(); } }
/** * Retorna o maior nmero de um campo da tabela u * for um inteiro. Assim, n~o teremos nenhum ID a */ public int retornaIDMax(String tabela) { try { String sql="SELECT max(ID) as contador ResultSet rs = this.executeQuery(sql); rs.next(); return rs.getInt("contador")+1; } catch (SQLException e) { System.out.println("Erro na sele~o do ca e.printStackTrace(); return 0;
FROM "+tabela;
ID Mximo"); a
27
} }
3.3.1
Criando tabelas
Vamos escrever uma classe que quando executada, conecta a um banco de dados e cria a tabela Midias, que vai ser usada no curso. Basta conectar no banco de dados, criando uma instncia da classe Coa nexao, e ento executar um comando SQL usando o mtodo executeUpa e date(String).
package conexao; import java.sql.*; public class CriaTabelas { public static void main(String[] args) { Conexao con = new Conexao(); ResultSet rs = null; try {
con.executeUpdate("create table Midias "+ "(ID int primary key not null, "+ "Titulo varchar(50) not null, Ano char(4) not null, "+ "Descricao text, Tipo enum (VHS , DVD) not null, "+ "unique(Titulo))"); con.executeUpdate("create table Pessoas "+ "(ID int primary key not null, "+ "Nome varchar(50) not null, Email varchar(50) not null, "+ "Endereco text, Cidade varchar(30) not null, "+ "Bairro varchar(40) not null, Telefone varchar(15), "+ "RG varchar(20) not null, unique(Email))"); } catch (SQLException e) { System.out.println("Erro: nao foi possivel criar tabela "+ Midias.\n "+ e.getMessage()); }
} }
28
3.3.2
Escrevendo um servlet
Aps vericar se o formulrio foi digitado corretamente (no arquivo Proo a cessarMidia.jsp), vamos redirecionar a aplicao para um servlet que vai ca cadastrar a m no banco de dados e redirecionar a aplicao para a pgina dia ca a de sucesso.
import import import import import javax.servlet.*; javax.servlet.http.*; java.sql.*; beans.*; conexao.*;
O protocolo Http tem dois tipos de conexo: a get, onde os parmetros so passados pela URL. a a post, onde os parmetros so passados atravs da requisio. a a e ca
public class ServletMidia extends HttpServlet { Conexao con = null; public void doGet (HttpServletRequest request, HttpServletResponse response) { this.doPost(request, response); }
Aqui pegamos o BeanMidia midia criado na pgina JSP Processara Midia.jsp. O valor de retorno do mtodo getAttribute(String) sempre um e e objeto da classe Object, portanto necessrio fazer um type cast para Beane a Midia.
BeanMidia midia = (BeanMidia) request.getAttribute("midia"); try { con = new Conexao();
29
rd = getServletContext().getRequestDispatcher("/sucesso.jsp");
} catch (SQLException ex) { if (ex.getErrorCode() == 1062) { midia.setErros("titulo", "Ttulo j existe."); a rd = getServletContext().getRequestDispatcher(""+ "/cadastro/RetryMidia.jsp"); } System.out.println(ex); } finally { if (con != null) con.fecharConexao(); con = null; }
try { if (rd != null) rd.forward(request,response); else { rd = getServletContext().getRequestDispatcher("/erro.jsp"); rd.forward(request,response); } } catch (Exception e) { System.out.println(e); } } }
3.3.3
Pgina de erro a
Na classe ServletMidia, h vrias referncias a pgina /erro.jsp. Vamos a a e a cri-la agora. Veja o cdigo: a o O atributo isErrorPage da diretiva page usado para marcar uma pgina e a JSP que serve como a pgina de erro para uma ou mais pginas. Como a a resultado disso, a pgina pode acessar o objeto impl a cito exception. J que a maioria das pginas JSP no serve como pginas de erro, o valor a a a a padro para este atributo false. a e
<%@ page isErrorPage="true" %> <html> <head> <title>Erro!</title> </head> <body>
30
<table align="center" border="0" cellspacing="2" cellpadding="2" width="70%"> <tr> <td bgcolor="#CCDDEE" align=center> <h3>Erro</h3> </td> </tr> <tr> <td bgcolor="#F7F7F7" align=center> Algum erro inesperado aconteceu.<br> </td> </tr> <tr> <td bgcolor="#F0F0F0" align=left> <li>Pode haver algum erro de conexão, tente novamente mais tarde</li> <li>Contate o administrador para depuração do erro.</li> </td> </tr> </table> </body> </html>
31
Tag Libraries
O que uma Tag Library ? e
Na tecnologia JSP, aes so elementos que podem criar e acessar objetos co a da linguagem de programao e afetar a sa de dados. A especicao de ca da ca JSP dene seis aes padro. JSP permite desenvolver mdulos reutilizveis, co a o a chamados de aes personalizadas (custom actions). Uma custom action co e invocada usando uma tag personalizada (custom tag) em uma pgina JSP. a Uma Tag Library uma coleo de custom tags. e ca Alguns exemplos de tarefas que podem ser feitas por custom actions incluem processamento de formulrios, acesso a banco de dados e outros a servios. A vantagem de usar Tag Libraries em vez de outros mtodos, como c e JavaBeans associados a scriptlets, que as Tags tornam-se mais simples de e utilizar (principalmente para programadores HTML que no conhecem Java) a e so reutilizveis. a a Algumas caracter sticas das custom tags so: a Podem ser personalizadas atravs de atributos passados pela pgina e a que solicitou a ao. ca Tem acesso a todos os objetos impl citos. Podem modicar a resposta gerada pela pgina que solicitou a ao. a ca Podem se comunicar com outras tags. Pode-se criar e inicializar JavaBeans, criar variveis que referenciam o bean em uma tag, e ento usar a a o bean em outra tag. Podem estar aninhadas dentro de outras, permitindo interaes comco plexas dentro de uma pgina JSP. a
4.1.2
Uma Tag uma classe que implementa a interface javax.servlet.jsp.tagext.Tag. e E usada para encapsular funcionalidades que podem ser usadas em uma pgina JSP. a
32
Uma Tag pode ser de dois tipos (h uma terceira na verso 1.2 de JSP): a a BodyTag ou Tag. A diferena bsica que o corpo de uma Tag avaliado c a e e apenas uma vez enquanto o corpo da BodyTag pode ser avaliado vrias vezes. a Quando uma Tag encontrada, so executados os seguintes mtodos na e a e seqncia: ue 1. setPageContext(): para ajustar o atributo PageContext. 2. setParent(): para ajustar alguma superclasse (null se nenhuma). 3. Ajustar os atributos, executando os mtodos set de cada um. e 4. doStartTag(): que inicia a tag. 5. doEndTag(): termina a tag. 6. release(): para liberar quaisquer recursos necessrios. a Existe a classe TagSupport, que implementa a interface Tag, e pode ser estendida para criar-se uma Tag. A interface BodyTag estende a interface Tag e nos fornece alguns mtodos e novos. So eles (na seqncia de execuo): a ue ca 1. setPageContext(): para ajustar o atributo PageContext. 2. setParent(): para ajustar alguma superclasse (null se nenhuma). 3. Ajustar os atributos, executando os mtodos set de cada um. e 4. doStartTag(): que inicia a tag. 5. setBodyContent(): ajusta a contedo do corpo da tag. u 6. doInitTag() aqui colocam-se instrues que devem ser executadas anco tes de avaliar o corpo da tag. 7. doAfterBody() executada aps a avaliao do corpo. Seu valor de e o ca a retorno importante. Se for SKIP BODY ele no avalia o corpo novae mente, e se for EVAL BODY BUFFERED ou EVAL BODY AGAIN ele faz outra iterao. ca 8. doEndTag(): termina a tag. 9. release(): para liberar quaisquer recursos necessrios. a Para criar uma BodyTag, basta que a classe implemente a interface BodyTag.
4.1.3
Tag Handlers?
Um tratador de tags (tag handler ) o objeto invocado por um recipiente e JSP (JSP Container ) para avaliar uma custom tag durante a execuo da ca pgina JSP que referencia a tag. Mtodos do tag handler so chamados pela a e a classe que implementa a pgina JSP nos vrios pontos que a tag encontrada. a a e 33
4.1.4
Um tag library descriptor (TLD) um documento XML que descreve a e tag library. Um TLD contm informaes sobre a biblioteca (library) como e co um todo e sobre cada tag contida na biblioteca. TLDs so usados pelo a recipiente JSP para validar as tags e por ferramentas de desenvolvimento JSP. Os seguintes elementos so necessrios para denir uma Tag Library: a a
<taglib> <tlibversion>A vers~o da biblioteca </tlibversion> a <jspversion> A vers~o da especifica~o JSP usada </jspversion> a ca <shortname> Um nome para a tag library </shortname> <uri> Uma URI que identifica unicamente a tag library </uri> <info> Informa~es sobre a tag library </info> co <tag> ... </tag> ... </taglib>
4.2
Construindo a aplicao ca
Vamos escrever uma tag que mostra todas as m dias contidas no banco de dados. Para isso, vamos fazer uma consulta e depois restaurar cada linha do resultado em uma linha de uma tabela HTML na pgina JSP. Para adicioa nar novos elementos dinamicamente e torn-los dispon a veis para outras aes co (anlogo a denio de vriaveis de script) na mesma pgina, o Recipiente a ca a a permite especicar quais elementos e quanto tempo eles estaro dispon a veis. Estas informaes so poss co a veis com a classe javax.servlet.jsp.tagext.TagExtraInfo.
4.2.1
34
PageContext pc = null; BodyContent body = null; StringBuffer sb = new StringBuffer(); ResultSet rs = null; Conexao con = null;
public void setPageContext(PageContext p) { pc = p; } public void setParent(Tag t) {} public Tag getParent() { return null; }
No mtodo doStartTag() faremos a consulta no banco de dados e armazee naremos o resultado no objeto rs e chamaremos o mtodo setVariaveis para e ajustar as variveis para a primeira passada pelo corpo da tag. A partir da a , quem vai renovar os valores das variveis o mtodo doAfterBody(), que vai a e e ser executado tantas vezes quantas forem o nmero de linhas obtidos com a u consulta SQL.
public int doStartTag() throws JspException { try { con = new Conexao(); rs = con.executeQuery("SELECT * FROM Midias order by Titulo"); setVariaveis(); } catch (SQLException e) { System.out.println(e); } if (pc.getAttribute("titulo") == null) return SKIP_BODY;
return EVAL_BODY_BUFFERED; } public void setBodyContent(BodyContent b) { body = b; } public void doInitBody() throws JspException {} private boolean setVariaveis() throws JspTagException { try { if (rs.next()) {
Armazena-se no objeto impl cito page (PageContext pc, no caso desta classe) estas variveis que sero usadas na pgina JSP. a a a
pc.setAttribute("titulo", rs.getString("Titulo")); pc.setAttribute("ano", rs.getString("Ano")); pc.setAttribute("descricao", rs.getString("Descricao")); pc.setAttribute("tipo", rs.getString("Tipo")); pc.setAttribute("ID", rs.getString("ID")); return true; } else { return false; } } catch (SQLException e) { System.out.println(e); return false; } } public int doAfterBody() throws JspException { try { sb.append(body.getString()); body.clear(); } catch (IOException e) { throw new JspTagException("Erro fatal: IOException!"); } if(setVariaveis()) { return EVAL_BODY_AGAIN; } try { body.getEnclosingWriter().write(sb.toString()); } catch (IOException e) { throw new JspTagException("Erro fatal: IOException!"); } return SKIP_BODY; } public int doEndTag() throws JspException { try { if(rs != null) { rs.close(); rs = null; } if (con != null) { con.fecharConexao(); con = null; } } catch (SQLException e) {} return EVAL_PAGE; } public void release() { pc = null; body = null; sb = null; } }
36
4.2.2
TagExtraInfo
Precisamos denir as variveis que colocamos na classe TagMidia (titulo, a ano, descricao, tipo e ID).
package tags; import javax.servlet.jsp.tagext.*; public class TagTEIMidia extends TagExtraInfo { public VariableInfo[] getVariableInfo(TagData data) { return new VariableInfo[] {
O construtor da classe VariableInfo aceita quatro argumentos: 1. O nome do atributo. 2. A classe do atributo (repare que um String, est entre aspas). e a 3. Se uma nova varivel (valor verdade) ou uma j existente na pgina e a a a (valor falso). 4. O escopo da varivel, onde: NESTED vale da tag de in a tag nal, a cio cio e a AT BEGIN vale da tag de in at o m da pgina JSP e AT END vale da tag nal at o m da pgina JSP. e a
new VariableInfo("titulo", "java.lang.String", true, VariableInfo.NESTED), new VariableInfo("ano", "java.lang.String", true, VariableInfo.NESTED), new VariableInfo("tipo", "java.lang.String", true, VariableInfo.NESTED), new VariableInfo("ID", "java.lang.String", true, VariableInfo.NESTED), new VariableInfo("descricao", "java.lang.String", true, VariableInfo.NESTED) }; } }
4.2.3
Descritor
Vamos agora criar o TagLib Descriptor. Crie o diretrio tld dentro do o diretrio WEB-INF e nele crie o arquivo TagLib.tld com o seguinte contedo: o u
<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
37
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <taglib> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>taglocadora</shortname> <info>Tags da Locadora</info> <tag> <name>mostremidias</name> <tagclass>tags.TagMidia</tagclass> <teiclass>tags.TagTEIMidia</teiclass> <bodycontent>JSP</bodycontent> <info>Tag que mostra o contedo do BD</info> u </tag> </taglib>
Dentro de <tag>, name nome que vai ser utilizado para chamar esta e tag na pgina JSP, tagclass a localizao da classe (dentro do diretrio a e ca o WEB-INF/classes), e teiclass a localizao da classe TagExtraInfo (se for e ca usada).
4.2.4
Pgina JSP a
Vamos escrever uma pgina JSP que usa a TagMidia para listar todo a contedo do banco de dados. D o nome de titulos.jsp e coloque na raiz da u e aplicao. Veja o cdigo: ca o
<%@ taglib uri="/WEB-INF/tld/TagLib.tld" prefix="todos" %> <html> <head> <title>Todos os ttulos</title> </head> <body bgcolor="#FFFFFF" text="#000000"> <table align="center" border="0" width="90%" cellspacing="2" cellpadding="4"> <tr> <th bgcolor="#CCDDEE" colspan=2> Listagem das Mdias </th> </tr>
Aqui est o in da tag. Coloque o prexo que voc deniu, e o nome a cio e da tag que quer usar (este nome est no arquivo TagLib.tld). a Entre a tag de in cio e a tag nal, pode-se usar livremente os atributos denidos na classe TagExtraInfo.
<todos:mostremidias> <tr bgcolor="#E3E3E3"> <td align=center>
38
<b>Mdia:</b> <%= titulo %> </td> <td align=center> <b>Ano:</b> <%= ano %> </td> </tr> <tr bgcolor="#F7F7F7"> <td align=center> <%= descricao %> </td> <td align=center> <%= tipo %> </td> </tr> <tr> <td colspan="2" bgcolor="#FFFFFF"> </td> </tr> </todos:mostremidias> </table> </body> </html>
39
Para criar uma tag com parmetros, basta especicar os atributos na a classe da Tag, e ento escrever os mtodos set e get para poder acess-los. a e a Tambm h modicaes no descritor da tag. e a co Vamos construir a aplicao para melhor ilustrar esta situao. ca ca
5.2
Construindo a aplicao ca
Para mostrar a utilidade das tags com parmetro, vamos fazer uma pgina a a de pesquisa de m dias, onde o usurio digita algum texto, procura-se no banco a de dados este texto e mostra-se o resultado da consulta na tela.
5.2.1
Pgina de pesquisa a
Vamos construir um arquivo chamado pesquisa.jsp, que procura por m dias no banco de dados:
<%@ taglib uri="/WEB-INF/tld/TagLib.tld" prefix="pesquisa" %> <html> <body> <center> <table align=center width="50%">
Repare que o arquivo que processa o formulrio o prprio arquivo pesa e o quisa.jsp.
<form method="post" action="pesquisa.jsp"> <th bgcolor="#CCDDEE" colspan=3> Digite a(s) palavra(s) chave(s) para a pesquisa </th> <tr bgcolor="#f7f7f7"> <td align=center>Pesquisa</td> <td align=center> <input type="text" name="chave" size=30>
40
<input type=submit value="Pesquisar >>"> <input type=reset value="Limpar"> </td> </tr> </form> </table>
Quando no for digitado nada no campo de texto ou for a primeira vez a que a pgina acessada, o comando request.getParameter(chave) retornar a e a valor nulo. Logo abaixo colocamos um comando de condio que s executa o que h ca o a dentro das chaves se o usurio digitou alguma chave de pesquisa. a
<% String tem = (String) request.getParameter("chave"); if (tem != null && !tem.equals("")) { %> <br><br> <table align=center width="70%"> <th bgcolor="#CCDDEE" colspan=3 align=center> Mdias encontradas </th>
Aqui est a tag com parmetro. Coloca-se o nome do atributo e a exa a presso ou valor associado a ele. a
<pesquisa:mostremidias chave=<%= tem %> > <tr bgcolor="#E3E3E3"> <td align=center> <b>Mdia:</b> <%= titulo %> </td> <td align=center> <b>Ano:</b> <%= ano %> </td> </tr> <tr bgcolor="#F7F7F7"> <td align=center> <%= descricao %> </td> <td align=center> <%= tipo %> </td> </tr> <tr> <td colspan="2" bgcolor="#FFFFFF"> </td> </tr> </pesquisa:mostremidias> </table>
41
5.2.2
No descritor das tags (/WEB-INF/tld/TagLib.tld ) h modicaes a sea co rem feitas para que a tag aceite parmetros. a A parte que especica a tag mostremidias car assim: a
<tag> <name>mostremidias</name> <tagclass>tags.TagMidia</tagclass> <teiclass>tags.TagTEIMidia</teiclass> <bodycontent>JSP</bodycontent> <info>Tag que mostra o contedo do BD</info> u <attribute> <name>chave</name> <required>false</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
Onde <name> o nome do atributo, <required> e se ele obrigatrio e e o ou no, e <rtexprvalue> se vo ser colocadas expresses (scriptlets ou a e a o expresses) dinmicas no valor do atributo (true, e se o valor esttico false). o a e a
5.2.3
Vamos modicar o arquivo TagMidia.java colocando um atributo chamado chave de tipo String e seus respectivos mtodos get e set. e Tambm vamos modicar o mtodo doStartTag() para que ele faa uma cone e c sulta diferente ao banco de dados caso o valor do atributo chave no seja a nulo (ou seja, queremos fazer uma pesquisa no banco de dados). Veja o novo cdigo: o
package tags; import import import import import import conexao.Conexao; java.io.*; java.sql.*; java.util.*; javax.servlet.jsp.*; javax.servlet.jsp.tagext.*;
42
BodyContent body = null; StringBuffer sb = new StringBuffer(); ResultSet rs = null; Conexao con = null; String chave = null;
public void setPageContext(PageContext p) { pc = p; } public void setParent(Tag t) {} public Tag getParent() { return null; } public int doStartTag() throws JspException { try { con = new Conexao();
Se foi passado algum parmetro, chave vai ser diferente de nulo, e feita a e uma consulta ao banco de dados, onde procura-se pela chave nos campos Titulo e Descricao.
if (chave != null) { rs = con.executeQuery("SELECT * FROM Midias where "+ "Titulo like %"+chave+"% or Descricao like "+ "%"+chave+"% order by Titulo"); } else { rs = con.executeQuery("SELECT * FROM Midias order by Titulo"); } setVariaveis(); } catch (SQLException e) { System.out.println(e); } if (pc.getAttribute("titulo") == null) return SKIP_BODY;
return EVAL_BODY_BUFFERED; } public void setBodyContent(BodyContent b) { body = b; } public void doInitBody() throws JspException {} private boolean setVariaveis() throws JspTagException { try { if (rs.next()) { pc.setAttribute("titulo", rs.getString("Titulo")); pc.setAttribute("ano", rs.getString("Ano"));
43
pc.setAttribute("descricao", rs.getString("Descricao")); pc.setAttribute("tipo", rs.getString("Tipo")); pc.setAttribute("ID", rs.getString("ID")); return true; } else { return false; } } catch (SQLException e) { System.out.println(e); return false; } } public int doAfterBody() throws JspException { try { sb.append(body.getString()); body.clear(); } catch (IOException e) { throw new JspTagException("Erro fatal: IOException!"); } if(setVariaveis()) { return EVAL_BODY_AGAIN; } try { body.getEnclosingWriter().write(sb.toString()); } catch (IOException e) { throw new JspTagException("Erro fatal: IOException!"); } return SKIP_BODY; } public int doEndTag() throws JspException { try { if(rs != null) { rs.close(); rs = null; } if (con != null) { con.fecharConexao(); con = null; } } catch (SQLException e) {} return EVAL_PAGE; } public void release() { pc = null; body = null; sb = null; } public void setChave(String nova) { chave = nova; } public String getChave() { return chave; }
44
5.2.4
Pode-se passar os valores dos formulrios HTML pela URL. Tente acessar a http://localhost:8080/locadora/pesquisa.jsp?chave=string e veja o que acontece. Se houver mais de um parmetro, separe-os usando ponto e v a rgula(;).
45
</web-app>
6.1
6.1.1
Construindo a aplicao ca
Web.xml
Vamos escrever o arquivo web.xml da nossa aplicao. Colocaremos apeca nas algumas informaes, so elas: co a O tempo de validade da sesso a Uma lista com nomes de arquivos que so abertos por padro quando a a um diretrio acessado o e Ajustar as pginas de erro padro, para que no apaream as causas do a a a c erro para o usurio (se voc no escreveu alguma pgina corretamente, a e a a j deve ter visto a pgina de erro que o Tomcat mostra). a a H uma ordem necessria das conguraes usadas no arquivo web.xml. a a co Trocando a ordem, a aplicao pode no funcionar. Abaixo est o cdigo: ca a a o 46
<?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <session-config> <session-timeout>10</session-timeout> </session-config>
6.1.2
Pgina de erro a
Vamos criar a pgina de erro que especicamos no arquivo web.xml. a Crie o arquivo erro404.jsp (404 o cdigo de pgina no encontrada) no e o a a diretrio raiz da aplicao. Veja o cdigo: o ca o
<%@ page isErrorPage="true" %> <html> <head> <title>Erro!</title> </head> <body> <table align="center" border="0" cellspacing="2" cellpadding="2" width="70%"> <tr> <td bgcolor="#CCDDEE" align=center> <h3>Erro</h3> </td> </tr> <tr> <td bgcolor="#F7F7F7" align=center> Pgina inexistente.<br> a
47
48
Agora sua vez de construir a aplicao. Crie uma parte da aplicao e ca ca que faz o cadastro de pessoas, nos mesmos moldes do cadastro de m dias. E necessrio para o cadastro obter as seguintes informaes sobre a pesa co soa: nome, endereo, telefone, cidade e bairro onde mora e RG. A tabela do c banco de dados tem o nome de Pessoas e foi criada (como voc deve lembrar) e no comeo do curso. c Nas prximas pginas esto os cdigos fonte para realizar tal processo. o a a o Mas antes de olhar lembre-se que s se aprende fazendo. o
49
CadastroPessoa.html
<html> <head> <style> p, td { font-family:Tahoma,Sans-Serif; font-size:11pt; padding-left:15; } </style> <title>Cadastro de Pessoa</title> </head> <body bgcolor="#FFFFFF" text="#000000"> <form action="ProcessarPessoa.jsp" method=post name="pessoas"> <center> <table cellpadding=4 cellspacing=2 border=0> <th bgcolor="#CCDDEE" colspan=2> <font size=5>Cadastro de Pessoas</font> <br> <font size=1><sup>*</sup> Campos necessários</font> </th> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Nome<sup>*</sup></b> <br> <input type="text" name="nome" value="" size=30 maxlength=50></td> <td valign=top> <b>Telefone</b> <br> <input type="text" name="telefone" value="" maxlength=15> </td> </tr> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Endereo c <br> <TEXTAREA NAME="endereco" ROWS="6" COLS="30"> </textarea> </td> <td valign=top> <b>RG<sup>*</sup></b></b> <br> <input type="text" name="RG" value="" maxlength=20> </td> </tr> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Cidade<sup>*</sup></b></b> <br> <input type="text" name="cidade" value="" maxlength=30> </td> <td valign=top> <b>Bairro<sup>*</sup></b></b> <br> <input type="text" name="bairro" value="" maxlength=40> </td> </tr>
50
<tr bgcolor="#F7F7F7"> <td align=center colspan=2> <input type="submit" value="Confirma"> <input type="reset" value="Limpar"> </td> </tr>
ProcessarPessoa.jsp
<%@ page import="beans.BeanPessoa" %> <jsp:useBean id="pessoa" class="beans.BeanPessoa" scope="request"> <jsp:setProperty name="pessoa" property="*" /> </jsp:useBean> <% if (pessoa.ehValido()) { %> <jsp:forward page=/servlet/ServletPessoa /> <% } else { %> <jsp:forward page="RetryPessoa.jsp" /> <% } %>
RetryPessoa.jsp
<%@ page import="beans.BeanPessoa" %> <jsp:useBean id="pessoa" class="beans.BeanPessoa" scope="request"/>
<html> <head> <style> p, td { font-family:Tahoma,Sans-Serif; font-size:11pt; padding-left:15; } </style> <title>Cadastro de Pessoa</title> </head> <body bgcolor="#FFFFFF" text="#000000"> <form action="ProcessarPessoa.jsp" method=post name="pessoas"> <center> <table cellpadding=4 cellspacing=2 border=0> <th bgcolor="#CCDDEE" colspan=2> <font size=5>Cadastro de Pessoas</font>
51
<br> <font size=1><sup>*</sup> Campos necessários</font> </th> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Nome<sup>*</sup></b> <br> <input type="text" name="nome" value=<%= pessoa.getNome() %> size=30 maxlength=50><br> <font color=#FF0000><%=pessoa.getErros("nome")%></font> </td> <td valign=top> <b>Telefone</b> <br> <input type="text" name="telefone" value=<%= pessoa.getTelefone() %> maxlength=15><br> <font color=#FF0000><%=pessoa.getErros("telefone")%></font> </td> </tr> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Endereo c <br> <TEXTAREA NAME="endereco" ROWS="6" COLS="30"> <%= pessoa.getEndereco() %> </textarea><br> <font color=#FF0000><%=pessoa.getErros("endereco")%></font> </td> <td valign=top> <b>RG<sup>*</sup></b></b> <br> <input type="text" name="RG" value=<%= pessoa.getRG() %> maxlength=20><br> <font color=#FF0000><%=pessoa.getErros("RG")%></font> </td> </tr> <tr bgcolor="#F7F7F7"> <td valign=top> <b>Cidade<sup>*</sup></b></b> <br> <input type="text" name="bairro" value=<%= pessoa.getCidade() %> maxlength=30><br> <font color=#FF0000><%=pessoa.getErros("cidade")%></font> </td> <td valign=top> <b>Bairro<sup>*</sup></b></b> <br> <input type="text" name="bairro" value=<%= pessoa.getBairro() %> maxlength=40><br> <font color=#FF0000><%=pessoa.getErros("bairro")%></font> </td> </tr>
52
<tr bgcolor="#F7F7F7"> <td align=center colspan=2> <input type="submit" value="Confirma"> <input type="reset" value="Limpar"> </td> </tr>
BeanPessoa.java
package beans; import java.util.Hashtable; /** * Implementar a classe Serializable requisito para ser um Enterprise Bean. e * Um objeto de uma classe que implementa esta interface pode ser escrito em disco ou enviado * Na aplica~o do curso n~o far diferena. ca a a c */ public class BeanPessoa implements java.io.Serializable {
/** * Nomes */ private private private private private private /* Este private
dos atributos preferencialmente iguais aos usados no formulrio a String nome; String endereco; String cidade; String telefone; String bairro; String RG; atributo serve para o controle de erros no formulrio */ a Hashtable erros;
public BeanPessoa() { /* Iniciamos os atributos com o String nulo */ nome = ""; endereco = ""; telefone = ""; cidade = ""; RG = ""; bairro = ""; erros = new Hashtable(); } /** * Mtodos para acessar os atributos. e * getNome() para ver ser valor, e setNome() para ajustar seu valor */ public String getNome() {
53
return nome; } public String getEndereco() { return endereco; } public String getCidade() { return cidade; } public String getTelefone() { return telefone; } public String getRG() { return RG; } public String getBairro() { return bairro; } public void setNome(String valor) { nome = valor; } public void setEndereco(String valor) { endereco = valor; } public void setCidade(String valor) { cidade = valor; } public void setTelefone(String valor) { telefone = valor; } public void setBairro(String valor) { bairro = valor; } public void setRG(String valor) { RG = valor; } /** * Verifica se todos os dados exigidos foram digitados, * alm de outras condi~es desejadas. e co */ public boolean ehValido() { boolean volta = true; if ((nome == null) || nome.equals("")) { erros.put("nome", "Por favor, digite um nome."); volta = false; }
54
if ((endereco == null) || endereco.equals("") ) { erros.put("endereco", "Por favor, digite o endereco."); volta = false; } if ((cidade == null) || cidade.equals("") ) { erros.put("cidade", "Por favor, selecione o cidade."); volta = false; } return volta; } /** *Usado para ver as mensagens de erro armazaenados na tabela de Hash */ public String getErros (String s) { String msg = (String) erros.get(s); return (msg == null) ? "" : msg; } /** * Usado para colocar algum erro na tabela */ public void setErros (String chave, String msg) { erros.put(chave,msg); } }
ServletPessoa.java
import import import import import javax.servlet.*; javax.servlet.http.*; java.sql.*; beans.*; conexao.*;
public class ServletPessoa extends HttpServlet { Conexao con = null; public void doGet (HttpServletRequest request, HttpServletResponse response) { this.doPost(request, response); }
55
con.executeUpdate("insert into Pessoas values ("+ con.retornaIDMax("Pessoas")+ ", "+pessoa.getNome()+" , "+pessoa.getEmail()+" , "+ pessoa.getEndereco()+" , "+pessoa.getCidade()+" , "+ pessoa.getBairro()+" , "+pessoa.getTelefone()+" , "+ pessoa.getRG()+")");
rd = getServletContext().getRequestDispatcher("/sucesso.jsp");
} catch (SQLException ex) { if (ex.getErrorCode() == 1062) { pessoa.setErros("email", "email j existe."); a rd = getServletContext().getRequestDispatcher(""+ "/cadastro/RetryPessoa.jsp"); } System.out.println(ex); } finally { if (con != null) con.fecharConexao(); con = null; }
try { if (rd != null) rd.forward(request,response); else { rd = getServletContext().getRequestDispatcher("/erro.jsp"); rd.forward(request,response); } } catch (Exception e) { System.out.println(e); } } }
56
Para recuperar ou passar objetos de uma pgina JSP para outra, ou de a uma pgina para um servlet (e vice-versa), uma das maneiras (e a mais a comum) usar os mtodos get/setAttribute(String chave, String objeto) dise e pon veis para os objetos impl citos pageContext, request, session e application.
8.2
Construindo a aplicao ca
Vamos construir uma pgina de login, onde se o usurio autorizado a a e e criada uma sesso para ele. a Precisaremos de um formulrio de acesso, um servlet para process-lo, e a a uma pgina JSP para testar se a sesso vlida ou no. a a e a a Comearemos com a pgina de acesso. Simples HTML. Veja o cdigo: c a o
Cdigo login.jsp o
public class ServletSenha extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) { doPost(req, res); }
57
HttpServletResponse res) { try { RequestDispatcher rd = null; String senha = (String) req.getParameter("senha"); String usuario = (String) req.getParameter("usuario"); if (login(usuario, senha)) { iniciarSessao(req, res); } rd = getServletContext().getRequestDispatcher(""+ "/autorizado.jsp"); if (rd != null) rd.forward(req,res); else { rd = getServletContext().getRequestDispatcher(""+ "/erro.jsp"); rd.forward(req,res); } } catch (Exception e) { System.out.println(e); }
} private boolean login(String usuario, String senha) { boolean volta = false; Conexao con = new Conexao(); try { ResultSet rs = con.executeQuery("select * from Pessoas "+ "where Email = "+usuario+""); if (rs.next()) { if (senha != null && senha.equals("senha")) volta = true; } if (con != null) con.fecharConexao(); } catch (Exception ex) { System.out.println(ex); } return volta; } private void iniciarSessao(HttpServletRequest req, HttpServletResponse res) { req.getSession().setAttribute("sessao", "autorizado"); }
58
Pgina de teste (autorizado.jsp. Note a diretiva include no in a cio do cdigo. Este arquivo (sessao.jsp) que nos interessa. o e
<%@ include file ="/sessao.jsp" %> <html> <head> <title>Erro!</title> </head> <body> <table align="center" border="0" cellspacing="2" cellpadding="2" width="70%"> <tr> <td bgcolor="#CCDDEE" align=center> <h3>Erro</h3> </td> </tr> <tr> <td bgcolor="#F7F7F7" align=center> Autorizado!<br> Voc^ pode fazer o que quiser agora nesta pgina e a </td> </tr> </table> </body> </html>
A pgina que verica se a sesso vlida (sessao.jsp) muito simples. a a e a e Se o objeto impl cito session tiver um atributo chamado de sessao e o valor dele for o String autorizado, este pedao de cdigo da pgina no faz nada, e c o a a ento o cdigo que est abaixo deste scriptlet ser mostrado. Caso contrrio, a o a a a redireciona para a pgina de erro. a
<% String sess = (String) session.getAttribute("sessao"); if (!(sess != null && sess.equals("autorizado"))) { %> <jsp:forward page="/erro403.jsp" /> <% } %>
Colocamos os Strings acima no objeto session no cdigo do arquivo Sero vletSenha lembra? :) 59
9.1
Carrinho de compras
Nosso carrinho vai ser um Bean, que vai ter como atributo principal um vetor (java.util.Vector ) que armazenar as m a dias que desejarmos. No caso, vamos armazenar apenas o t tulo da m dia, mas com um pouco mais de cdigo poder o amos armazenar um objeto BeanMidia ou qualquer outra coisa que zesse sentido na aplicao. ca Veja o cdigo para BeanCarrinho.java: o
package beans; import java.util.Vector; import java.util.Enumeration; public class BeanCarrinho { Vector v; String comando = null;
public BeanCarrinho() { v = new Vector(); } private void adicionarItens(String[] array) { for (int i = 0; i < array.length; i++) v.addElement(array[i]); } private void removerItens(String[] array) { for (int i = 0; i < array.length; i++) v.removeElement(array[i]); }
60
} public String[] getItems() { String[] s = new String[v.size()]; v.copyInto(s); return s; } public void processar(String[] itens) { if (itens != null && comando != null) { if (comando.equals("adicionar")) adicionarItens(itens); else if (comando.equals("remover")) removerItens(itens); reset(); } }
9.2
Pgina JSP a
Vamos mostrar na mesma pgina o carrinho e a pesquisa por palavrasa chave. Para isso, basta modicar um pouco o arquivo pesquisa.jsp. Vamos adicionar um formulrio com checkboxes para o usurio escolher as tas que a a deseja botar no carrinho. E no in da pgina vamos colocar a parte do cio a carrinho incluindo uma pgina que vamos criar em seguida. a Veja o cdigo para a pgina carrinho.jsp: o a
<%@ taglib uri="/WEB-INF/tld/TagLib.tld" prefix="pesquisa" %> <html> <body> <center>
Incluso esttica do arquivo carrinho1.jsp. Seria o mesmo que copiar seu a a cdigo e colar aqui. o
<%@ include file ="/carrinho1.jsp" %> <table align=center width="50%"> <form method="post" action="carrinho.jsp"> <th bgcolor="#CCDDEE" colspan=3> Digite a(s) palavra(s) chave(s) para a pesquisa
61
</th> <tr bgcolor="#f7f7f7"> <td align=center>Pesquisa</td> <td align=center> <input type="text" name="chave" size=30> <input type=submit value="Pesquisar >>"> <input type=reset value="Limpar"> </td> </tr> </form> </table> <% String tem = (String) request.getParameter("chave"); if (tem != null && !tem.equals("")) { %> <br><br> <form action=carrinho.jsp method=post> <table align=center width="70%"> <th bgcolor="#CCDDEE" colspan=2 align=center> Mdias encontradas </th> <th bgcolor="#CCDDEE" >Carrinho</th> <pesquisa:mostremidias chave=<%= tem %> > <tr bgcolor="#E3E3E3"> <td align=center> <b>Mdia:</b> <%= titulo %> </td> <td align=center> <b>Ano:</b> <%= ano %> </td> <td> <input TYPE=checkbox name=reserva value=<%=titulo %> > </td> </tr> <tr bgcolor="#F7F7F7"> <td align=center> <%= descricao %> </td> <td align=center> <%= tipo %> </td> <td> </td> </tr> <tr> <td colspan="3" bgcolor="#FFFFFF"> </td> </tr>
62
<td align=center> <input type="submit" value="Confirma"> </td> <td align=center> <input type="reset" value="Limpar"> </td> <td> </td> </tr> </table>
Vamos ver a parte lgica do carrinho agora. o Usa-se um bean vlido por toda a sesso. Com o mtodo processar(..), a a e inclu mos ou removemos m dias do BeanCarrinho. Colocando o valor do atributo property da ao <jsp:setProperty> como ca *, ele vai, para todos os parmetros presentes na requisio (objeto rea ca quest), tentar usar o mtodo setNomeDoParametro() do Bean. e
<jsp:useBean id="carrinho" scope="session" class="beans.BeanCarrinho" /> <jsp:setProperty name="carrinho" property="*" /> <% String[] temp = request.getParameterValues("reserva"); if (temp != null) { carrinho.processar(temp); } String[] items = carrinho.getItems(); if (items.length > 0) { %> <form action=carrinho.jsp method=post> <table> <th bgcolor="#CCDDEE">Voc^ tem no carrinho:</th> e <th bgcolor="#CCDDEE" >Remover</th> <% for (int i=0; i<items.length; i++) { %> <tr> <td bgcolor="#F0F0F0"> <%= items[i] %> </td> <td bgcolor="#E0E0E0"> <input type=checkbox name=reserva value=<%= items[i] %>>
63
</td> </tr> <% } %> <tr bgcolor="#E0E0E0"> <td align=center> <input type="submit" value="Confirma"> </td> <td align=center> <input type="reset" value="Limpar"> </td> <td> </td> </tr>
64
65
66
Referncias Bibliogrcas e a
[1] Duane K. Fields, Mark A. Kolb. Desenvolvendo na Web com Java Server Pages. Editora Cincia Moderna, Primeira Edio, 2000. e ca [2] Star Developer Stardeveloper.com : Connecting to Databases using JDBC. Star Developer, 2001. Dispon vel online em http://stardeveloper.com. Acessado em setembro de 2002. [3] Star Developer Stardeveloper.com : Java Server Pages and Servlets Articles. Star Developer, 2001. Dispon vel online em http://stardeveloper.com. Acessado em setembro de 2002. [4] Sun Microsystems JavaServer Pages(TM) Technology. Sun Microsystems, 2001. Dispon online em http://java.sun.com/products/jsp/. Acessado vel em setembro de 2002. [5] Orion Application Server OrionServer Taglibs Tutorial. IronFlare AB, 2002. Dispon online em http://www.orionserver.com/. Acessado em vel setembro de 2002.
67