UNIVERSIDADE FEDERAL DE SANTA CATARINA PROGRAMA ESPECIAL DE TREINAMENTO
CIˆ ENCIAS DA COMPUTAC ¸ ˜ AO
Curso de JSP
Roberto Hartke Neto
Vers˜ ao 1.0
Florian´ opolis, Outubro de 2002
Sum´ ario
1 Introdu¸ c˜ ao 3
1.1 O que ´ e JSP? . . . . 3
1.1.1 Por que usar JSP se j´ a existe PHP, ASP, etc? . . . . . 3
1.2 Como JSPs funcionam . . . . 4
1.3 Instalando e configurando o Tomcat . . . . 4
1.3.1 Obtendo o Tomcat . . . . 4
1.3.2 Instalando o Tomcat . . . . 4
1.3.3 Executando o Tomcat . . . . 5
1.3.4 Disponibilizando a aplica¸c˜ ao . . . . 5
1.3.5 Estrutura de diret´ orios da aplica¸c˜ ao . . . . 5
2 Release 1 6 2.1 Java Beans . . . . 6
2.1.1 O que faz de um Bean um Bean? . . . . 6
2.1.2 Conven¸c˜ oes de um Bean . . . . 6
2.2 JSP Tags . . . . 7
2.2.1 A¸c˜ oes JSP . . . . 7
2.2.2 Diretivas . . . . 10
2.2.3 Declara¸c˜ oes . . . . 11
2.2.4 Express˜ oes . . . . 11
2.2.5 Scriptlets . . . . 11
2.2.6 Coment´ arios . . . . 11
2.3 Objetos impl´ıcitos . . . . 12
2.4 Construindo a aplica¸c˜ ao . . . . 14
2.4.1 Construindo o formul´ ario . . . . 14
2.4.2 Criando um JavaBean . . . . 15
2.4.3 Primeiro arquivo JSP . . . . 18
2.4.4 Formul´ ario para tratar erros . . . . 19
2.4.5 P´ agina de sucesso . . . . 21
2.4.6 Disponibilizando a aplica¸c˜ ao . . . . 21
3 Release 2 22 3.1 Servlets . . . . 22
3.1.1 O que s˜ ao servlets? . . . . 22
3.2 Usando Java JDBC . . . . 23
3.2.1 Acesso ao banco de dados . . . . 23
3.2.2 Especificando o driver JDBC . . . . 23
3.2.3 Estabelecendo a conex˜ ao . . . . 23
3.2.4 Encontrando dados em uma tabela . . . . 24
3.2.5 Fazendo consultas com JDBC . . . . 24
3.3 Interface RequestDispatcher . . . . 24
3.4 Construindo a aplica¸c˜ ao . . . . 25
3.4.1 Escrevendo uma classe que conecta a um banco de dados 25 3.4.2 Criando tabelas . . . . 28
3.4.3 Cadastrando os dados no banco de dados . . . . 29
3.4.4 P´ agina de erro . . . . 29
4 Release 3 31 4.1 Tag Libraries . . . . 31
4.1.1 O que ´ e uma Tag Library ? . . . . 31
4.1.2 O que ´ e uma Tag ? . . . . 31
4.1.3 Tag Handlers ? . . . . 32
4.1.4 Descritor de Tag Libraries . . . . 33
4.2 Construindo a aplica¸c˜ ao . . . . 33
4.2.1 Escrevendo uma BodyTag . . . . 33
4.2.2 TagExtraInfo . . . . 36
4.2.3 Descritor . . . . 36
4.2.4 P´ agina JSP . . . . 37
5 Release 4 39 5.1 Tags com parˆ ametros . . . . 39
5.2 Construindo a aplica¸c˜ ao . . . . 39
5.2.1 P´ agina de pesquisa . . . . 39
5.2.2 Descritor das Tags . . . . 41
5.2.3 Modificando o arquivo TagMidia.java . . . . 41
5.2.4 Passando parˆ ametros pela URL . . . . 44
6 Descritor da aplica¸ c˜ ao 45 6.1 Construindo a aplica¸c˜ ao . . . . 45
6.1.1 Web.xml . . . . 45
6.1.2 P´ agina de erro . . . . 46
7 Release 6 48 7.1 Construindo a aplica¸c˜ ao . . . . 48
8 Release 7 56 8.1 Passando objetos para outras partes da aplica¸c˜ ao . . . . 56
8.2 Construindo a aplica¸c˜ ao . . . . 56
9 Release 8 59 9.1 Carrinho de compras . . . . 59
9.2 P´ agina JSP . . . . 60
10 Release 9 64
Referˆ encias Bibliogr´ aficas 66
Cap´ıtulo 1 Introdu¸ c˜ ao
1.1 O que ´ e JSP?
JSP significa “Java Server Pages”. Esta tecnologia ´ e usada para servir conte´ udo dinˆ amico para o usu´ ario, usando l´ ogica e dados no lado do servidor.
JSP faz parte da plataforma J2EE (Java 2 Enterprise Edition) e juntamente com os Java Servlets e Java Beans pode ser usada para desenvolver aplica¸c˜ oes web eficientes, escal´ aveis e seguras rapidamente.
1.1.1 Por que usar JSP se j´ a existe PHP, ASP, etc?
Existem v´ arias linguagens usadas para criar aplica¸c˜ oes web. Entre elas ASP, PHP, ColdFusion e Perl. Por que usar JSP ent˜ ao?
• JSP usa Java.
Java ´ e uma das linguagens mais populares atualmente e ´ e interpretada, portanto o c´ odigo escrito em uma arquitetura pode ser portado para qualquer outra.
• JSP ´ e parte do pacote J2EE
J2EE ´ e um dos modelos mais usados para contruir aplica¸c˜ oes de grande porte, e ´ e suportado por v´ arias gigantes da computa¸c˜ ao como IBM, Oracle, Sun, etc.
• Programa¸ c˜ ao em rede ´ e inerente a Java
O suporte inerente de Java para a ´ area de redes faz dela uma ´ otima linguagem para a Internet.
• JSP x ASP
Uma das diferen¸cas que pode ser fundamental para a escolha entre
estas duas tecnologias ´ e que ASP ´ e da Microsoft e s´ o roda em ambiente
Windows, e tamb´ em todo software necess´ ario ´ e pago. JSP, feito pela
Sun, roda em qualquer plataforma que tenha a m´ aquina virtual de
Java, e tem v´ arios softwares gratuitos para disponibilizar a aplica¸c˜ ao
(Tomcat por exemplo).
1.2 Como JSPs funcionam
A finalidade de JSP ´ e fornecer um m´ etodo de desenvolvimento de servlets declarativo e centrado na apresenta¸c˜ ao. A especifica¸c˜ ao de JSP ´ e definida como uma extens˜ ao da API de Servlets. Conseq¨ uentemente, n˜ ao ´ e de se admirar que por tr´ as dos panos, servlets e p´ aginas JSP tem muito em comum.
Tipicamente, p´ aginas JSP est˜ ao sujeitas a uma fase de tradu¸c˜ ao e outra de processamento da requisi¸c˜ ao. A fase de tradu¸c˜ ao ´ e feita apenas uma vez, a menos que a p´ agina JSP mude, e no caso ´ e traduzida novamente. Supondo que n˜ ao houve nenhum erro de sintaxe na p´ agina, o resultado ´ e uma p´ agina JSP que implementa a interface Servlet.
A fase de tradu¸c˜ ao ´ e tipicamente realizada pela engine JSP, quando ela recebe uma requisi¸c˜ ao para a p´ agina JSP pela primeira vez. A especifica¸c˜ ao JSP 1.1 tamb´ em permite que p´ aginas JSP sejam pr´ e-compiladas em arquivos class. Isto pode ser ´ util para evitar a demora para carregar a p´ agina JSP na primeira vez que ela ´ e acessada. V´ arias informa¸c˜ oes da fase de tradu¸c˜ ao, como a localiza¸c˜ ao de onde ´ e armazenado o p´ agina JSP j´ a compilada (portanto o servlet correspondente a esta p´ agina) s˜ ao dependentes da implementa¸c˜ ao da engine JSP.
A classe que implementa uma p´ agina JSP estende a classe HttpJspBase, que implementa a interface Servlet. O m´ etodo de servi¸co desta classe, jspService(), essencialmente encapsula o conte´ udo da p´ agina JSP. Ainda que o m´ etodo
jspService() n˜ ao pode ser sobrescrito, o desenvolvedor pode descrever even- tos de inicializa¸c˜ ao e destrui¸c˜ ao fornecendo implementa¸c˜ oes dos m´ etodos js- pInit() e jspDestroy dentro da p´ agina JSP.
Uma vez que a classe ´ e carregada no recipiente, o m´ etodo jspService() ´ e respons´ avel por responder ` as requisi¸c˜ oes do cliente.
1.3 Instalando e configurando o Tomcat
Primeiro vocˆ e precisa ter a m´ aquina virtual java (JDK 1.3 ou mais atual) instalada na sua m´ aquina. Esta pode ser obtida gratuitamente no endere¸co http://java.sun.com.
1.3.1 Obtendo o Tomcat
Tomcat ´ e um servidor de p´ aginas JSP e Servlets. Desenvolvido pela funda¸c˜ ao Apache, no projeto Jakarta, seu c´ odigo ´ e aberto e o programa ´ e gratuito. Pode ser obtido em http://jakarta.apache.org.
1.3.2 Instalando o Tomcat
Instale ou descompacte o arquivo que vocˆ e baixou em algum diret´ orio.
Depois vocˆ e ter´ a que criar duas vari´ aveis de ambiente, CATALINA HOME e JAVA HOME, onde CATALINA HOME ´ e o diret´ orio base do Tomcat e JAVA HOME ´ e o diret´ orio base da plataforma Java.
Por exemplo, se o Tomcat foi instalado em c:\tomcat e a JVM (Java
Virtual Machine) est´ a em c:\java, estas vari´ aveis devem ser:
• 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´ a em Painel de Controle, Sistema, Avan¸ cado, Vari´ aveis de Ambiente e entre com as informa¸c˜ oes.
No caso do UNIX, use o comando export (ou set, dependendo da sua distribui¸c˜ ao).
1.3.3 Executando o Tomcat
V´ a no diret´ orio CATALINA HOME\bin (onde CATALINA HOME ´ e o diret´ orio base do Tomcat), e execute o arquivo startup.bat para iniciar o Tomcat e shutdown.bat para encerr´ a-lo.
No caso dos UNIX, v´ a no mesmo diret´ orio e digite ./tomcat4 start para iniciar e ./tomcat4 stop para finaliz´ a-lo.
Para visualizar as p´ aginas acesse http://localhost:8080/ (localhost ou o en- dere¸co da m´ aquina).
1.3.4 Disponibilizando a aplica¸ c˜ ao
Crie um diret´ orio dentro do diret´ orio CATALINA HOME/webapps, ou coloque o arquivo da sua aplica¸c˜ ao (.WAR) neste diret´ orio. Para ver a aplica¸c˜ ao acesse a URL http://localhost:8080/(nome do diret´ orio ou arquivo da aplica¸ c˜ ao)/ no navegador.
Exemplo:
Para acessar a aplica¸c˜ ao localizada em CATALINA HOME/webapps/app, acesse http://localhost:8080/app.
1.3.5 Estrutura de diret´ orios da aplica¸ c˜ ao
As aplica¸c˜ oes JSP seguem um padr˜ ao. Devem ter um diret´ orio WEB-
INF (letras mai´ usculas). Dentro desse, crie outro diret´ orio chamado classes
(letras min´ usculas). Neste vocˆ e deve colocar todos as classes que vocˆ e usa na
aplica¸c˜ ao (arquivos .class), inclusive servlets e beans. Pacotes (arquivos .jar)
podem ser colocados no diret´ orio WEB-INF/lib/. Os arquivos JSP podem ser
postos no diret´ orio raiz ou em qualquer outro diret´ orio, menos no WEB-INF
e sub-diret´ orios!
Cap´ıtulo 2 Release 1
2.1 Java Beans
2.1.1 O que faz de um Bean um Bean?
Um Bean ´ e simplesmente uma classe de Java que segue um conjunto de conven¸c˜ oes simples de design e nomea¸c˜ ao delineado pela especifica¸c˜ ao de JavaBeans. Os Beans n˜ ao precisam estender uma determinada classe ou implementar uma determinada interface.
2.1.2 Conven¸ c˜ oes de um Bean
As conven¸c˜ oes de JavaBean s˜ ao o que nos permitem desenvolver Beans, porque elas permitem que o container Bean analise um arquivo de classe Java e interprete seus m´ etodos como propriedades, designando a classe como um Bean de Java.
• Beans s˜ ao simplesmente objetos Java. Mas como seguem um padr˜ ao fica mais f´ acil trabalhar com eles.
• Uma boa pr´ atica ´ e colocar Bean no nome de uma classe que ´ e um Bean, para que seja melhor identificado. Assim uma classe que representa uma pessoa ficaria PessoaBean ou BeanPessoa.
O construtor Bean
A primeira regra da cria¸c˜ ao do Bean JSP ´ e que vocˆ e tem que implemen- tar um construtor que n˜ ao tenha argumentos. Este construtor ´ e usado por exemplo para instanciar um Bean atrav´ es da tag <jsp:useBean> visto mais adiante. Se a classe n˜ ao especificar um construtor sem argumentos, ent˜ ao um construtor sem argumentos e sem c´ odigo ser´ a assumido.
public Bean() { }
Propriedades de um Bean
Coloque os atributos como privados, e fa¸ca m´ etodos get e set para acess´ a-
los, e este m´ etodos ent˜ ao ser˜ ao p´ ublicos.
private String nome;
public String getNome() { return nome;}
public void setNome(String novo) { nome = novo; }
Uma boa conven¸c˜ ao de nome de propriedades, ´ e come¸car com letra min´ uscula e colocar em mai´ uscula a primeira letra de cada palavra subseq¨ uente. Assim como nos m´ etodos de ajuste, a palavra set ou get come¸ca em min´ uscula e a primeira letra da propriedade ser´ a mai´ uscula.
private String corCarro;
public String getCorCarro();"
Propriedades indexadas
Caso a propriedade seja um conjunto de valores (array ), ´ e uma boa pr´ atica criar m´ etodos para acessar o conjunto inteiro de valores e para acessar uma posi¸c˜ ao espec´ıfica.
private String[] telefone;
public String[] getTelefone() { return telefone; }
public String getTelefone(int index) { return telefone[index]; }
Propriedades booleanas
Para propriedades booleanas, vocˆ e pode substituir a palavra get por is.
private boolean enabled;
public boolean isEnabled() { return enabled; }
2.2 JSP Tags
Numa olhada r´ apida, JSP parece com HTML (ou XML), ambos cont´ em texto encapsulado entre tags, que s˜ ao definidas entre os s´ımbolos < e >.
Mas enquanto as tags HTML s˜ ao processadas pelo navegador do cliente para mostrar a p´ agina, as tags de JSP s˜ ao usadas pelo servidor web para gerar conte´ udo dinˆ amico.
A seguir est˜ ao os tipos de tags v´ alidos em JSP:
2.2.1 A¸ c˜ oes JSP
Executam diversas fun¸c˜ oes e estendem a capacidade de JSP. Usam sintaxe
parecida com XML, e s˜ ao usadas (entre outras coisas) para manipular Java
Beans. Existem seis tipos de a¸c˜ oes:
<jsp:forward>
Este elemento transfere o objeto request contendo informa¸c˜ ao da re- quisi¸c˜ ao do cliente de uma p´ agina JSP para outro arquivo. Este pode ser um arquivo HTML, outro arquivo JSP ou um servlet, desde que fa¸ca parte da mesma aplica¸c˜ ao.
Sintaxe:
<jsp:forward page="(URL relativa | <%= express~ao %>)" />
ou
<jsp:forward page="(URL relativa | <%= express~ao %>)" >
<jsp:param name="nome do par^ametro"
value="(valor do par^ametro| <%= express~ao %>)" />
</jsp:forward>
<jsp:getProperty>
Este elemento captura o valor da propriedade de um bean usando o m´ etodo get da propriedade e mostra o valor na p´ agina JSP. ´ E necess´ ario criar 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 est´ atico ou dinˆ amico numa p´ agina JSP. Os resultados de incluir um ou outro s˜ ao diferentes. Se o arquivo
´
e est´ atico, seu conte´ udo ´ e inclu´ıdo quando a p´ agina ´ e compilada num servlet.
Se for dinˆ amico, funciona como uma requisi¸c˜ ao para o arquivo e manda o resultado de volta para a p´ agina. Quando estiver terminada a a¸c˜ ao do include continua-se processando o restante da p´ agina.
Sintaxe:
<jsp:include page="{URL relativa | <%= express~ao %>}"
flush="true" />
ou
<jsp:include page="{URL relativa | <%= express~ao %>}"
flush="true" >
<jsp:param name="nome do par^ametro"
value="{nome do par^ametro | <%= express~ao %>}" />
</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´ a embutido no navegador ou instalado na m´ aquina. N˜ ao ser´ a explicado o funcionamento deste elemento no curso.
<jsp:useBean>
Localiza ou instancia um componente. Primeiro tenta localizar uma instˆ ancia do bean. Se n˜ ao existe, instancia ele a partir da classe especifi- cada. Para localizar ou instanciar o bean, s˜ ao seguidos os seguintes passos, nesta ordem:
1. Tenta localizar o bean com o escopo e o nome especificados.
2. Define uma vari´ avel de referˆ encia ao objeto com o nome especificado.
3. Se o bean for encontrado, armazena uma referˆ encia ao objeto na vari´ avel.
Se foi especificado o tipo, converte o bean para este tipo.
4. Se n˜ ao encontrar, instancia-o pela classe especificada, armazenando uma referˆ encia ao objeto na nova vari´ avel.
5. Se o bean tiver sido instanciado (ao inv´ es de localizado), e ele tem tags 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~ao %>}"
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 m´ etodos de ajuste (set) dele. ´ E necess´ ario declarar o bean com <jsp:useBean> antes de ajustar uma propriedade. Es- tas duas a¸c˜ oes trabalham juntas, portanto o nome de instˆ ancia usada nas duas deve ser igual.
Sintaxe:
<jsp:setProperty
name="nome de inst^ancia do bean"
{ property="*" |
property="nome da propriedade" [ param="nome do par^ametro" ] | property="nome da propriedade" value="{string | <%= express~ao %>}"
} />
2.2.2 Diretivas
S˜ ao instru¸c˜ oes processadas quando a p´ agina JSP ´ e compilada em um servlet. Diretivas s˜ ao usadas para ajustar instru¸c˜ oes no n´ıvel da p´ agina, inserir dados de arquivos externos, e especificar tag libraries. Diretivas s˜ ao definidas entre <%@ e %>.
Existem trˆ es tipos de diretivas:
Include
Inclui um arquivo est´ atico em uma p´ agina JSP.
Sintaxe:
<%@ include file="relativeURL" %>
Page
Define atributos que s˜ ao aplicados a todo o arquivo JSP, e a todos os seus 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
Define uma tag library e seu prefixo a ser usado na p´ agina JSP.
Sintaxe:
<%@ taglib uri="localiza¸c~ao do descritor da tag"
prefix="prefixo da tag" %>
2.2.3 Declara¸ c˜ oes
S˜ ao similares com as declara¸c˜ oes de vari´ aveis em Java, e definem vari´ aveis para uso subseq¨ uente em express˜ oes ou scriptlets. S˜ ao definidas entre <%! e
%>.
Sintaxe:
<%! int x = 0; declara¸c~ao; ... %>
2.2.4 Express˜ oes
Cont´ em um comando v´ alido da linguagem Java que ´ e avaliado, convertido para um String, e inserido onde a express˜ ao aparece no arquivo JSP. N˜ ao ´ e usado ponte e v´ırgula para terminar a express˜ ao, e s´ o pode haver uma entre
<%= e %>.
Sintaxe:
<%= pessoa.getNome() %>
2.2.5 Scriptlets
S˜ ao blocos de c´ odigo Java embutidos numa p´ agina JSP. O c´ odigo do scriptlet ´ e inserido literalmente no servlet gerado pela p´ agina. ´ E definido entre <% e %>.
Sintaxe:
<% int x = 0;
x = 4 * 9;
String str = "PET";
...
%>
2.2.6 Coment´ arios
S˜ ao similares aos coment´ arios HTML, mas s˜ ao tirados da p´ agina quando
o arquivo JSP ´ e compilado em servlet. Isto significa que os coment´ arios
JSP n˜ ao aparecem no c´ odigo fonte da p´ agina visualizada pelo navegador
do usu´ ario. Coment´ arios em HTML s˜ ao feitos entre <!– e –>, enquanto
coment´ arios em JSP s˜ ao entre <%– e –%>.
2.3 Objetos impl´ıcitos
Como uma caracter´ıstica conveniente, o container JSP deixa dispon´ıvel objetos impl´ıcitos que podem ser usados nos scriptlets e express˜ oes, sem que o autor tenha que cri´ a-los. Estes objetos instanciam classes definidas na API (application program interface) de Servlets. S˜ ao nove objetos:
Tabela 2.1: Objetos Impl´ıcitos
Objeto Classe ou Interface Descri¸c˜ ao
page javax.servlet.jsp.HttpJspPage Instˆ ancia de servlet da p´ agina
config javax.servlet.ServletConfig Dados de configura¸c˜ ao do Servlet
request javax.servlet.http.HttpServletRequest Dados de solicita¸c˜ ao incluindo parˆ ametros response javax.servlet.http.HttpServletResponse Dados da resposta
out javax.servlet.jsp.JspWriter Fluxo de sa´ıda para o conte´ udo da p´ agina session javax.servlet.http.HttpSession Dados de sess˜ ao es-
pec´ıficos de usu´ ario application javax.servlet.ServletContext Dados compartilhados
por todas as p´ aginas da aplica¸c˜ ao
pageContext javax.servlet.jsp.PageContext Dados de contexto para execu¸c˜ ao da p´ agina
exception javax.lang.Throwable Erros n˜ ao pegos ou
exce¸c˜ ao
Objeto page
O objeto page representa a pr´ opria p´ agina JSP ou, mais especificamente, uma instˆ ancia da classe de servlet na qual a p´ agina foi traduzida.
Objeto config
O objeto config armazena dados de configura¸c˜ ao de servlet — na forma
de parˆ ametros de inicializa¸c˜ ao — para o servlet no qual uma p´ agina JSP ´ e
compilada. Pelo fato das p´ aginas JSP raramente serem escritas para interagir com parˆ ametros de inicializa¸c˜ ao, este objeto impl´ıcito raramente ´ e usado na pr´ atica.
Objeto request
O objeto request representa a solicita¸c˜ ao que acionou o processamento da p´ agina atual. Para solicita¸c˜ oes de HTTP, este objeto fornece acesso a todas as informa¸c˜ oes associadas com uma solicita¸c˜ ao, incluindo sua fonte, a URL solicitada e quaisquer cabe¸calhos, cookies ou parˆ ametros associados com a solicita¸c˜ ao. Dentre os usos mais comuns para o objeto request, encontra-se a procura por valores de parˆ ametros e cookies.
Objeto response
O objeto response representa a resposta que ser´ a enviada de volta para o usu´ ario como resultado do processamento da p´ agina JSP.
Objeto out
Este objeto impl´ıcito representa o fluxo de sa´ıda para a p´ agina, cujo conte´ udo ser´ a enviado para o navegador como o corpo de sua resposta.
Objeto session
Este objeto impl´ıcito de JSP representa a sess˜ ao atual de um usu´ ario individual. Todas as solicita¸c˜ oes feitas por um usu´ ario, que s˜ ao parte de uma ´ unica s´ erie de intera¸c˜ oes com o servidor da web, s˜ ao consideradas parte de uma sess˜ ao. Desde que novas solicita¸c˜ oes por aqueles usu´ arios continuem a ser recebidas pelo servidor, a sess˜ ao persiste. Se, no entanto, um certo per´ıodo de tempo passar sem que qualquer nova solicita¸c˜ ao do usu´ ario seja recebida, a sess˜ ao expira.
O objeto session, ent˜ ao armazena informa¸c˜ oes a respeito da sess˜ ao. Os dados espec´ıficos de aplica¸c˜ ao s˜ ao tipicamente adicionados ` a sess˜ ao atrav´ es de atributos, usando os m´ etodos da interface javax.servlet.http.HttpSession.
O objeto session n˜ ao est´ a dispon´ıvel para todas as p´ aginas JSP, seu uso
´
e restrito ` as p´ aginas que participam do gerenciamento da sess˜ ao. Isto ´ e indicado atrav´ es do atributo session da diretiva page. O padr˜ ao ´ e que todas as p´ aginas participem do gerenciamento de sess˜ ao. Se o atributo estiver definido para false, o objeto n˜ ao estar´ a dispon´ıvel e seu uso resultar´ a em um erro de compila¸c˜ ao quando o recipiente JSP tentar traduzir a p´ agina para um servlet.
Objeto application
Este objeto impl´ıcito representa a aplica¸c˜ ao ` a qual a p´ agina JSP pertence.
Ela ´ e uma instˆ ancia da interface javax.servlet.ServletContext. As p´ aginas JSP est˜ ao agrupadas em aplica¸c˜ oes de acordo com suas URLs.
Este objeto permite acessar informa¸c˜ oes do container, interagir com o
servidor e fornece suporte para logs.
Objeto pageContext
O objeto pageContext ´ e uma instˆ ancia da classe javax.servlet.jsp.PageContext, e fornece acesso program´ atico a todos os outros objetos impl´ıcitos. Para os objetos impl´ıcitos que aceitam atributos, o objeto pageContext tamb´ em for- nece m´ etodos para acessar aqueles atributos. Al´ em disso, o objeto pageCon- text implementa m´ etodos para transferir controle da p´ agina atual para uma outra p´ agina, temporariamente, para gerar output a ser inclu´ıdo no output da p´ agina atual, ou permanentemente para transferir todo o controle.
Objeto exception
O objeto exception ´ e uma instˆ ancia da classe java.lang.Throwable. O objeto exception n˜ ao est´ a automaticamente dispon´ıvel em todas as p´ aginas JSP. Ao inv´ es disso, este objeto est´ a dispon´ıvel apenas nas p´ aginas que te- nham sido designadas como p´ aginas de erro, usando o atributo isErrorPage da diretiva page.
2.4 Construindo a aplica¸ c˜ ao
Iniciando a constru¸c˜ ao da aplica¸c˜ ao, vamos criar um formul´ ario de cadas- tro para a m´ıdia, um bean que representa a m´ıdia, e um arquivo JSP que processa o formul´ ario. Criaremos tamb´ em um formul´ ario idˆ entico ao pri- meiro mas que mostra poss´ıveis erros ocorridos no cadastro. E por ´ ultimo, uma p´ agina HTML simples que indica se o cadastro foi realizado ou n˜ ao.
2.4.1 Construindo o formul´ ario
Aqui iremos criar o formul´ ario para o cadastro de fitas. Ele ´ e puramente feito em HTML, n˜ ao tem c´ odigo jsp.
<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">
Especificamos o arquivo que processar´ a o formul´ ario no atributo action 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>
<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 formul´ ario devem preferencialmente ter o mesmo nome que seu atributo correspondente no bean usado para armazenar as informa¸c˜ oes do formul´ ario.
<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¸c~ao
<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>
</table>
</center>
</form>
</body>
</html>
2.4.2 Criando um JavaBean
Vamos criar nosso bean que ter´ a as informa¸c˜ oes da M´ıdia. Ele deve ter
todos os atributos do formul´ ario que constru´ımos, e todos os m´ etodos set
e get para acess´ a-los. Al´ em disso, teremos outro atributo, para controle
de eventuais erros no processamento do formul´ ario (dados necess´ arios n˜ ao digitados por exemplo). Usaremos uma tabela de hash (java.util.Hashtable) que ter´ a como chave o nome do atributo e como valor a mensagem de erro que desejarmos. Chamaremos a Hashtable de erros, e ela tamb´ em ter´ a seus m´ etodos set e get.
Por fim, criaremos um m´ etodo para verificar se todos os dados necess´ arios foram digitados, validando ou n˜ ao o formul´ ario.
Abaixo est´ a o c´ odigo fonte do BeanMidia, veja os coment´ arios para mai- ores detalhes.
package beans;
import java.util.Hashtable;
/**
* Implementar a classe Serializable ´e requisito para ser um
* Enterprise Bean. Um objeto de uma classe que implementa
* esta interface pode ser escrito em disco ou enviado pela rede.
* Na aplica¸c~ao do curso n~ao far´a diferen¸ca.
*/
public class BeanMidia implements java.io.Serializable {
/**
* Nomes dos atributos preferencialmente iguais aos usados
* no formul´ario
*/
private String titulo;
private String ano;
private String tipo;
private String descricao;
/* Este atributo serve para o controle de erros no formul´ario */
private Hashtable erros;
public BeanMidia() {
/* Iniciamos os atributos com o String nulo */
titulo = "";
ano = "";
descricao = "";
tipo = "";
erros = new Hashtable();
} /**
* M´etodos para acessar os atributos.
* 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;
}
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,
* al´em de outras condi¸c~oes desejadas.
*/
public boolean ehValido() { boolean volta = true;
if ((titulo == null) || titulo.equals("")) {
erros.put("titulo", "Por favor, digite um t´ıtulo.");
volta = false;
}
if ((ano == null) || ano.equals("") ) {
erros.put("ano", "Por favor, digite o ano da m´ıdia .");
volta = false;
}
if ((tipo == null) || tipo.equals("") ) {
erros.put("tipo", "Por favor, selecione o tipo da m´ıdia .");
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;
}
/**
* Usado para colocar algum erro na tabela
*/
public void setErros (String chave, String msg) {
erros.put(chave,msg);
} }
2.4.3 Primeiro arquivo JSP
Agora vamos construir o arquivo que processa o formul´ ario, este, at´ e que enfim, feito em JSP.
O atributo import da diretiva page estende o conjunto de classes Java que podem ser referenciadas um uma p´ agina JSP sem ter que explicitamente especificar os nomes de pacote de classes.
<%@ page import="beans.BeanMidia" %>
A tag <jsp:useBean> diz ` a p´ agina que vocˆ e quer disponibilizar um Bean para a p´ agina.
• O atributo id especifica um nome para o Bean, que ser´ a o nome usado para referenciar o Bean ao longo da p´ agina e de sua vida na aplica¸c˜ ao.
• O atributo class especifica o nome de classe do pr´ oprio Bean.
• O atributo scope controla o escopo do Bean, ou seja, para quem e quanto tempo ele permanecer´ a dispon´ıvel. Os valores podem ser page, request, session e application.
<jsp:useBean id="midia" class="beans.BeanMidia" scope="request">
Mostramos abaixo trˆ es maneiras de ajustar os atributos de um bean. A primeira diz-se o nome do atributo do bean no parˆ ametro property e ent˜ ao especifica-se o valor no parˆ ametro value.
Nas outras duas o atributo do bean tem o mesmo nome do valor colocado em property.
Pode-se tamb´ em ajustar os valores dos atributos usando os m´ etodos set 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>
Verifica-se se todos os atributos necess´ arios foram digitados e ent˜ ao redireciona- se para a p´ agina de sucesso ou para o formul´ ario que trata erros.
<%
if (midia.ehValido()) {
%>
<jsp:forward page="/sucesso.jsp"/>
<%
} else {
%>
<jsp:forward page="RetryMidia.jsp" />
<%
}
%>
2.4.4 Formul´ ario para tratar erros
Este arquivo ´ e visualmente idˆ entico ao formul´ ario anterior, mas ele ´ e um arquivo JSP que mostra poss´ıveis erros ocorridos durante o cadastro.
Declaramos o bean usado no arquivo nas primeiras linhas. ´ E necess´ ario que ele tenha o mesmo nome dos arquivos antecessores (no caso, Processar- Midia.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 formul´ ario fique igual ao que foi digitado anteriormente. Isto poupa
trabalho ao usu´ ario que n˜ ao precisa digitar tudo novamente.
<input type="text" name="titulo" value=’<%= midia.getTitulo() %>’
size=30 maxlength=40><br>
Se houve algum erro na digita¸c˜ ao do t´ıtulo, o comando midia.getErros(“titulo”) retornar´ a o String de erro que colocamos na tabela de hash associado a chave
“titulo”, caso contr´ ario n˜ ao retornar´ a nada e n˜ ao aparecer´ a nada na p´ agina.
<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¸c~ao
<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) verifica se o valor do atributo tipo ´ e igual ao String. Se for, ele imprime checked no c´ odigo fonte da p´ agina, fazendo com que o checkbox fique marcado. Isto serve, novamente, para deixar o formul´ ario como o usu´ ario digitou anteriormente.
<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">
<input type="reset" value="Limpar">
</td>
</tr>
</table>
</center>
</form>
</body>
</html>
2.4.5 P´ agina de sucesso
Vamos fazer uma p´ agina que nos indica se a opera¸c˜ ao foi realizada com sucesso. Sempre que houve ˆ exito, redirecionaremos a aplica¸c˜ ao para esta p´ agina.
<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 aplica¸ c˜ ao
Crie um diret´ orio chamado locadora no diret´ orio webapps do Tomcat.
Dentro do diret´ orio locadora, crie um diret´ orio cadastro e coloque os arquivos ProcessarMidia.jsp, CadastroMidia.html e RetryMidia.jsp.
No diret´ orio raiz da aplica¸c˜ ao (../locadora) coloque o arquivo sucesso.jsp, e no diret´ orio WEB-INF/classes/beans coloque os arquivos BeanMidia.java e BeanMidia.class
Agora, inicie o Tomcat, acesse no navegador a URL http://localhost:8080/locadora
e teste a aplica¸c˜ ao.
Cap´ıtulo 3 Release 2
3.1 Servlets
3.1.1 O que s˜ ao servlets?
Servlets s˜ ao programas simples feitos em Java os quais rodam em um Servlet Container. Um Recipiente (Container) Servlet ´ e como um servidor Web que trata requisi¸c˜ oes do usu´ ario e gera respostas. Recipiente Servlet
´
e diferente de Servidor Web porque ele ´ e feito somente para Servlets e n˜ ao para outros arquivos (como .html etc). O Recipiente Servlet ´ e respons´ avel por manter o ciclo de vida do Servlet. Pode ser usado sozinho (standalone) ou conjugado com um servidor Web. Exemplo de Recipiente Servlet ´ e o Tomcat, e de servidor Web o Apache.
Servlets s˜ ao na verdade simples classes Java as quais necessitam imple- mentar a interface javax.servlet.Servlet. Esta interface cont´ em cinco m´ etodos que precisam ser implementados. Na maioria das vezes vocˆ e n˜ ao precisa im- plementar esta interface. Por quˆ e? Porque o pacote javax.servlet j´ a provˆ e duas classes que implementam esta interface i.e. GenericServlet e HttpSer- vlet. Ent˜ ao tudo que vocˆ e precisa fazer ´ e estender uma dessas classes e so- brescrever o m´ etodo que vocˆ e precisa para seu Servlet. GenericServlet ´ e uma classe muito simples que somente implementa a interface javax.servlet.Servlet e fornece apenas funcionalidades b´ asicas. Enquanto HttpServlet ´ e uma classe mais ´ util que fornece m´ etodos para trabalhar com o protocolo HTTP. As- sim se seu servlet usa o protocolo HTTP (o que ocorrer´ a na maioria dos casos) ent˜ ao ele deveria estender a classe javax.servlet.http.HttpServlet para construir um servlet e isto ´ e o que faremos na nossa aplica¸c˜ ao.
Servlets uma vez iniciados s˜ ao mantidos na mem´ oria. Ent˜ ao toda re- quisi¸c˜ ao que chega, vai para o Servlet na mem´ oria e este gera uma resposta.
Esta caracter´ıstica de “manter na mem´ oria” faz com que usar Java Servlets seja um m´ etodo extremamente r´ apido e eficiente para construir aplica¸c˜ oes Web.
N˜ ao ser´ a escrito nenhum Servlet neste curso.
3.2 Usando Java JDBC
JDBC (Java DataBase Connectivity) ´ e a API Java para comunica¸c˜ ao com bancos de dados. JDBC especifica a interface necess´ aria para conectar a um banco de dados, executar comandos SQL e queries, e interpretar resultados.
Esta interface ´ e independente do banco de dados e da plataforma.
As classes JDBC est˜ ao no pacote java.sql, que precisa ser importado para a classe Java que faz uso de alguma classe desta API.
3.2.1 Acesso ao banco de dados
A API JDBC n˜ ao pode comunicar-se diretamente com o banco de dados.
O acesso ´ e fornecido por um driver JDBC, que ´ e uma classe espec´ıfica para o banco de dados e implementa a interface definida pela API. Este driver ´ e fornecido pelo vendedor do banco de dados ou por outro provedor de servi¸co.
3.2.2 Especificando o driver JDBC
No seu programa, vocˆ e tem que especificar o driver JDBC que vai usar.
Faz-se isso com uma simples, talvez estranha, opera¸c˜ ao:
Class.forName(JDBC-driver-class-name)
O m´ etodo Class.forName() faz com que a JVM carregue o driver na mem´ oria. Vocˆ e pode pensar que tem que instanciar a classe do driver e usar a referˆ encia a ele para acessar o banco de dados, mas JDBC n˜ ao funciona desta maneira. Quando o driver ´ e carregado na mem´ oria da JVM, ele se registra com a classe java.sql.DriverManager. Ent˜ ao vocˆ e usa m´ etodos est´ aticos da classe DriverManager para obter referˆ encia ao objeto Connection, que ent˜ ao fornecer´ a acesso ao banco de dados.
3.2.3 Estabelecendo a conex˜ ao
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~ao foi poss´ıvel encontrar a classe do Driver do MySQL");
} catch (SQLException ex) {
System.out.println("N~ao foi poss´ıvel conectar ao servidor");
} finally {
try { if (connection != null) connection.close(); } catch (SQLException e) { }
}
3.2.4 Encontrando dados em uma tabela
Antes de poder fazer consultas ao banco de dados com JDBC, vocˆ e precisa criar um objeto Statement. Um objeto Statement pode ser reutilizado atrav´ es de m´ ultiplas requisi¸c˜ oes SQL. ´ E criado pelo objeto Connection e ´ e portanto dependente do driver que vocˆ e est´ a usando para conectar ao banco de dados.
E muito simples, como vocˆ ´ e pode ver:
Statement statement = connection.createStatement();
3.2.5 Fazendo consultas com JDBC
Fazer uma consulta com JDBC ´ e f´ acil uma vez que vocˆ e tenha o objeto Statement : vocˆ e simplesmente passa a consulta como parˆ ametro do m´ etodo executeQuery(). A tabela de resultados ´ e retornada pelo m´ etodo como uma instˆ ancia da classe ResultSet da API de JDBC. Abaixo est´ a um exemplo de consulta:
String query = ‘‘SELECT * FROM TABELA’’;
ResultSet resultset = statement.executeQuery(query);
Estes m´ etodos lan¸cam exce¸c˜ oes, portanto no seu programa deve estar dentro de um bloco try/catch.
O objeto ResultSet revela o conte´ udo da tabela uma linha por vez e for- nece m´ etodos para acessar dados de cada coluna da tabela da linha corrente, indicada por um cursor interno. Quando o ResultSet ´ e criado, o cursor de linha n˜ ao est´ a na primeira linha, mas sim antes dela. Chamando o m´ etodo next(), o ResultSet avan¸ca o cursor em uma linha, retornando valor verdade 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´ a posicionado em uma linha que vocˆ e gostaria de examinar, vocˆ e pode chamar v´ arios m´ etodos suportados pelo objeto ResultSet para restaurar dados das colunas e obter informa¸c˜ oes sobre os resultados.
3.3 Interface RequestDispatcher
Esta interface est´ a presente no pacote javax.servlet e cont´ em dois m´ etodos:
• forward(ServletRequest request, ServletResponse response) transfere uma requisi¸c˜ ao para outro recurso no mesmo servidor. Este recurso pode ser um servlet, uma p´ agina JSP ou uma simples p´ agina HTML.
• include(ServletRequest request, ServletResponse response) atua no lado do servidor, inclui a resposta do recurso dado (Servlet, p´ agina JSP ou HTML) dentro da resposta de quem chamou o recurso.
Para obter uma referˆ encia a interface RequestDispatcher temos duas for- mas:
• ServletContext.getRequestDispatcher(String resource)
• ServletRequest.getRequestDispatcher(String resource)
Se o servlet ´ e subclasse de HttpServletRequest, simplesmente chama-se o m´ etodo getRequestDispatcher(String resource) para pegar uma referˆ encia ao objeto RequestDispatcher.
RequestDispatcher rd;
rd = request.getRequestDispatcher("caminho do recurso");
rd.forward(request, response);
Se n˜ ao for subclasse, utilize a outra maneira.
rd = getServletContext().getRequestDispatcher("caminho do recurso");
rd.forward(request, response);
3.4 Construindo a aplica¸ c˜ ao
3.4.1 Escrevendo uma classe que conecta a um banco de dados
Na aplica¸c˜ ao que estamos construindo neste curso, teremos que inserir e restaurar dados do bancos de dados diversas vezes. Para simplificar nossa vida, criaremos uma classe que conecta ao banco de dados, e tem m´ etodos para acess´ a-lo. Assim para fazer a conex˜ ao bastar´ a instanciar um objeto desta classe.
J´ a no construtor da classe faremos a conex˜ ao usando os m´ etodos descritos na parte de JDBC desta apostila.
Para os outros m´ etodos, leia os coment´ arios do arquivo para maiores detalhes.
package conexao;
import java.sql.*;
public class Conexao {
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~ao foi poss´ıvel encontrar a classe do "+
"Driver do MySQL");
} catch (SQLException ex) {
System.out.println("N~ao foi poss´ıvel conectar ao servidor");
throw ex;
} try {
statement = connection.createStatement();
} catch (SQLException ex) {
System.out.println("N~ao foi poss´ıvel criar a statement");
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~ao foi poss´ıvel encontrar a classe "+
"do Driver do MySQL");
} catch (SQLException ex) {
System.out.println("N~ao foi poss´ıvel conectar ao servidor");
} try {
statement = connection.createStatement();
} catch (SQLException ex) {
System.out.println("N~ao foi poss´ıvel criar a statement");
} }
/**
* Executa um update na base de dados
* @param update String SQL a ser executado
* @throws SQLException se n~ao for poss´ıvel executar
* o update (Erro de SQL).
*/
public synchronized void executeUpdate(String update) throws SQLException {
try {
statement.executeUpdate(update);
} catch (SQLException ex) {
System.out.println("N~ao foi poss´ıvel executar o update");
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~ao for poss´ıvel executar a query
* (Erro de SQL).
*/
public synchronized ResultSet executeQuery(String query) throws SQLException {
try {
return statement.executeQuery(query);
} catch (SQLException ex) {
System.out.println("N~ao foi poss´ıvel executar a query");
throw ex;
} } /**
* Fecha a conexao com a base de dados.
*/
public void fecharConexao() {
try {
statement.close();
} catch (SQLException ex) { ex.printStackTrace();
} }
/**
* Retorna o maior n´umero de um campo da tabela se ele
* for um inteiro. Assim, n~ao teremos nenhum ID igual a outro.
*/
public int retornaIDMax(String tabela) {
try {
String sql="SELECT max(ID) as contador FROM "+tabela;
ResultSet rs = this.executeQuery(sql);
rs.next();
return rs.getInt("contador")+1;
} catch (SQLException e) {
System.out.println("Erro na sele¸c~ao do ID M´aximo");
e.printStackTrace();
return 0;
} }
}
3.4.2 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 instˆ ancia da classe Co- nexao, e ent˜ ao executar um comando SQL usando o m´ etodo executeUp- 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());
}
} }
Para criar as tabelas, basta executar a classe CriaTabelas.
3.4.3 Cadastrando os dados no banco de dados
Ap´ os verificar se o formul´ ario foi digitado corretamente (no arquivo Pro- cessarMidia.jsp ), vamos redirecionar a aplica¸c˜ ao para um arquivo que vai cadastrar a m´ıdia no banco de dados e redirecionar a aplica¸c˜ ao para a p´ agina de sucesso. Modifique o arquivo ProcessarMidia.jsp dando um forward para o arquivo CadMidia.jsp em vez de sucesso.jsp.
<%@ page import="beans.BeanMidia, java.sql.*, conexao.*" %>
<%! String pagina = null; %>
<%
BeanMidia midia = (BeanMidia) request.getAttribute("midia");
Conexao con = null;
try {
con = new Conexao();
con.executeUpdate("insert into Midias values ("+con.retornaIDMax("Midias")+
", ’"+midia.getTitulo()+"’ , ’"+midia.getAno()+
"’ , ’"+midia.getDescricao()+"’ , ’"+
midia.getTipo()+"’)");
pagina = "/sucesso.jsp";
} catch (SQLException ex) {
if (ex.getErrorCode() == 1062) {
midia.setErros("titulo", "T´ıtulo j´a existe.");
pagina = "/cadastro/RetryMidia.jsp";
}
System.out.println(ex);
} finally {
if (con != null)
con.fecharConexao();
con = null;
}
if (pagina == null)
pagina = "/erro.jsp";
%>
<jsp:forward page=’<%= pagina %>’ />
3.4.4 P´ agina de erro
No arquivo CadMidia.jsp, h´ a referˆ encia a p´ agina /erro.jsp. Vamos cri´ a-la
agora. Veja o c´ odigo:
O atributo isErrorPage da diretiva page ´ e usado para marcar uma p´ agina JSP que serve como a p´ agina de erro para uma ou mais p´ aginas. Como resultado disso, a p´ agina pode acessar o objeto impl´ıcito exception.
J´ a que a maioria das p´ aginas JSP n˜ ao serve como p´ aginas de erro, o valor padr˜ ao para este atributo ´ e false.
<%@ 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>
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>
Cap´ıtulo 4 Release 3
4.1 Tag Libraries
4.1.1 O que ´ e uma Tag Library ?
Na tecnologia JSP, a¸c˜ oes s˜ ao elementos que podem criar e acessar objetos da linguagem de programa¸c˜ ao e afetar a sa´ıda de dados. A especifica¸c˜ ao de JSP define seis a¸c˜ oes padr˜ ao. JSP permite desenvolver m´ odulos reutiliz´ aveis, chamados de a¸c˜ oes personalizadas (custom actions ). Uma custom action ´ e invocada usando uma tag personalizada (custom tag ) em uma p´ agina JSP.
Uma Tag Library ´ e uma cole¸c˜ ao de custom tags.
Alguns exemplos de tarefas que podem ser feitas por custom actions incluem processamento de formul´ arios, acesso a banco de dados e outros servi¸cos. A vantagem de usar Tag Libraries em vez de outros m´ etodos, como JavaBeans associados a scriptlets, ´ e que as Tags tornam-se mais simples de utilizar (principalmente para programadores HTML que n˜ ao conhecem Java) e s˜ ao reutiliz´ aveis.
Algumas caracter´ısticas das custom tags s˜ ao:
• Podem ser personalizadas atrav´ es de atributos passados pela p´ agina que solicitou a a¸c˜ ao.
• Tem acesso a todos os objetos impl´ıcitos.
• Podem modificar a resposta gerada pela p´ agina que solicitou a a¸c˜ ao.
• Podem se comunicar com outras tags. Pode-se criar e inicializar Java- Beans, criar vari´ aveis que referenciam o bean em uma tag, e ent˜ ao usar o bean em outra tag.
• Podem estar aninhadas dentro de outras, permitindo intera¸c˜ oes com- plexas dentro de uma p´ agina JSP.
4.1.2 O que ´ e uma Tag ?
Uma Tag ´ e uma classe que implementa a interface javax.servlet.jsp.tagext.Tag.
E usada para encapsular funcionalidades que podem ser usadas em uma ´
p´ agina JSP.
Uma Tag pode ser de dois tipos (h´ a uma terceira na vers˜ ao 1.2 de JSP):
BodyTag ou Tag. A diferen¸ca b´ asica ´ e que o corpo de uma Tag ´ e avaliado apenas uma vez enquanto o corpo da BodyTag pode ser avaliado v´ arias vezes.
Quando uma Tag ´ e encontrada, s˜ ao executados os seguintes m´ etodos na seq¨ uˆ encia:
1. setPageContext(): para ajustar o atributo PageContext.
2. setParent(): para ajustar alguma superclasse (null se nenhuma).
3. Ajustar os atributos, executando os m´ etodos set de cada um.
4. doStartTag(): que inicia a tag.
5. doEndTag(): termina a tag.
6. release(): para liberar quaisquer recursos necess´ arios.
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 m´ etodos novos. S˜ ao eles (na seq¨ uˆ encia de execu¸c˜ ao):
1. setPageContext(): para ajustar o atributo PageContext.
2. setParent(): para ajustar alguma superclasse (null se nenhuma).
3. Ajustar os atributos, executando os m´ etodos set de cada um.
4. doStartTag(): que inicia a tag.
5. setBodyContent(): ajusta a conte´ udo do corpo da tag.
6. doInitTag() aqui colocam-se instru¸c˜ oes que devem ser executadas an- tes de avaliar o corpo da tag.
7. doAfterBody() ´ e executada ap´ os a avalia¸c˜ ao do corpo. Seu valor de retorno ´ e importante. Se for SKIP BODY ele n˜ ao avalia o corpo nova- mente, e se for EVAL BODY BUFFERED ou EVAL BODY AGAIN ele faz outra itera¸c˜ ao.
8. doEndTag(): termina a tag.
9. release(): para liberar quaisquer recursos necess´ arios.
Para criar uma BodyTag, basta que a classe implemente a interface Body- Tag.
4.1.3 Tag Handlers ?
Um tratador de tags (tag handler ) ´ e o objeto invocado por um recipiente
JSP (JSP Container ) para avaliar uma custom tag durante a execu¸c˜ ao da
p´ agina JSP que referencia a tag. M´ etodos do tag handler s˜ ao chamados pela
classe que implementa a p´ agina JSP nos v´ arios pontos que a tag ´ e encontrada.
4.1.4 Descritor de Tag Libraries
Um tag library descriptor (TLD) ´ e um documento XML que descreve a tag library. Um TLD cont´ em informa¸c˜ oes sobre a biblioteca (library ) como um todo e sobre cada tag contida na biblioteca. TLDs s˜ ao usados pelo recipiente JSP para validar as tags e por ferramentas de desenvolvimento JSP. Os seguintes elementos s˜ ao necess´ arios para definir uma Tag Library :
<taglib>
<tlibversion>A vers~ao da biblioteca </tlibversion>
<jspversion> A vers~ao da especifica¸c~ao JSP usada </jspversion>
<shortname> Um nome para a tag library </shortname>
<uri> Uma URI que identifica unicamente a tag library </uri>
<info> Informa¸c~oes sobre a tag library </info>
<tag> ... </tag>
...
</taglib>
4.2 Construindo a aplica¸ c˜ ao
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 p´ agina JSP. Para adicio- nar novos elementos dinamicamente e torn´ a-los dispon´ıveis para outras a¸c˜ oes (an´ alogo a defini¸c˜ ao de v´ ariaveis de script) na mesma p´ agina, o Recipiente permite especificar quais elementos e quanto tempo eles estar˜ ao dispon´ıveis.
Estas informa¸c˜ oes s˜ ao poss´ıveis com a classe javax.servlet.jsp.tagext.TagExtraInfo.
4.2.1 Escrevendo uma BodyTag
Abaixo est´ a a classe TagMidia, que implementa a interface javax.servlet.jsp.tagext.Bodytag.
package tags;
import conexao.Conexao;
import java.io.*;
import java.sql.*;
import java.util.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
public final class TagMidia implements BodyTag {
private PageContext pc = null;
private BodyContent body = null;
private StringBuffer sb = new StringBuffer();
private ResultSet rs = null;
private Conexao con = null;
public void setPageContext(PageContext p) {
pc = p;
}
public void setParent(Tag t) {}
public Tag getParent() {
return null;
}
No m´ etodo doStartTag() faremos a consulta no banco de dados e armaze- naremos o resultado no objeto rs e chamaremos o m´ etodo setVariaveis para ajustar as vari´ aveis para a primeira passada pelo corpo da tag. A partir da´ı, quem vai renovar os valores das vari´ aveis ´ e o m´ etodo doAfterBody(), que vai ser executado tantas vezes quantas forem o n´ umero de linhas obtidos com a 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()) {
Aqui vamos ajustar as vari´ aveis que vamos definir na classe TagExtraInfo.
Armazena-se no objeto impl´ıcito page (PageContext pc, no caso desta classe) estas vari´ aveis que ser˜ ao usadas na p´ agina JSP.
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;
} }
4.2.2 TagExtraInfo
Precisamos definir as vari´ aveis que colocamos na classe TagMidia (titulo, 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 ´ e um String, est´ a entre aspas).
3. Se ´ e uma nova vari´ avel (valor verdade) ou uma j´ a existente na p´ agina (valor falso).
4. O escopo da vari´ avel, onde: NESTED vale da tag de in´ıcio a tag final, AT BEGIN vale da tag de in´ıcio at´ e o fim da p´ agina JSP e AT END vale da tag final at´ e o fim da p´ agina JSP.
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 diret´ orio tld dentro do diret´ orio WEB-INF e nele crie o arquivo TagLib.tld com o seguinte conte´ udo:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"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 conte´udo do BD</info>
</tag>
</taglib>
Dentro de <tag>, name ´ e nome que vai ser utilizado para chamar esta tag na p´ agina JSP, tagclass ´ e a localiza¸c˜ ao da classe (dentro do diret´ orio WEB-INF/classes ), e teiclass ´ e a localiza¸c˜ ao da classe TagExtraInfo (se for usada).
4.2.4 P´ agina JSP
Vamos escrever uma p´ agina JSP que usa a TagMidia para listar todo conte´ udo do banco de dados. Dˆ e o nome de titulos.jsp e coloque na raiz da aplica¸c˜ ao. Veja o c´ odigo:
<%@ taglib uri="/WEB-INF/tld/TagLib.tld" prefix="todos" %>
<html>
<head>
<title>Todos os t´ıtulos</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 M´ıdias
</th>
</tr>
Aqui est´ a o in´ıcio da tag. Coloque o prefixo que vocˆ e definiu, e o nome da tag que quer usar (este nome est´ a no arquivo TagLib.tld).
Entre a tag de in´ıcio e a tag final, pode-se usar livremente os atributos definidos na classe TagExtraInfo.
<todos:mostremidias>
<tr bgcolor="#E3E3E3">
<td align=center>
<b>M´ıdia:</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>