Professional Documents
Culture Documents
I - Fundamentos Básicos 3
II – Servlets 16
IV – Objetos Implícitos 41
- Objetos Implícitos 41
− Relacionados a Servlets 42
− Relacionados ao Input/Output 43
− Contextuais 48
− Tratamento de Erros 55
− Ações 56
V – Cookies 61
2
− A classe ResultSet 76
3
I - Fundamentos Básicos
Este capítulo cobre os seguintes tópicos :
A plataforma Web
Baseada em HTTP (RFC 2068)
Protocolosimples de transferência de arquivos
Sem estado (não mantém sessão aberta)
4
Principais m étodos H T T P
G ET – pede ao servidor um arquivo, inform ando
sua U R I absoluta
Pode enviar dados porém o tam anho é lim itado
PO ST – envia dados ao servidor (com o fluxo de
bytes)
É o m étodo preferido quando se está usando
form ulários para subm issão
H EA D – U sado para obter inform ações do
docum ento. A penas o cabeçalho é retornado
5
O que é JSP ?
JSP é um acrônimo para Java Server Pages e consiste numa linguagem de script baseada
em java para criação de sites com conteúdos dinâmicos.
Inicialmente as páginas na Web eram apenas páginas estáticas, isto é, seu conteúdo não
variava a cada solicitação conforme algum parâmetro. Com a sofisticação dos serviços
disponibilizados via Web, surgiu a necessidade de disponibilizar informações com
natureza dinâmica (lista de preços atualizados, compras on-line, etc). Isso exigiu que o
servidor web fizesse algum processamento adicional da solicitação a fim de gerar uma
resposta personalizada. Algumas tecnologias para geração de conteúdo dinamicamente
são :
O CGI foi primeiro padrão para conteúdo da Web dinâmico. Ele é um protocolo de
comunicação que o servidor HTTP utiliza para conversação com outro programa. Um
CGI script é qualquer programa (PERL, C, Java) que se comunica com o servidor WEB
através do protocolo CGI. Um script CGI (como ficou conhecido este mecanismo) é um
programa que atende às requisições enviadas por um cliente e a ele repassadas pelo
servidor HTTP.
6
Um CGI tradicional possui algumas ineficiências que limitam sua aplicabilidade em
sistemas Web de grande escala. Uma delas deve-se ao fato de que um programa CGI
roda fora do servidor Web e não como um subprocesso do servidor. Dessa forma um
novo processo deve ser criado cada vez que um programa CGI precisa ser executado, o
que ocasiona um overhead considerável para o servidor. Outro problema é que os
programas de CGI são projetados para tratar de apenas uma única solicitação específica,
na qual um novo processo é criado, as informações da solicitação são enviadas para ele,
espera-se o processamento, a resposta é repassada de volta para o navegador e o
processo é finalizado. Com isso fica difícil, por exemplo, dois CGI’s compartilharem
recursos, o que otimizaria em muito a performance dos sistemas. É fácil imaginar os
problemas de performance ocasionados por este modelo num site que atenda a milhares
de solicitações simultâneas.
Para amenizar estes problemas, os novos sistemas para geração de conteúdo dinâmico
assumem a forma de módulos que alavancam as interfaces de programas aplicativos
específicos de servidor, a fim de interagir diretamente com o processo do servidor Web
como um subprocesso do mesmo, evitando assim muito do overhead associado aos
programas CGI convencionais.
APIs do Servidor
Podem substituir totalmente o CGI com vanta-gens
Melhor interação como servidor
Múltiplos clientes são atendidos por processos internos
(threads)
Muito mais rápidos e eficientes
Desvantagens
Em geral dependem de plataforma, fabricante e linguagem
Soluções proprietárias
Ex: ISAP (Microsoft), NSAPI (Netscape), etc
S e r v le t A P I
A P I in d e p e n d e n te d e p la ta f o r m a e p r a tic a m e n te
in d e p e n d e n te d e f a b r ic a n te
C o m p o n e n te s s ã o e s c r ito s e m J a v a e s e
c h a m a m S e r v le ts
C o m o o s c o m p o n e n te s S A P I p r o p r ie tá r io s ,
r o d a m d e n tr o d o s e r v id o r , m a s a tr a v é s d e u m a
M á q u in a V ir tu a l
D e s e n v o l v id o p e lo E S M S . C 11
7
Vantagens dos Servlets
... sobre CGI
Cada nova requisição inicia um novo thread, não um
novo processo
Mais integrado ao servidor, rodam como parte deste :
mais facilidade para compartilhar informações,
recuperar e decodificar dados enviados pelo cliente
... sobre APIs proprietárias
Não dependem de único servidor ou sistema
operacional
Têm toda a API Java à disposição
Servlets e JSP
Servlets são a alternativa Java para CGI Scripts e assim possuem todas as vantagens da
plataforma à sua disposição : APIs, multiplataforma, multithreading, OO. Sua
desvantagem é que tanto o conteúdo estático quanto o dinâmico residem no código
fonte do programa, o que acarreta sérios problemas de manutenção.
JSP é a combinação de HTML com Java dentro de uma mesma página (como ASP e
PHP), porém, usando-se tags especiais do tipo HTML que interagem com objetos java
no servidor, podemos introduzir conteúdo dinâmico em qualquer parte da página sem
necessidade que código Java bruto apareça. Em princípio, todo o código fora dos tags é
HTML puro. Isso possibilita gerar um código mais manutenível pois permite a
separação do código que se destina a apresentação (HTML e tags) do código
responsável por gerar o conteúdo dinâmico (tipicamente Java).
Execução de Servlets
Servidor Web (Host)
1 Container de Servlet
1
Cliente Servidor Web 2 - Carrega Servlet se
5
necessário
3 - Cria encadeamento que
4
vai processar solicitação
(thread)
4 - Thread executa, retorna
resultado e finaliza
8
Execução de Servlets/JSP
Uma página JSP é tipicamente convertida para um servlet quando de sua compilação,
por isso trataremos a forma de execução de ambos de forma indistinta.
Um servidor HTTP com suporte a servlets deve possuir um ServletEngine (container
servlet) que é o software responsável por executá-los. Este software corresponde a um
processo em Java separado do servidor HTTP rodando uma JVM e recebe todas as
solicitações para execução de um servlet/jsp.
3. Uma vez inicializado, o servlet estará apto a lidar com centenas de acessos
simultaneamente, disparando para cada acesso uma nova thread para atendê-lo
(encadeamento), ao invés de criar um novo processo. As threads são muito menos
custosas do que os processos convencionais, gerando um overhead muito menor
para sua criação e destruição. Elas compartilham a mesma memória que a do
processo pai e assim podem compartilhar recursos como conexões com banco de
dados, dentre outros.
9
Solução: scripts de servidor
Colocaa linguagem de programação dentro do
HTML (e não o contrário)
<h1>Servlet </h1>
<% for(int num=1; num <= 5 ; i++){ %>
<p>Parágrafo ” + num + </p> <%}%>
O Web designer pode projetar as páginas em
ferramentas como DreamWeaver
Página fica mais legível
Quando houver muita programação, código
pode ser escondido em servlets, JavaBeans, etc
Desenvolvido pelo ESMS.C 15
Scripts de servidor
Alguns dos mais populares:
Microsoft Active Server Pages (ASP)
Sun Java Server Pages (JSP)
Macromedia Cold Fusion
PHP
As páginas são processadas pelo servidor
apropriado que retorna apenas conteúdo HTML
para o cliente
PHP
É uma linguagem de script Open Source que disponibiliza suporte para uma vasta gama
de recursos como acesso a banco de dados, comunicação com servidores de diretório,
manipulação de arquivos, e-mail , dentre muitos outros.
10
Benefícios de JSP
JSP oferece diversos benefícios como um sistema para geração de conteúdo dinâmico.
Sendo uma tecnologia baseada em Java, ela se aproveita de todas as vantagens que a
linguagem Java fornece : orientação a objetos, tratamento de exceções, gerenciamento
automático de memória, dentre outros aspectos que conduz a um ganho significativo de
produtividade.
Pelo fato do bytecode de Java compilado ser portável através de todas as plataformas
que possuam uma JVM, o uso de JSP não o restringe a uma plataforma de hardware,
sistema operacional ou software específico (o que não é verdade com o ASP). Pelo fato
de JSP ser neutra a fornecedores, os desenvolvedores e arquitetos de sistemas podem
selecionar melhores soluções em todas as etapas de acionamento de JSP.
JSP pode se aproveitar de todas as APIs de Java padrão, incluindo aquelas para acesso a
bancos de dados compatíveis com muitas plataformas, serviços de diretório,
processamento distribuído, criptografia, etc.
11
Exemplo de um Servlet
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SimpleServlet extends HttpServlet{
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException,IOException{
PrintWriter out;
response.setContentType(“text/html”);
out = response.getWriter();
String user = request.getParameter(“usuario”);
if (user == null) user = “World”;
out.println(“<html><body>”);
out.println(“<h1>Simple Servlet Output</h1>”);
out.println(“<p>Hello, ” + user);
out.println(“</body></html>”); out.close(); }
Desenvolvido pelo ESMS.C 18
E x e m p lo d e u m J S P e q u iv a le n te
< h tm l> < b o d y >
<%
S tr i n g u s e r = r e q u e s t.g e tP a r a m e te r ( “ u s u a r io ” ) ;
if ( u s e r = = n u ll)
u s e r = “ W o r ld ” ;
%>
< h 1 > S im p le S e r v le t O u t p u t < /h 1 >
< P > H e llo , < % = u s e r % >
< /b o d y > < /h tm l>
D e s e n v o l v id o p e lo E S M S . C 19
12
C om o executar Servlets e JSP
Para executar Servlets e JSP é preciso im plantá-
los em um W eb C ontainer
U m W eb C ontainer pode estar executando com o
parte de um servidor H TT P que o repassa as
requisições destinadas a servlets e JSP
N este curso usarem os o Tom cat W eb C ontainer,
que pode tanto funcionar conectado a outro
servidor com o usar seu próprio servidor W eb
E m produção geralm ente é acoplado num
servidor de páginas estáticas eficiente
D esen volvid o p elo E SM S.C 21
Estrutura do Tomcat
C om o im plantar um a aplicação
no T om cat
H á três m aneiras
T ransferir os arquivos da aplicação (JSP, servlets)
para contextos já reconhecidos pelo servidor
C onfigurar um novo contexto (server.xm l)
Im plantar a aplicação com o um W ebA rchive(W A R )
C ontextos são diretórios devidam ente
configurados que o Tom cat reconhece com o
aplicações W eb
D ois contextos default: exam ples e R O O T
13
Como usar o contexto ROOT
Para usar o contexto ROOT:
Copie arquivos JSP, HTM L, imagens, etc em
$TOM CAT_HOM E/webapps/ROOT
Coloque beans, classes e servlets em
$TOM CAT_HOM E/webapps/ROOT/W EB-IN F/classes
Acesse páginas JSP usando
http://servidor:8080/
Acesse servlets usando
http://servidor:8080/servlet/
Desenvolvido pelo ESM S.C 24
Contextos
Contextos são quase a mesma coisa que
aplicações web
Definem a porta de entrada da aplicação
Cada nova aplicação requer um novo contexto
(server.xml)
No Tomcat os contextos estão definidos no
diretório webapps
Podemos criar novos contextos dentro do
webapps ou em qualquer outro diretório
Desenvolvido pelo ESM S.C 26
14
Contextos
Todo diretório de contexto tem uma estrutura
padrão
Diretório raiz (JSP, HTML, imagens, etc)
Diretório WEB-INF - possui um arquivo de
configuração padrão (web.xml)
O WEB-INF pode conter dois diretórios
reconhecidos pelo servidor
/WEB-INF/classes – onde ficam os servlets e classes
utilitárias
/WEB-INF/lib – onde ficam as bibliotecas JAR que serão
carregadas como parte da aplicação
Desenvolvido pelo ESM S.C 27
Configuração da Instalação
Para que um contexto possa inicializar corretamente,
deve haver um arquivo web.xm l no diretório W EB-
IN F do contexto.
O arquivo web.xm l configura inúm eros parâmetros
relacionados à aplicação
Inicialização de servlets
M apeamentos de nomes de servlets
Inicialização do contexto
Parâm etros de servlets
...
15
Exemplo de web.xml (1/3)
Parâmetro que pode ser lido por
<web-app> qualquer componente
<context-param>
<param-name>tempdir</param-name>
<param-value>/tmp</param-value>
</context-param> Instância de
um servlet
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>pacote.myServlet</servlet-class>
<init-param> Parâmetro que pode
<param-name>password</param-name> ser lido pelo servlet
<param-value>123456</param-value>
</init-param> Ordem para carga
<load-on-startup>1</load-on-startup> prévia do servlet
</servlet>
Desenvolvido pelo ESM S.C 30
16
II - Servlets
II - S erv lets
E ste c ap ítulo co b re o s se g u in tes tó pico s :
O q u e são S erv lets?
C iclo d e V ida
In icializaç ão
F in alização
M éto d o s de S erv iço
C o m o criar u m H T T P serv le t
C iclo d e V id a
Q u a n d o o se rv id o r rece b e u m a re q u isiç ão p o r
u m serv le t, ele a rep assa p ara o co n tain e r q u e :
C ria u m a in stân cia d a classe d o serv let
C h am a o m éto d o d e inicialização in it()
C a d a req u isição é tra ta d a p o r u m m éto d o
serv ic e()
O C o n tain e r cria u m ob je to d e re q u isição
(S erv le tR eq u est) e u m d e resp o sta
(S ertv letR esp o n se) e os p assa co m o p arâm etro
Q u a n d o o co n ta in er d ec id ir re m o v er o serv let d a
m e m ó ria e le o fin aliza ch am an d o d estro y()
D ese n vo lv id o p elo E S M S.C 36
17
Inicialização de um servlet
Tarefa realizada apenas um a vez
O perações com uns : carregar parâm etros de
inicialização, dados de configuração, etc
Ex: A cessa os parâm etros de
public void init () inicialização
throw s S ervletE xception{
S tring dirIm agens = getInitP aram eter(“im agens”);
if (dirIm agens == null) {
throw new U navailableE xception(‘C onfiguração
Incorreta’);
} }
D esen volvid o p elo E SM S.C 37
F in a liz a ç ã o
O m é to d o d e stro y () é c h a m a d o e p o d e se r
u sa d o p a ra lib e ra r re c u rso s, c o m o c o n e x õ e s
c o m b a n c o d e d a d o s , e tc
Ex:
p u b lic v o id d e stro y () {
b a n c o .c lo se ();
b a n c o = n u ll;
}
D e se n vo lv id o p e lo E S M S .C 37
Métodos de Serviço
São os métodos que implementam
operações de resposta executadas quando o
cliente envia uma requisição
Todos os métodos de serviço recebem dois
parâmetros: um objeto ServletRequest e
outro ServletResponse
Nos servlets HTTP estes métodos estão
divididos em doPost() e doGet()
18
Como criar um servlet HTTP
Crieuma classe que estenda de HttpServlet e
implemente um ou mais dos seus métodos de
serviço:
import javax.servlet.*;
import javax.servlet.http.*;
import javax.io.*;
public class ServletWeb extends HttpServlet {
public void doGet (HttpServletRequest request,
HttpServletResponse response)
throws IOException {
PrintWriter out = response.getWriter();
response.setContentType(“text/html”);
out.println(“<h1>Hello, World!</h1>”);
out.close();
}}
Desenvolvido pelo ESMS.C 39
C o m o u sa r d o G e t() e d o P o st()
U se d o G e t() p a ra re c e b e r re q u is iç õ e s
GET
L in k s c lic a d o s o u U R L d ig ita d a s
d ire ta m e n te
A lg u n s fo rm u lá rio s q u e u sa m G E T
U se d o P o st() p a ra re c e b e r d a d o s d e
fo rm u lá rio s
O JS P tra ta in d isc rim in a d a m e n te o s d o is
m é to d o s
D e se n v o lv id o p e lo E S M S .C 40
19
Como gerar uma resposta
Primeiro é preciso obter de response um fluxo
de saída
Writer out = response.getWriter();
Deve-se também definir o tido de dados a ser
gerado. Isso é importante para que o browser
saiba exibir as informações
response.setContentType(“text/html”);
Depois, pode-se gerar os dados imprimindo-os
no objeto de saída (out) obtido anteriormente
out.println(“<h1>Hello, world!</h1>”)
Desenvolvido pelo ESMS.C 42
Exercícios
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
}
}
20
e) Vamos agora configurar o arquivo web.xml com o servlet hello acrescentando o
parâmetro de inicialização que este está lendo. Acrescente as seguintes linhas no /WEB-
INF/web.xml:
<servlet>
<servlet-name>
hello
</servlet-name>
<servlet-class>
hello
</servlet-class>
<init-param>
<param-name>nome</param-name>
<param-value>SEUNOME</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/servlet/hello</url-pattern>
</servlet-mapping>
f) Uma vez tendo alterado o arquivo web.xml, você deve fazer um reload no contexto.
Para isso o Tomcat disponibiliza uma página de gerenciamento que pode ser acesada em
http://servidor:8080/manager/html. Entre nesta página, procure pelo seu contexto e
clique em reload.
http://servidor/contexto/servlet/hello?nome=<SEUNOME>
21
III - Scripts JSP
Este capítulo cobre os seguintes tópicos :
Vimos que é possível utilizar JavaBeans para mantermos a separação entre apresentação
e implementação e as vantagens que isso proporciona, principalmente em grandes
projetos. No entanto, esta abordagem “purista” para o desenvolvimento de JSP nem
sempre é a mais adequada para todos os casos. Para páginas simples, que precisam ser
implementadas em curto espaço de tempo, talvez seja melhor uma abordagem mais
direta e prática.
Neste capítulo, mostraremos como criar páginas JSP que mesclam HTML e código Java
para obtenção do conteúdo dinâmico. Estes códigos são denominados scripts e, apesar
de JSP permitir linguagens alternativas para criá-los, focaremos aqui exclusivamente em
scripts na linguagem Java.
22
Hello World !
Para quebrar o gelo, vamos analisar nossa
primeira página JSP. Ela lê um parâmetro da
solicitação e utiliza seu valor para apresentar
uma mensagem na tela.
<html>
<body>
<h1> <%= request.getParameter("text") %> </h1>
</body>
</html>
Para construir uma página usando JSP, você geralmente escreve o texto HTML
normalmente e inclui o código entre as tags JSP. As tags normalmente começam com
"<%" e terminam com "%>". Vamos mostrar uma possibilidade de implementação para
o clássico exemplo do "Hello World” :
Ex. helloworld.jsp :
<html>
<body>
</body>
</html>
<html>
<body>
</body>
</html>
O que aconteceu foi que o servidor JSP executou os comandos entre as tags especiais
"<%" e "%>", gerou e enviou para o browser um código puramente HTML.
23
Declarações
• Servem para definir variáveis e métodos
específicos para uma página JSP
• Sua sintaxe é : <%! declarações %>
• Os métodos e variáveis declarados podem
ser referenciados por outros elementos de
criação de script dentro da mesma página
JSP independente da ordem na qual a
declaração ocorre em relação a estes
elementos
Desenvolvido pelo ESMS.C 9
Declarações
• Declaração de variáveis :
<%! int x=0, y; String text = “Texto”; %>
• Declaração de métodos :
<%! int soma (int x, int y) { return (x + y); } %>
• As variáveis aqui declaradas são criadas na
inicialização da página e seus valores são
compartilhados por todos que a acessarem.Se
uma pessoa mudar o valor de x para 1, todos
que acessarem o servlet depois disso verão x=1
Desenvolvido pelo ESMS.C 10
Estes são métodos especiais para tratar os eventos de inicialização (jspInit) e finalização
(jspDestroy) dos servlets. Se o método jspInit() for definido, pode-se garantir que o
container JSP o chame depois que a classe de servlet tenha sido instanciada, mas antes
que a primeira solicitação seja processada. Similarmente, se o método jspDestroy()
estiver definido numa página JSP, este será executado quando o container JSP precisar
descartar a classe de servlet, seja porque o container está sendo desligado, ou porque a
página não tenha sido solicitada recentemente e o container precisa liberar recursos (ex.
memória). O formato geral para declará-los é :
24
Expressões
• O resultado da avaliação de uma expressão
é inserido no output da página no lugar da
tag de expressão original
• Sua sintaxe é : <%= expressão %> (não
requer ; no final)
• Não há restrição quanto ao tipo de retorno
das expressões
• Exs:<%= “Mensagem” %> --> imprime : Mensagem
<%= msg %> --> imprime o conteúdo da var. msg
<%= fatorial(0) %> --> imprime o resultado da func
Desenvolvido pelo ESMS.C 11
As declarações são usadas para adicionar variáveis e métodos a uma página JSP, mas
não são capazes de contribuir diretamente para o output da página. As expressões em
JSP possuem o objetivo explícito de geração de output.
Exemplo :
Neste exemplo, hours é verificada para determinar se é menor que 12. Se sim, o
operador terciário retorna a cadeia “AM”, caso contrário retorna “PM”. O valor
retornado é adicionado ao output da página.
25
Scriptlets
• São blocos de código executados cada vez
que a página JSP é processada
• Servem para criação de scripts de objetivos
gerais
• Sua sintaxe é : <% scriptlet %>
• Uma variável definida num scriptlet estará
disponível para uso em expressões e
scriptlets subseqüentes na mesma página
Os scriptlets são utilizados para criação de códigos arbitrários, que realizam qualquer
processamento que se queira. Dentro de uma tag de scriptlet é possível declarar
variáveis, instanciar objetos, imprimir no output da página, enfim, realizar qualquer
codificação válida com a linguagem de script que está sendo utilizada, no nosso caso
Java.
1 - <html>
2 - <body> <h1>Intruder Alert</h1>
3 - <% GameGrid grid = GameGrid.getGameGrid();
4- Recognizer r1 = new Recognizer (grid,0,0);
5- Recognizer r2 = new Recognizer (grid,100,100);
6- r1.findProgram (“Flynn”);
7- r2.findProgram (“Flynn”); %>
8 - <h2> Status </h2>
9 - <ul>
10 - <li> Recognizer : <%= r1.statusReport() %>
11 - </ul>
12 - Alert Level : <%= grid.alertLevel() %>
13 - </body>
14 - </html>
Misturado ao código HTML temos o código Java. Na linha 3 a variável grid recebe uma
instância da classe GameGrid retornada pelo método getGameGrid(). Nas linhas 4 e 5
novas instâncias da classe Recognizer são criadas e atribuídas às variáveis r1 e r2.
Como os scriptlets são executados toda vez que a página é solicitada, novas instâncias
dessa classe são criadas e atribuídas a r1 e r2 a cada nova solicitação. Na linha 10 uma
tag de expressão é utilizada para imprimir o retorno do método statusReport() executado
a partir da variável r1. Só foi possível acessar r1 na linha 10 porque ele foi declarado
num scriptlet anterior a este ponto.
26
Exercícios
1 – Criar uma página JSP que possua uma variável soma, do tipo inteiro, inicializada
com 0 e definida numa tag de declaração. Incrementar essa variável de 10 cada vez que
a página for solicitada e imprimir o seu conteúdo. Criar uma outra variável sub, também
do tipo inteiro, inicializada com 100 e declarada dentro de um scriptlet. Essa variável
deve ser subtraída de 10 cada vez que a página for solicitada. Explique qual está sendo o
comportamento das variáveis após solicitações simultâneas da página e o motivo do
mesmo.
2 – Fazer uma página JSP que receba dois números reais (double) como parâmetros
(num e porcent) e execute um método que calcule a porcentagem porcent de num
retornando também um double. O resultado deve ser impresso na tela.
3 – Fazer uma página JSP que recebe um número inteiro como parâmetro, calcule seu
fatorial através do método fatorial e imprima o resultado na tela. O método fatorial pode
ser como descrito abaixo :
if (x == 0) return 1
else return x * fatorial (x-1) ; }
Dica : Para converter uma String para um número inteiro utilizar : Integer.parseInt
(“string”)
27
Embora já possamos escrever algumas aplicações em JSP com o que já aprendemos até
agora, elas serão ainda fracas. Um dos grandes potenciais de qualquer linguagem de
programação é a utilização de controles de fluxo (condicionais e loops) para executar
diferentes partes de um programa baseado em testes. Nas próximas páginas
aprenderemos os seguintes tópicos:
• Comandos condicionais;
• Comandos de loops
Controle de Fluxo
• Comandos Condicionais : IF
<html> <body>
<% java.util.Date dateNow = new java.util.Date();
int hourNow = dateNow.getHours(); %>
<% if ((hourNow >= 5) && (hourNow < 13)) { %>
<font face="verdana">Bom Dia!!!</font>
<% } else if ((hourNow >= 13) && (hourNow < 19)) { %>
< font face="verdana">Boa Tarde!!!</font>
<% } else if ((hourNow >= 19) && (hourNow < 24)) { %>
<font face="verdana">Bom Noite!!!</font>
<% } else { %>
<font face="verdana">Boa Madrugada!!!</font>
<% } %>
</body></html>
Desenvolvido pelo ESMS.C 15
Controle de Fluxo
• Comandos Condicionais : switch
<html> <body>
<% java.util.Date dateNow = new java.util.Date();
int monthNow = (dateNow.getMonth()+1); %>
<% String mes;
switch (monthNow){
case 1: mes="Janeiro"; break;
case 2: mes="Fevereiro"; break;
...
case 10: mes="Outubro"; break;
case 11: mes="Novembro"; break;
default: mes="Dezembro"; break;
} %>
<font face="verdana"> Nós estamos em <%= mes %></font>
</body></html>
Desenvolvido pelo ESMS.C 16
28
Na instrução switch, o teste (um tipo primitivo de byte, char, short ou int) é comparado
com cada valor em questão. Se um valor coincidente é achado, a instrução (ou
instruções) depois do teste é executada. Se nenhum valor for encontrado, a instrução
default é executada (exemplo no arquivo switch.jsp).
Controle de Fluxo
• Comandos de loops : for
<html>
<body>
<% for (int i = 2; i < 8 ; i++) { %>
<font size = <%= i %> > Bom Dia!!! - Fonte: <%= i %>
</font>
<% } %>
</body>
</html>
Onde:
initialization - é uma expressão que inicia o começo do loop;
test - é o teste que ocorre depois de cada passo do loop;
increment - é qualquer chamada de expressão ou função.
29
Controle de Fluxo
• Comandos de loops : while
<html>
<body>
<% int i = 0;
while (i < 8) { %>
<font size = <%= i %>> Bom Dia!!! - Fonte: <% = i %>
</font> <br>
<% i++; } %>
</body>
</html>
O loop while (exemplo no arquivo while.jsp) é usado para repetir uma instrução ou
bloco de instruções até que uma condição particular seja verdadeira. Loops while se
parecem com o seguinte:
while ( condition) {
bodyOfLoop
Observe que se a condição é inicialmente falsa na primeira vez que é testada o corpo do
loop while nunca será executado. Se você precisa executar o corpo, pelo menos uma
vez, você pode usar o código do..while que será visto a seguir.
Controle de Fluxo
• Comandos de loops : do while
<html>
<body>
<% int i = 0;
do { %>
<font size=<%= i %>>Bom Dia!!! - Fonte: <%= i %>
</font> <br>
<% i++;
} while ( i < 8 ); %>
</body></html>
30
O loop é exatamente como o loop while, exceto pelo fato de o loop do executar uma
dada instrução ou bloco até que uma condição seja falsa. A diferença principal entre os
dois é que os loops while testam a condição antes de iniciar o loop, tornando possível
que o corpo do loop nunca seja executado caso a condição seja inicialmente falsa. Os
loops do...while executam pelo menos uma vez antes de testar a condição (exemplo no
arquivo do_while.jsp)
do {
bodyOfLoop
}
while ( condition );
Interrupção de Loops
Em todos os loops (for, while e do), o loop termina quando a condição que você está
testando é atingida. Porém, em algumas situações você desejará sair do loop antes do
seu término normal. Para isso, você pode usar as palavras chaves break e continue.
Controle de Fluxo
• Interrupção de loops : break
<html>
<body>
<% int j;
for (int i = 1; i < 8 ; i++) {
j = i%5; => j recebe o resto da divisão por cinco
if (j == 0){ break; } %> => se for 0 é divisível por 5 e pára
<font size= <%= i %>> Bom Dia!!! - Fonte: <%= i %>
</font> <br>
<% } %>
</body></html>
Desenvolvido pelo ESMS.C 20
No exemplo acima, o código dentro do loop é executado até que a variável i assuma um
valor que seja divisível por 5. Quando isso ocorre, o loop é finalizado e o programa
continua a ser executado após o final do código do loop (exemplo no arquivo break.jsp).
31
Controle de Fluxo
• Interrupção de loops : continue
<html>
<body>
<% int j;
for (int i = 1; i < 8 ; i++) {
j = i%5;
if (j == 0){ continue; } %> => quando i for divisível por 5,
a linha não será impressa
<font size=<%= i %>>Bom Dia!!! - Fonte: <%= i %>
</font><br>
<% } %>
</body>
</html>
Desenvolvido pelo ESMS.C 21
Comentários
• Dois tipos de comentários :
– Conteúdo : é quando utilizamos o comentário
HTML dentro da página JSP.
• Ex : <!-- Comentário sobre o conteúdo de x = <%=
x %> -->
– JSP : O corpo deste comentário é ignorado.
Serve principalmente para depuração.
• Ex : 5! = <%= fact(5) %> <br>
<%-- 6! = <%= fact(6) %> <br> --%>
• Comentário da linguagem de script utilizada. No
caso de java : /* comentário */ ou // comentário
Desenvolvido pelo ESMS.C 22
Comentários JSP: não são enviados para o cliente e são visíveis apenas nos arquivos
fonte JSP originais. O corpo do comentário é ignorado pelo container JSP.
32
Exercícios :
4 – Faça uma página JSP que receba como parâmetro um número inteiro e calcule o
fatorial de 0 até este número e imprima os resultados. (Utilize o método para calcular
fatorial dado no exercício 3)
5 – Faça uma página que receba o valor de um salário e uma porcentagem como
parâmetros. Calcule a porcentagem especificada sobre o salário, a qual representa um
aumento do mesmo, utilizando a função func criada no exercício 2. Se o resultado for
menor que R$ 400,00 , imprima “Você recebeu um aumento de <aumento> ! Teu
emprego é um lixo, sai logo daí !”, se o resultado for maior que R$ 400,00 e menor que
R$ 2.999,99, imprima “Você recebeu um aumento de <aumento> ! Até que teu emprego
não é ruin não.”, mas se o resultado for superior a R$ 2.999,99 imprima “Seu novo
salário é de <novo_salario> ! Você é político ?”.
6 – Faça uma página JSP que receba três números inteiros como parâmetros : min, max
e div. Deve ser impresso os números de min a max na tela até que se encontre neste
intervalo um número divisível por div e então o laço deve ser interrompido. Se nenhum
número for encontrado, todos os números entre min e max (inclusive) serão impressos.
33
O último tópico que veremos neste capítulo trata das diretivas JSP. As diretivas são
usadas para fornecer informações especiais ao container JSP sobre a página quando esta
é compilada para servlet. Elas não produzem qualquer output que seja visível, ao invés
disso, elas geram efeitos colaterais que mudam o modo que o container JSP processa a
página. Existem dois tipos principais de diretivas: page e include.
Diretivas JSP
• As diretivas são usadas para fornecer
informações especiais ao container JSP
sobre a página quando esta é compilada
para servlet. Elas não produzem qualquer
output que seja visível, ao invés disso, elas
geram efeitos colaterais que mudam o modo
que o container JSP processa a página.
• Dois tipos : page e include
Diretivas JSP
• Diretiva page : define atributos que afetam
toda a página JSP
• Sintaxe :
<%@ page attribute1=“valor1” attribute2 =
“valor2” attribute3= ... %>
ou
<%@ page attribute1 = “valor1” %>
<%@ page attribute2 = “valor2” %> ...
Desenvolvido pelo ESMS.C 24
34
Diretivas JSP
• Atributos da diretiva page :
– info : Permite ao autor adicionar uma cadeia de
documentação à página que sumariza sua
funcionalidade. O valor padrão para o atributo
info é a cadeia vazia. Pode ser recuperada pelo
método getServletInfo.
– Ex :
<%@ page info = “Controle de usuários,
Copyright 2002 by ESMS.C” %>
Desenvolvido pelo ESMS.C 25
Diretivas JSP
• Atributos da diretiva page :
– language : Define a linguagem de criação de
scripts da página. O padrão para este atributo é
java.
– Ex :
<%@ page language = “java” %>
35
Diretivas JSP
• Atributos da diretiva page :
– contentType : Define o tipo MIME, i.e, o tipo
de informação contida em uma resposta de
HTTP. Os tipos mais comuns para JSP são :
“text/html” (padrão), “text/xml” e “text/plain”,
indicando respostas em HTML, XML e texto.
– Ex :
<%@ page contentType = “text/xml” %>
Diretivas JSP
• Atributos da diretiva page :
– extends : Identifica a super classe a ser usada
pelo container quando ele está traduzindo a
página JSP em um servlet Java. Geralmente
deixamos o próprio container selecionar a super
classe para a página pois isso tipicamente
fornece a melhor peformance.
36
Diretivas JSP
• Atributos da diretiva page :
– import : Permite especificar quais pacotes
serão importados, estendendo assim o conjunto
de classes que podem ser referenciadas em uma
página. É o único atributo que pode se repetir.
– Ex :
<%@ page import = “java.util.List” %> => importa
a classe List
<%@ page import = “java.util.* , java.text.*” %> =>
importa todas as classes do pacote java.util e
java.text
Desenvolvido pelo ESMS.C 29
Diretivas JSP
• Atributos da diretiva page :
– session : Indica se uma página participa ou não
do gerenciamento de sessão. O valor padrão é
true. Se a página não irá utilizar recursos de
sessão, deve-se passá-lo para false pois isso
resulta em ganho de performance.
– Ex :
<%@ page session = “false” %>
37
Diretivas JSP
• Atributos da diretiva page :
– buffer : Controla o uso da saída bufferizada. O
padrão é um buffer de 8kb.
– Ex :
<%@ page buffer=“none” %> => sem buffer
Saída bufferizada
Uma vez que o servidor HTTP tenha começado a enviar um documento para um
navegador, ele não pode “mudar de idéia” e depois pedir para o navegador não exibir o
conteúdo enviado. O servidor Web poderia cancelar a transmissão do documento, mas o
navegador exibiria qualquer conteúdo recebido até então. Se, a medida que uma
página JSP fosse sendo processada o conteúdo HTML gerado fosse enviado
diretamente para o servidor Web, para este encaminhar a resposta para o
navegador, ocorreriam problemas como :
• Numa página HTML todo o cabeçalho (de solicitação e de resposta) deve vir antes
que o corpo da página. Nos cabeçalhos de respostas são definidas informações como
armazenamento em cache da página e, mais importante, dados de cookies. Se uma
página JSP quisesse definir cookies, teria que defini-los antes que qualquer output
de JSP fosse gerado para ser enviado como corpo da resposta, ou seja, no início da
página. Se quiséssemos por algum motivo gerar conteúdo do corpo e depois definir
um cookie, seria muito tarde
• Outro problema está relacionado a erros de processamento. Se um erro ocorreu no
meio do processamento de uma página, todo conteúdo gerado antes daquele
momento apareceria no navegador seguido da mensagem de erro. Não seria possível
descartar o output anterior e exibir apenas a mensagem de erro, ou encaminhar o
controle para uma página especial de tratamento de erros.
Caso o atributo esteja definido como false, quando o buffer fica cheio o container irá
disparar uma exceção e exibirá uma página de erro no navegador que solicitou a página.
Diretivas JSP
• Atributos da diretiva page :
– isThreadSafe : Quando definido para true (o
padrão), um novo encadeamento é criado para
tratar de cada solicitação para a página, de
modo que múltiplas solicitações para a página
sejam tratadas simultaneamente. Caso seja
false, o container irá reponder a cada solici-
tação sequencialmente, na ordem em que foram
recebidas.
– Ex : <%@ page isThreadSafe=“true” %>
39
O atributo isThreadSafe é usado para indicar se uma página é capaz de responder a
múltiplas solicitações simultâneas. Quando é definido para false, o container JSP
expedirá solicitações destacadas para a página sequencialmente, na ordem em que elas
foram recebidas, esperando a solicitação atual terminar seu processamento antes de
iniciar o próximo. Quando estiver definido para true (o padrão), um novo encadeamento
(uma nova thread) é criado para tratar de cada solicitação para a página, de modo que
múltiplas solicitações sejam tratadas simultaneamente.
Se for possível, este atributo deve estar definido para true, caso contrário, a performance
sofrerá dramaticamente sempre que múltiplos usuários tentarem acessar a página ao
mesmo tempo, já que cada usuário terá que esperar até que todas as solicitações
anteriormente submetidas tenham sido atendidas antes que o processamento da sua seja
iniciado. Se a página estiver com tráfego muito pesado, ou sua geração de conteúdo for
muito intensa em relação ao processamento, esta espera provavelmente não será
aceitável pelos usuários.
Para saber de forma prática se uma página pode estar com este atributo definido como
true, tenha em mente o seguinte :
• Vimos que o container JSP cria threads para tratar de solicitações a uma página e
que threads referentes ao mesmo servlet compartilham espaço de memória. Isso
pode ser utilizado vantajosamente para fins de melhoria de performance.
• A memória compartilhada é aquela definida pelas variáveis declaradas dentro da
tag <%! %> e, uma vez que seu valor tenha sido modificado, o novo valor será
visível a todas as threads do mesmo servlet. Variáveis definidas dentro de
scriptlets são locais a cada thread.
• A definição de variáveis compartilhadas deve ser feita com critério, pois a
seguinte situação pode ocorrer : imagine que X seja uma variável compartilhada
e que João submeteu o valor 10 para X. No final desta página existe o seguinte
código : <%= X %>, que deve imprimir o conteúdo de X submetido por João.
Antes que a thread que estava tratando da solicitação de João terminasse seu
processamento (e imprimisse o valor de X), Pedro faz um acesso a essa mesma
página submetendo o valor 20 para X. Suponha então que o sistema operacional
(que é o responsável por definir qual thread estará ocupando o processamento
num dado instante) pára o processamento da thread de João e coloca a de Pedro
no lugar. A thread de Pedro muda o valor de X para 20, ocupa o processador por
um tempo e então é retirada pelo sistema operacional que recoloca a thread de
João para terminar seu processamento. Quando a thread de João chega no
comando para imprimir o conteúdo de X, irá imprimir 20 e não 10 como havia
submetido João, causando um resultado errôneo.
Para resolver este tipo de inconsistência, pode-se passar o atributo isThreadSafe para
false, pois assim garante-se que cada thread seja processada até o seu término antes que
outra ganhe o direito de processamento, porém, como já vimos, perde-se totalmente as
otimizações de performance do container . O mais indicado é utilizar recursos como o
synchronized quando houver o potencial para inconsistências, ou ainda, considerar a
possibilidade de definir a variável como local (dentro de um scriptlet).
40
Diretivas JSP
• Atributos da diretiva page :
Diretivas JSP
• Atributos da diretiva page :
Diretivas JSP
• Diretiva include : Permite incluir o
conteúdo de um arquivo em outro. A
diretiva tem o efeito de substituir a si
mesma pelo conteúdo do arquivo indicado.
• O conteúdo pode ser texto estático (HTML)
ou comandos JSP, que serão processados
como se fossem parte da página original.
• Ex : <%@ include file=“localURL” %>
41
Desenvolvido pelo ESMS.C 36
Exercícios :
<%!
//classe que implementa um pool de conexões para um banco de dados
DBConectionPool pool = new DBConectionPool();
//a variável con representa uma conexão para um banco de dados
Conection con = pool.getConection();
//classe que implementa as operações de inserção, deleção e update nas tabelas
DBComands comandos = new BDComands(con);
<%
Nome = request.getParameter(“nome”);
CPF = request.getParameter(“cpf”);
RG = request.getParameter(“rg”);
Comandos.Insert(Nome,CPF,RG,”EMPREGADO”);
%>
7 – As variáveis pool e con deveriam estar declaradas dentro do scriptlet ? Por quê ?
9 – Caso possa ocorrer algum problema, que mudanças deveriam ser feitas na página
para evitá-lo.
10 – Faz sentido ter uma variável compartilhada sendo que seu valor está relacionado
com os dados específicos de um usuário ?
11 – Crie uma página com o atributo buffer = “1kb” e o atributo autoFlush = “false”.
Primeiramente, faça com que ela imprima apenas uma vez a frase “Testando a
bufferizacao !” e a execute. Agora modifique-a para que ela imprima a mesma frase
1000 vezes e a execute novamente. Explique o resultado da primeira e da segunda
execução relacionando-o ao buffer.
42
IV – Objetos Implícitos
Este capítulo cobre os seguintes tópicos :
− Objetos Implícitos
− Relacionados a Servlets
− Relacionados ao Input/Output
− Contextuais
− Tratamento de Erros
− Ações
Os nove objetos implícitos fornecidos por JSP podem ser classificados da seguinte
forma:
• objetos relacionados ao servlet da página (page, config) : Os dois objetos
implícitos de JSP nesta categoria se baseiam na implementação da página JSP como
um servlet.
• objetos relacionados ao output e input da página (request, response, out) : Os
objetos classificados nessa categoria se concentram na entrada e saída (input/output)
de uma página JSP.
• objetos contextuais (application, session, pageContext) : Os objetos implícitos
dessa categoria fornece à página JSP acesso ao contexto dentro do qual ela está
respondendo.
• objetos resultantes de erros (exception) : Esta última categoria dos objetos
implícitos fornece apenas um objeto que é usado no tratamento de erros dentro de
uma página JSP.
43
Objetos Relacionados a Servlets
• Objeto page : O objeto page representa a
própria página JSP ou, mais
especificamente, uma instância da classe de
servlet na qual a página foi traduzida.
• Ex :
<%@ page info="Página de Teste" %>
Page Info :
<%= ( (javax.servlet.jsp.HttpJspPage)page).getServletInfo()
%>
Esta expressão irá imprimir o valor da cadeia de documenta-
ção da página
Desenvolvido pelo ESMS.C 38
44
Objetos Relacionados a Input/Output
45
Diversos métodos da interface que javax.servlet.hhtp.HttpServletRequest:
Método Descrição
Retorna o método de HTTP (e.g, POST, GET, etc) para a
String getMethod()
solicitação.
String getRequestURI() Retorna o URL de solicitação (não inclui a cadeia de consulta).
Retorna a cadeia de consulta que segue o URL de solicitação, se
String getQueryString()
houver algum.
Recupera os dados da sessão para a solicitação (i.e, o objeto
HttpSession getSession()
implícito session).
Recupera os dados da sessão para a solicitação (i.e, o objeto
HttpSession getSession(boolean flag)
implícito session), opcionalmente criando-o se ele ainda não existir.
RequestDispatcher
Cria um dispatcher de solicitação para o URL local indicado.
getRequestDispatcher(String path)
Retorna o nome totalmente qualificado do host que enviou a
String getRemoteHost()
solicitação.
String getRemoteAddr() Retorna o endereço de rede (IP) do host que enviou a solicitação.
String getRemoteUser() Retorna o nome do usuário que enviou a solicitação, se conhecido.
Exemplo :
<html>
<body>
<h2> Alguns Métodos do Objeto Ímplicito Request </h2>
<br><b>Valor do parâmetro Nome:</b> <%= " "+request.getParameter("nome") %>
<br><b>Valor do parâmetro Idade: </b> <%= " "+request.getParameter("idade") %>
<br><b>URL:</b> <%=" "+ request.getRequestURI()%>
<br><b>Cadeia de consulta:</b> <%= " " + request.getQueryString() %>
<br><b>Cliente:</b> <%= " " + request.getRemoteHost() %>
<br><b>Host da URL:</b ><%= " "+ request.getServerName() %>
</body>
</html>
http://.../request.jsp?nome=MARIA&idade=60
46
O objeto response representa a resposta que será enviada de volta para o usuário como
resultado do processamento da página JSP. Este objeto implementa a interface
javax.servlet.http.HttpServletResponse que é uma subinterface de
javax.servlet.ServletResponse. Podemos dividir os métodos desse objeto em quatro
funcionalidades :
Reescrita da URL:
Método Descrição
Codifica um URL para uso com o método sendRedirect() para
String encodeRedirectURL(String url)
incluir informações de sessão.
Codifica um URL usado em um link para incluir informações de
String encodeURL(String url)
sessão.
Exemplo 1 :
<% response.setDateHeader("Expires",0);
response.setHeader("Pragma","no-cache");
if(request.getProtocol().equals("HTTP/1.1"))
{
response.setHeader("Cache-Control","no-cache");
}
%>
47
Este scriplet define vários cabeçalhos para evitar que a página seja armazenada em
cache por um navegador.
Primeiro é definido o cabeçalho Expires para uma data no passado. Isto indica para o
navegador que o conteúdo da página já expirou, desta forma, não sendo armazenado em
cache.
O valor no-cache para o cabeçalho Pragma é fornecido pela versão 1.0 do protocolo
HTTP para especificar que os navegadores e servidores proxy não devem armazenar em
cache uma página.. A versão 1.1 de HTTP substitui este cabeçalho por um cabeçalho
Cache-Control mais específico, mas recomenda a inclusão do cabeçalho Pragma
também, para compatibilidade retroativa. Portanto, se a solicitação indicar que o
navegar (ou o servidor proxy) aceita HTTP 1.1, ambos os cabeçalhos são enviados.
<html>
<head>
<title>
Response
</title>
</head>
<body>
<h1>Exemplo de utilização do objeto response.</h1>
<% response.sendError(401,"Esta página não contém erro algum, mas como foi
configurado no cabeçalho um código de erro o browser interpreta como se
houvesse ! "); %>
</body>
</html>
48
Objetos Relacionados a
Input/Output
• Objeto out: representa o fluxo de saída para
a página, cujo conteúdo será enviado para o
navegador como o corpo de sua resposta.
• Utilizando este objeto, é possível gerar
output dentro do corpo de um scriptlet sem
ter que temporariamente fechar o scriptlet
para inserir conteúdo estático ou tags de
expressões (<%= expressão %>) JSP.
• Principais métodos : print() e println()
Desenvolvido pelo ESMS.C 50
Este objeto implícito representa o fluxo de saída para a página, cujo conteúdo será
enviado para o navegador com o corpo de sua resposta. O objeto out é uma instância da
classe javax.servlet.jsp.JspWriter. Vejamos o exemplo abaixo (arquivo out.jsp) :
Exemplo sem o uso do objeto out: Exemplo com o uso do objeto out:
<html><body>
<html><body>
<p> Asteriscos gerados fora do <p> Asteriscos gerados no scriplet:
scriplet: <%
<% int qt = 0;
int qt = 0; while (qt < 5){
while (qt < 5){ qt ++;
qt ++; %> out.print("*");
* }
<% } %> out.print(“<br> Foram gerados” +
<br> qt + “asteriscos”
<%= "Foram gerados " + qt + " %>
asteriscos.” %>
</body> </html> </body> </html>
Desenvolvido pelo ESMS.C 51
Esse objeto é muito utilizado para gerar conteúdo dentro do corpo de um scriptlet, sem
ter que fechá-lo temporariamente para inserir conteúdo de página estático ou tags de
expressão. Contudo, deve-se evitar usar os métodos print() ou println() (imprime
acrescentando um \n no final) para inserir cadeias de caracteres muito grandes. No
próximo caso, é mais aconselhável fechar o script e inserir o conteúdo estático. Veja o
exemplo abaixo:
49
Não Aconselhável: Aconselhável:
<% <%
if(i == 1){ if(i == 1) { %>
out.print("<h6>"+ <h6>
"<font face='verdana'>"+ <font face='verdana'>
"Guga viaja nesta sexta"+ Guga viaja nesta sexta
"para a Suíça para"+ para a Suíça para
"jogar"+ jogar
"</font>"+ </font>
"</h6>"); </h6>
} %> <% } %>
Objetos Contextuais
• Os objetos implícitos dessa categoria
fornecem à página JSP acesso ao contexto
dentro do qual ela está respondendo. Os três
objetos implícitos contextuais são:
– session
– application
– pageContext
Os objetos implícitos nesta categoria fornecem à página JSP acesso ao contexto dentro
do qual ela está sendo processada. O objeto session, fornece o contexto para a
solicitação à qual a página está respondendo. Que dados já foram associados com o
usuário individual que está solicitando a página ? O objeto application fornece o
contexto no servidor dentro do qual a página está rodando. Já o objeto page-Context se
concentra no contexto da própria página JSP, fornecendo acesso programático a todos
50
os outros objetos implícitos. A tabela a seguir traz os métodos comuns aos quatro
objetos e que são usados para armazenar e recuperar valores de atributos :
Os métodos comuns a esses três objetos, bem como ao objeto request, e que são usados
para armazenar e recuperar valores de atributos, estão resumidos na tabela 1:
Tabela 1
Método Descrição
void setAttribute(String key, Object value) Associa um valor de atributo com um nome.
Enumeration getAttributeNames() Recupera os nomes de todos os atributos associados com o objeto.
Object getAttribute(String key) Recupera o valor de atributo associado com a chave.
void removeAttribute(String key) Remove o valor de atributo associado com a chave.
Objetos Contextuais
• Objeto session : Representa a sessão atual
de um usuário individual.
• Persiste enquanto o usuário estiver intera-
gindo com a página
• Depois de um certo período de inatividade a
sessão expira
• Principais métodos :
– setAttribute (nome, objeto)
– getAttribute (nome)
Desenvolvido pelo ESMS.C 52
<%
session.setAttribute("nome", request.getParameter(“nome”));
session.setAttribute(“senha”, request.getParameter(“senha”))
%>
Uma vez que um objeto tenha sido armazenado através do método setAttibute(), ele
pode ser recuperado - na mesma página ou em outra acessada pelo usuário. O código
abaixo ilustra a recuperação do objeto armazenado no código anterior:
<%
String nome = (String) session.getAttribute("nome");
String senha = (String) session.getAttribute("senha");
.....
%>
51
Perceba que o método getAttribute() retorna um objeto da classe Object, portanto, é
necessário fazermos um cast para converter o objeto retornado em uma instância da
classe desejada.
O objeto session implementa a interface javax.servlet.http.HttpSession. A tabela
abaixo traz os principais métodos utilizados por esse objeto, além daqueles descritos
anteriormente:
Método Descrição
Object getAttibute(String nome) Recupera o objeto identificado por "nome".
String getId() Retorna o Id da sessão.
long getCreationTime() Retorna a hora na qual a sessão foi criada.
long getLastAccessedTime() Retorna a última vez que uma solicitação associada com a sessão foi recebida.
Retorna o tempo máximo (em segundos) entre solicitações pelo qual a sessão
int getMaxInactiveInterval()
será mantida.
void setMaxInactiveInterval(int Define o tempo máximo (em segundos) entre solicitações pelo qual a sessão
time) será mantida.
boolean isNew() Retorna se o navegador do usuário ainda não tiver confirmado o ID de sessão.
boolean invalidate() Descarta a sessão, liberando quaisquer objetos armazenados como atributos.
Objetos Contextuais
• Objeto application : Representa a aplicação
à qual a página JSP pertence. Ex:
• http:\\server\jsp_dev\index.jsp
• http:\\server\jsp_dev\principal.jsp
• http:\\server\jsp_dev\tutorial\tutorial.jsp
• Seus métodos retornam informações sobre o
container, acessam recursos no servidor,
fornecem suporte a log e, principalmente ,
fornecem acesso a parâmetros de inicia-
lização da aplicação como um todo.
Desenvolvido pelo ESMS.C 54
Este objeto representa a aplicação à qual a página JSP pertence. Ele é uma instância da
interface javax.servlet.ServletContext. Os containers JSP tipicamente tratam do
primeiro nome de diretório em um URL como uma aplicação. Exemplo:
• http://server/jsp_dev/index.jsp
• http://server/jsp_dev/principal.jsp
• http://server/jsp_dev/forum/forum.jsp
• http://server/jsp_dev/tutorial/tutorial.jsp
São todos considerados parte da mesma aplicação jsp_dev. Além dos métodos descritos
na tabela 1, os métodos do objeto application podem ser divididos em quatro
funcionalidades :
52
Recuperar informações de versão do container servlet:
Método Descrição
String getServerInfo() Retorna o nome e versão do container servlet.
int getMajorVersion() Retorna a versão principal da API do servlet para o container servlet.
int getMinorVersion() Retorna a versão secundária da API do servlet para o container servlet.
Exemplo :
Um grupo de páginas JSP que residem na mesma aplicação podem fazer uso de
atributos do objeto application para disponibilizar recursos que devem estar disponíveis
para todas as páginas da aplicação. Outra utilização muito frequente para o objeto
application é a utilização de parâmetros de inicialização para a aplicação como um todo.
Estas e outras funcionalidades estão ilustradas no código abaixo (arquivo
application.jsp) :
<html>
<body>
<%
//Este trecho de código grava um objeto do tipo String no contexto da aplicação a qual a
//página pertence
String aux = "aux e um objeto armazenado no contexto desta aplicacao e pode ser
recuperado por qualquer pagina que pertença a ela ";
application.setAttribute("aux",aux);
%>
53
<br><br>
<b>Informaçoes sobre o container : </b><br>
<%= application.getServerInfo() %>
<br><br>
<b>Caminho no servidor onde está armazenada esta página : </b><br>
<%= application.getRealPath("application.jsp") %>
<br><br>
<b>Recuperando parâmetros de inicialização : </b><br>
<%= "Usuário : " + application.getInitParameter("username") %><br>
<%= "Senha : " + application.getInitParameter("password") %>
</body>
</html>
<!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>
<context-param>
<param-name>username</param-name>
<param-value>admin</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>teste</param-value>
</context-param>
</web-app>
54
Objetos Contextuais
• Objeto pageContext :
– fornece acesso programático a todos os outros
objetos implícitos.
– este acesso é especialmente útil na perspectiva
de criação de tags personalizadas.
– alguns métodos para recuperar objetos
implícitos são : getPage - retorna o objeto page,
getRequest - retorna o objeto request, getOut -
retorna o objeto out, getSession - retorna o
objeto session e assim para cada um deles.
Desenvolvido pelo ESMS.C 63
Objetos Contextuais
• Objeto pageContext (continuação):
– acesso aos atributos dos objetos que lidam com
atributos, isto é, aqueles que implementam os
métodos : setAttribute, getAttributeNames,
getAttibute (key) e removeAttibute (key)
– estes objetos e seus respectivos escopos são :
• request - REQUEST_SCOPE
• session - SESSION_SCOPE
• application - APPLICATION_SCOPE
• pageContext - PAGE_SCOPE
Desenvolvido pelo ESMS.C 64
Objetos Contextuais
• O bjeto pageContext (continuação):
– alguns m étodos para tratar de atributos são :
• setAttribute (key, value, scope)
• getA ttribute (key, scope)
• removeAttribute (key, scope)
• findAttribute (nam e)
• O objeto pageContext também im plem enta
m étodos que possibilitam transferir o
controle da página atual para outra e serão
vistos com mais detalhes no tópico Ações.
Desenvolvido pelo ESM S.C 65
55
O objeto pageContext fornece várias facilidades como gerenciamento de sessões,
atributos, inclusões e encaminhamento de requisições de fluxo de resposta. O objeto
pageContext é uma instância da classe javax.servlet.jsp.PageContext. Além dos
métodos para lidar com atributos descritos na tabela 1, os principais métodos desse
objeto podem ser divididos em três categorias :
Os últimos dois métodos listados na tabela anterior permitem a procura, através de todos
os escopos definidos, por um atributo associado com uma String passada como
parâmetro. Nos dois casos, o objeto pageContext irá realizar uma busca através dos
escopos na seguinte ordem: pageContext, request, session e application..
A tabela anterior traz métodos que recebe parâmetros para especificar o escopo. A
classe javax.servlet.jsp.PageContext fornece variáveis estáticas para representar estes
quatro escopos diferentes. A tabela a seguir resume estas variáveis:
Variável Descrição
PAGE_SCOPE Escopo para atributos armazenados no objeto pageContext.
REQUEST_SCOPE Escopo para atributos armazenados no objeto request.
SESSION_SCOPE Escopo para atributos armazenados no objeto session.
APPLICATION_SCOPE Escopo para atributos armazenados no objeto application.
56
O exemplo abaixo ilustra o uso do método "getAttribute" e das variáveis estáticas
descritas na tabela anterior :
<%
User uPag=(User)pageContext.getAttibute("user",pageContext.PAGE_SCOPE)
//Recupera o object "usuario" do escopo pageContext
User uReq=(User)pageContext.getAttibute("user",pageContext.REQUEST_SCOPE)
//Recupera o object "usuario" do escopo request
User uSes=(User)pageContext.getAttibute("user",pageContext.SESSION_SCOPE)
//Recupera o object "usuario" do escopo session
User uApp=(User)pageContext.getAttibute("user",pageContext.APPLICATION_SCOPE)
//Recupera o object "usuario" do escopo application
%>
Tratamento de Erros
• Objeto Exception : tem o propósito de
possibilitar o tratamento de erros em
páginas cujo atributo isErrorPage = “true”
• Principais métodos são :
– getMessage : msg de erro descritiva
– printStackTrace(out) : imprime a pilha de
execução para o fluxo de saída designado
– toString() : retorna uma cadeia combinando o
nome da classe da exceção com sua msg de erro
Desenvolvido pelo ESMS.C 61
O objeto exception não está automaticamente disponível em todas as páginas JSP. Este
objeto está disponível apenas nas páginas que tenham sido designadas como páginas de
erro, usando o atributo isErrorPage configurado com true na diretiva page. O objeto
exception é uma instância da classe java.lang.Throwable correspondente ao erro não
capturado que fez com que o controle fosse transferido para a página de erro. Os
principais métodos da classe java.lang.Throwable que são utilizados dentro das páginas
JSP são listados na tabela abaixo:
Método Descrição
String getMessage() Retorna a mensagem de erro descritiva associada com a exceção quando ela foi lançada.
void
Imprime a pilha de execução em funcionamento quando a exceção foi lançada para o
printStackTrace(PrintWri
fluxo de saída especificado pelo parâmetro out.
ter out)
Retorna uma cadeia combinando o nome da classe da exceção com sua mensagem de
String toString()
erro, se houver alguma.
O trecho abaixo ilustra o uso do objeto exception em uma página de erro JSP:
57
<@ page isErrorPage=true %>
<h1>Erro Encontrado</h1>
O seguinte erro foi encontrado:<br>
<b><%= exception %></b><br>
<% exception.printStackTrace(out); %>
Ações
• Forward : A ação <jsp:forward> transfere
permanentemente o controle de uma página
JSP para um outro local no servidor.
• O conteúdo gerado antes é descartado.
• Os objetos request e session serão os
mesmos tanto para a página original quanto
para a página encaminhada.
• Considerações quanto bufferização
• Sintaxe : <jsp:forward page=“localHRL” />
Desenvolvido pelo ESMS.C 67
Ações
fatoração.jsp
<% x = recebe_fatoracao.jsp
request.getParameter(“x”);
<% y =
y = Fatora (x); request.getAttribute(“y”);
if (y != null) { %>
Quando o controle é transferido para uma outra página JSP, o container irá
automaticamente atribuir um novo objeto pageContext à página encaminhada. O objeto
58
request e session, no entanto, serão os mesmos tanto para página original quanto para a
página encaminhada.
Ações
• Include : A ação <jsp:include> transfere
temporariamente o controle de uma página
JSP para um outro local no servidor.
• O output da página incluída é colocado no
output da página atual que continua seu
processamento.
• Sintaxe :
<jsp:include page=“localHRL” flush=“true” />
• Diretiva include x Ação include
Desenvolvido pelo ESMS.C 69
59
A página incluída pode ser um documento estático, um CGI, um servlet ou outra página
JSP. Assim como acontece com a ação <jsp:forward>, o atributo page da ação
<jsp:include> suporta valores obtidos em tempo de execução. O atributo flush controla
se o buffer de saída da página original deve ou não ser esvaziado antes que o novo
output comece a ser incluído. Geralmente é definido como “true”.
Assim como acontece com páginas acessadas através da ação <jsp:forward>, será
atribuído às páginas incluídas um novo objeto pageContext e compartilhado os objetos
session e request. Sendo assim, caso seja necessário passar valores da página original
para a incluída, deve-se usar um destes objetos.
Diretiva Include :
Ação Include :
• Cada página incluída é um servlet separado, que deve ser carregado e executado
pelo container.
• Troca de informações entre as páginas através do objeto session ou request.
• Como cada página incluída é um servlet separado, uma alteração em alguma delas
não requer uma alteração forçada na página principal para a alteração ter efeito
(recompilação automática).
• Menores tamanhos de classe, já que o código correspondente ao arquivo incluído
não é repetido nos servlets para todas as páginas JSP que fazem a inclusão.
• Possibilidade de especificar em tempo de execução a página a ser incluída.
• Pode incluir páginas estáticas, CGI’s, servlets ou outra página JSP.
60
Exercícios :
3 – Crie uma página chamada origem.jsp que recebe um número inteiro como
parâmetro, calcula seu fatorial e acrescenta o resultado como atributo da solicitação.
Depois, crie um objeto do tipo javax.servlet.RequestDispatcher. Para isso utilize o
método getRequestDispatcher(“<pagina destino>”) do objeto request:
Objeto application
Objeto out
6 - Faça uma página que exiba o status da bufferização, apresentando qual o tamanho
total do buffer, quantos bytes já foram utilizados e qual a porcentagem livre do mesmo.
7 - O método abaixo simula o jogo do lançamento de uma moeda para depois verificar
se ela caiu no lado da cara ou da coroa. O método retorna uma String com o resultado, e
um exemplo da forma como pode ser utilizado a partir de uma página está no quadro
abaixo.
61
<%!
String jogueMoeda(){
String retorno = "";
int i = (int)(Math.random()*10); //um número entre 0 e 10
i = i%2; //resto da divisao de i por 2
if(i==0){ Exemplo de utilização :
retorno = "cara"; <html>
} else { <body>
retorno = "coroa";
} <h1>Deu <%= jogueMoeda() %>!</h1>
return retorno;
} </body>
%> </html>
Modifique o código de forma que o método receba como parâmetro o número de vezes
que irá lançar a moeda. Além disso, utilize o objeto out para imprimir, a partir do
próprio método, os resultados. A inserção deste objeto no método irá causar dois erros
que devem ser tratadados. Algumas dicas para tentar resolvê-los são : lembre-se que o
java exige o tratamento de exceções em determinadas situações, os objetos implícitos
não são visíveis dentro dos métodos criados numa página JSP e o objeto out é da classe
javax.servlet.jsp.JspWriter.
Objeto session
<html>
<body>
</body>
</html>
9 - Crie uma página que leia um valor numérico passado pelo usuário, multiplique seu
valor por 10, e então encaminha o processamento utilizando a ação <jsp:forward> para
outra página que irá imprimir o resultado.
10 - Numa situação em que queremos utilizar uma página que cria inúmeros objetos que
serão compartilhados por outras, qual melhor opção, utilizar a diretiva include ou a ação
include ?
62
V - Cookies
IV - Cookies
Como padrão, os cookies expiram tão logo o usuário encerra a navegação naquele site,
porém, podemos configurá-los para persistirem por vários dias, até uma data de
expiração especificada. Por razões de segurança, um cookie só pode ser recuperado pelo
servidor que o forneceu. Opcionalmente, um cookie pode ser tornado acessível para
outros servidores que compartilham o mesmo domínio do servidor original que o gravou
. Eles ainda podem ser restritos a uma hierarquia de diretórios de URL específico no
servidor, ou servidores, do qual ele é acessível. Cada cookie recebe um nome, e um
servidor pode então definir múltiplos cookies e fazer a identificação entre eles através
dos seus nomes.
Gerenciando Cookies
le_cookie.jsp
Toda vez que uma página é submetida
.... para o servidor web, o browser antes
getCookies() verifica se há algum cookie referente àquele
servidor (ou domínio) e os envia no cabeçalho
...
de solicitação. Quando a página chega no
servidor, é possível ler este cabeçalho e
recuperar os cookies enviados.
A classe Cookie
Manipulando Cookies
• Manipulamos um cookie através de
instâncias da classe Cookie
• Construtor :
Cookie cookie = new Cookie("nome" , “valor");
• Principais Métodos :
– getValue() - setValue()
– getDomain() - setDomain()
– getMaxAge() - setMaxAge(int i)
– getName()
64
Manipulamos um cookie através de instâncias da classe javax.servlet.http.Cookie, que é
automaticamente inserida no servlet associado que é gerado na compilação da página
JSP. Essa classe fornece apenas um tipo de construtor que recebe duas variáveis do tipo
String, que representam o nome e o valor do cookie :
Método Descrição
getName() retorna o nome do cookie
getValue() retorna o valor armazenado no cookie
getDomain() retorna o servidor ou domínio do qual o cookie pode ser acessado
getPath() retorna o caminho deURL do qual o cookie pode ser acessado
getSecure() indica se o cookie acompanha solicitações HTTP ou HTTPS.
setValue() atribui um novo valor para o cookie
setDomain() define o servidor ou domínio do qual o cookie pode ser acessado
setPath(nome do path) define o caminho de URL do qual o cookie pode ser acessado
setMaxAge(inteiro) define o tempo restante (em segundos) antes que o cookie expire
retorna o valor de um único cabeçalho de solicitação como um
setSecure(nome)
número inteiro
Depois de construir uma nova instância, ou modificar uma instância recuperada através
do método getCookies(), é importante ter em mente a necessidade de usar o método
addCookie( ) para atualizar no navegador do usuário as alterações feitas no cookie. Para
apagar um cookie utilizamos a seguinte técnica : chamamos o método "setMaxAge(0)"
com valor zero e depois mandamos gravar chamando o método "addCookie( )". Isso faz
com que o cookie seja gravado, substituindo o de mesmo nome, e imediatamente (após
zero segundos) expira.
Definindo um cookie
O primeiro passo ao usar um cookie dentro de uma página é defini-lo. Isto é feito
criando uma instância da classe Cookie e chamando os métodos "sets" para definir os
valores de seus atributos.
<%
String email = request.getParameter("email");
String cookieName = "cookieJSP";
Cookie cookieJSP = new Cookie(cookieName, email);
cookieJSP.setMaxAge(7 * 24 * 60 * 60); //define o tempo de vida como 7 dias (604800
//segundos)
cookieJSP.setVersion(0); //versão 0 da especificação de cookie
65
cookieJSP.setSecure(false); //indica que o cookie deve ser transferido pelo protocolo
//HTTP padrão
cookieJSP.setComment("Email do visitante"); //insere um comentário para o cookie
response.addCookie(cookieJSP); //grava o cookie na máquina do usuário
%>
<html> <head>
<title>Grava Cookie</title>
</head>
<body>
<h1>Grava Cookie</h1>
Esta página grava um cookie na sua máquina.<br>
<a href='readcookie.jsp'>Lê conteúdo do cookie</a>
</body> </html>
A página que irá fornecer um email que será gravado pela página "addcookie.jsp" pode
ser da seguinte forma :
<html> <body>
<form action="addcookie.jsp">
<input type="text" name="email">
<input type="submit" value="ok">
</body> </html>
Recuperando um Cookie
A página jsp vista anteriormente tem a finalidade de receber um valor (email) passado
através de um formulário de uma página html. Este valor é armazenado de forma
persistente em um cookie e poderá ser acessado pelas outras páginas JSP que
compartilham o domínio e o caminho originalmente atribuídos ao cookie. Os cookies
são recuperados através do método getCookies() do objeto implícito request. A página
abaixo (readcookie.jsp) mostra um exemplo de recuperação do valor de um cookie.
<%
String cookieName = "cookieJSP";
Cookie listaPossiveisCookies[] = request.getCookies();
Cookie cookieJSP = null;
if (listaPossiveisCookies != null) {
//quando não existe cookies associados, o método getCookies() retorna um valor null
int numCookies = listaPossiveisCookies.length;
for (int i = 0 ; i < numCookies ; ++i) {
if (listaPossiveisCookies[i].getName().equals(cookieName)) { //procura pelo cookie
cookieJSP = listaPossiveisCookies[i];
break;
}
}
} %>
<html> <body>
<h1>Lê Cookie</h1>
66
<% if (cookieJSP != null) { %>
A pagina "addcookie" gravou o seguinte email: <%= cookieJSP.getValue() %>
<% }
else { %>
O cookie não gravou ou o prazo do cookie expirou.
<% } %>
</body> </html>
O primeiro scriptlet nesta página recupera os cookies associados àquela página e depois
tenta encontrar um cookie identificado pelo nome "cookieJSP".
• o tamanho dos dados armazenados (nome e valor) não devem ultrapassar 4K.
• o navegador pode armazenar múltiplos cookies, contanto obedece um certo limite.
Um navegador armazena até 20 cookies por configuração de domínio. O navegador
armazena também 300 cookies em geral. Se qualquer um destes dois limites forem
alcançados, espera-se que o navegador exclua cookies menos utilizados.
• o domínio atribuído a um cookie deve ter pelo menos dois pontos, por exemplo :
www.exemplo.com ou .exemplo.com. Esta regra existe para evitar a especificação
de cookies que podem ser lidos através de um domínio inteiro de alto nível (.com,
.org, .net, etc). Quando nenhum domínio é especificado na criação de um cookie
através do método setDomain(nome do domínio), então ele poderá ser lido apenas
pelo host que originalmente o definiu.
67
Exercícios :
2 – Crie uma página JSP que grava um cookie chamado datecookie com o valor da data
atual do sistema e expira num prazo de dois dias. Ela deve conter um link para uma
outra página que deverá apresentar o conteúdo do cookie ou apresentar uma mensagem
que o cookie não pode ser encontrado ou já expirou. Para obter a data do sistema fazer
68
VI - Enviando Email com JSP
O envio de email nos dias de hoje, para quem utiliza a internet, é algo comum e
corriqueiro. É bastante comum encontrarmos sites a partir da qual podemos enviar um
email ou enviar aquela página html para um amigo. Vale citar o fato que o envio de
email via páginas html/jsp pode ser uma excelente ferramenta para webmasters que
precisam enviar periodicamente mensagem padrão para grupos de usuários.
O envio do(s) email(s) é efetuado através da API JavaMail, que pode ser obtida em :
http://www.javasoft.com/products/javamail/index.html. Neste link, encontram-se todas
as informações necessárias para a confecção de aplicações que lidam com emails.
Utilizando esta API você poderá fazer seu próprio WebMail, personalizando-o da forma
como desejar.
O primeiro destes, a página html, terá um formulário com três objetos do tipo "TEXT",
um do tipo "TEXTAREA" e um botão do tipo "SUBMIT" para enviar o formulário com
os dados do email.Os dados que forem preenchidos neste formulário serão tratados pela
página JSP enviaremail.jsp que foi definida como o action do formulário. Abaixo segue
o código da página “preencheremail.html” :
<html>
<body>
69
Abaixo segue o código da página JSP enviaremail.jsp com a lógica de programação
responsável por criar e enviar o "email" :
<html>
<body>
<%
try {
//definição do mailserver
Properties props = System.getProperties();
props.put("10.0.134.8", "10.0.134.8");
//Data de envio
message.setSentDate(new Date());
70
}
catch (AddressException e) {
out.println("<p>Endereço de Email inválido</p>");
}
catch (MessagingException e) {
out.println("<p>Impossível enviar o email.</p>");
}
%>
</body>
</html>
No arquivo acima, optamos por levantar as exceções na própria página jsp de onde se
envia o email, poderíamos ter definido uma página de erro para fazer este tratamento.
São dois os possíveis erros decorrentes da tentativa de enviar o email :
O código abaixo, ilustra o tratamento da exceção gerada por endereço de email inválido.
catch (AdressException e) {
out.println(“<p>Endereço de Email inválido</p>”);
}
No trecho de código seguinte, fazemos o tratamento da exceção gerada pelo não envio
da mensagem. Essa exceção pode ser causada por vários problemas, tais como:
problema no servidor de email, problemas na rede, entre outros.
catch (MessagingException e) {
out.println(“<p>Impossível enviar o email.</p>”);
}
Exercício :
1 – Crie uma página JSP que , quando executada, lê um arquivo texto com uma lista de
e-mails e envia um texto pré-definido para cada e-mail da lista. Se ocorrer algum erro
no decorrer deste processo, este deve ser tratado numa página de erro chamada error.jsp.
O código abaixo implementa a funcionalidade de ler um arquivo num formato pré-
definido e armazenar seu conteúdo numa estrutura de dados denominada Properties.
Você deve incrementá-lo com o código de envio de e-mail para todos os e-mails
carregados do arquivo lido.
/*
Buscando o arquivo a ser inserido na tabela
O arquivo deve ter o seguinte formato:
email1 curso@dataprev.gov.br
email2 .........
71
email3 .........
email4 .........
*/
FileInputStream input;
input = new
FileInputStream(" Caminho completo para o arquivo ");
table.load(input); //Carregando dados do arquivo
input.close(); //Fechando fluxo entrada de dados
//Laço para varrer a estrutura table com os e-mails lidos do arquivo
for(int i=0; i < table.size(); i++) {
72
VII – Trabalhando com Banco de Dados
Este capítulo cobre os seguintes tópicos :
Hoje em dia, a maioria dos sites da internet que produzem conteúdo dinâmico fazem
uso de algum banco de dados. Gerenciamento de anúncios, informações de usuários,
lista de contato, compras on-line são apenas alguns dos recursos comumente
gerenciados através de um banco de dados.
Diferentemente de outras linguagens (PHP, Cold Fusion, etc), JSP não define um
conjunto próprio de comandos para acessar um banco de dados específico (em PHP por
exemplo, existe um conjunto específico de comandos para acessar cada banco de dados
diferente, consequentemente, uma página projetada para acessar o MySQL tem que ser
refeita se quisermos mudar o banco para Interbase), mas sim utiliza a API JDBC de
java para isso. Como todos os drivers de diferentes fabricantes baseiam sua
implementação nas interfaces e classes definidas nesta API, todos eles implementam o
mesmo conjunto de métodos (com as mesmas assinaturas). Sendo assim, se quisermos
mudar o banco de dados da nossa aplicação java, basta apenas carregar o driver
referente ao novo banco que tudo continuará funcionando com (quase) nenhuma
alteração no código da aplicação.
O primeiro passo para se estabelecer uma conexão com um banco de dados utilizando
java é obter o driver JDBC do banco em questão. Existe um serviço no site da SUN que
reúne inúmeros drivers de diferentes fabricantes e permite configurar uma consulta para
buscar pelo driver JDBC desejado (http://servlet.java.sun.com/products/jdbc/drivers).
Os drivers geralmente são fornecidos como arquivos com extensão .JAR. Arquivos .jar
são geralmente usados para agrupar todos os arquivos de uma determinada aplicação
Java. Dentro deles pode-se ter desde .class, arquivos html de documentação a arquivos
de áudio. Com esse tipo de recurso você pode criar uma espécie de executável para
Java, bastando para isso, associar o tipo .jar com o java.exe ou com o javaw.exe
facilitando assim a distribuição de suas aplicações. Alem disso, arquivos jar podem ser
úteis para distribuir conjuntos de pacotes que se prestem a realizar alguma operação. É
comum, por exemplo, ver os drivers JDBC(Java Database Connectivity) ou applets
serem distribuídos nesse tipo de arquivo. Os arquivos jar usam um padrão de
compressão baseado no formato de compressão zip de modo que qualquer aplicativo
que suporte esse formato pode abrir e manipular um .jar.
Há várias maneiras de “instalar” um Jar para ser usado pela sua aplicação web:
73
• A forma mais simples é copiar o arquivo para o diretório
<JAVA_HOME>\jre\lib\ext. Isso torna o arquivo automaticamente visível ao
jdk e todas as aplicações, web ou não, irão reconhece-lo.
• Outra forma é copiar o arquivo para qualquer diretório na máquina e então
referenciar seu caminho totalmente qualificado na variável de ambiente
CLASSPATH. O jdk faz uso dessa variável para acrescentar as libs aí definidas
à sua lista de bibliotecas. O incoveniente dessa abordagem é que as IDEs de
desenvolvimento geralmente ignoram o CLASSPATH de maneira que você terá
que adicionar o arquivo jar manualmente ao conjunto de libs reconhecidos pela
sua IDE. Como em cada IDE há uma maneira diferente de se fazer isso, não irei
explicar como fazê-lo.
• Outra alternativa é copiar o arquivo para o diretório WEB-INF/lib do contexto
que sua aplicação faz parte. Isso faz com que somente a aplicação web dentro
deste contexto tenha acesso ao arquivo Jar.
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jar.html
Uma vez instalado o driver JDBC do banco que desejamos utilizar, temos que
configurar as informações necessárias para estabelecermos uma conexão. Para tanto,
utilizaremos a classe javax.sql.DataSource implementada pelo driver. Essa classe
encapsula todas as informações necessárias para obtermos uma conexão com um
determinado banco de dados (driver, localização, usuário, senha, etc), permitindo que
eliminemos as informações de conexão do código (caso usemos JNDI para registrá-lo) e
criando uma interface única através da qual iremos nos referir ao banco desejado. Se por
exemplo mudarmos a base de dados de local ou as informações de login mudarem, basta
apenas alterarmos suas propriedades com as novas informações e qualquer código que o
esteja utilizando não precisará ser alterado.
Para instanciar o objeto, utilizamos o nome de classe totalmente qualificado. Esse nome
vai depender do banco que se deseja acessar. O código abaixo apresenta a definição de
um DataSource para acessar um banco Oracle.
74
ds.setUser("SYSDBA");
ds.setPassword("masterkey");
Uma vez tendo instanciado apropriadamente um objeto DataSource, podemos usar seu
método getConnection para obtermos uma conexão com o banco que o objeto
referencia.
Uma vez tendo estabelecido uma conexão com um banco de dados (com um usuário
com privilégios suficientes), podemos comandar os mais diversos tipos de operações
para que este as execute : consultas, alterações nas informações das tabelas ou em sua
estrutura, execução de stored procedures, dentre outras. É importante lembrar que,
sempre depois que a conexão for utilizada, esta deve ser fechada com o comando
close().
Executando consultas
Uma vez obtido um objeto Statement, podemos definir uma consulta e submeter sua
execução ao banco através do método executeQuery(String query) do objeto Statement :
O parâmetro query é uma String com uma consulta qualquer na linguagem SQL
suportada pelo banco. O método retorna um objeto da classe ResultSet. Falaremos mais
sobre este objeto posteriormente.
75
se quiséssemos que os valores de dt_nascimento e salario fossem passados em tempo de
execução utilizando a classe Statement, faríamos da seguinte forma
//Montagem da consulta
String query = “select nome, dt_nascimento, salario from EMPREGADOS where
dt_admissao > ? and salario < ?” ;
//Substituição dos valores
java.sql.PreparedStatement pstm = con.prepareStatement(query);
pstm.setDate(1,java.sql.Date.valueOf(“data_formato_JDBC”)); // yyyy-mm-dd
pstm.setDouble(2, Double.parseDouble(“salario”));
//Execução da consulta
java.sql.ResultSet rs = pstm.executeQuery();
Executando alterações
Já vimos como executar consultas num banco de dados através do método executeQuery
das classes Statement e PreparedStatement, método este que retorna um ResultSet com
o resultado da consulta. Veremos agora como submeter instruções que modificam
valores das tabelas, alteram sua estrutura ou criam novos objetos dentro do banco.
Os comandos SQL para realizar modificações no conteúdo de uma tabela são : update,
insert e delete. Essas instruções podem ser submetidas ao banco através do método
executeUpdate existente em ambas as classes e que retorna um inteiro com o número de
linhas afetadas pela execução do comando. Vejamos os exemplos :
76
String insert = “insert into EMPREGADOS values ( “ ‘ + request.getParameter(“nome”)
+ “ ’ , ” + request.getParameter(“salario”) + “, ‘ ” +
request.getParameter(“dt_admissao”) + “ ‘ )”;
//Execução da consulta
int x = stm.executeUpdate(insert);
Quando o comando for uma instrução DDL (Database Definition Language), como a
alteração ou criação de uma tabela, o valor de retorno deste método será zero. O
exemplo abaixo mostra um comando que cria uma stored procedure dcentro do banco.
JDBC permite que executemos uma Stored Procedure de um banco de dados a partir de
uma aplicação java. Para isso, devemos criar um objeto da classe
java.sql.CallableStatement, que é uma subclasse de PreparedStatement, a partir de uma
conexão estabelecida com o banco :
77
No código acima, instanciamos um objeto CallableStatement apto a executar a
procedure que criamos anteriormente. Quando o driver encontra "{call
SHOW_SUPPLIERS}" , ele irá traduzir esta sintaxe no SQL nativo usado pelo banco
para chamar a stored procedure chamada SHOW_SUPPLIERS. Para efetivamente a
executarmos, devemos fazer :
java.sql.ResultSet rs = cs.executeQuery();
O método que deve ser utilizado para executar a procedure depende do conteúdo da
mesma e está resumido na sequência abaixo :
Quando for o caso de usar a terceira opção, deve-se usar o método getResultSet() ou
getUpdateCount() para obter o resultado. Para obter todos os resultados usar o método
getMoreResults() que irá posicionar no próximo result set ou update count. Este método
retorna true caso o próximo resultado retorne um result set e, como o método
getUpdateCount() retorna –1 caso não existam mais resultados, pode-se usar a seguinte
expressão como condição de parada num laço para varrer todos os resultados:
Primeiro criamos a string que vai representar a chamada à procedure com seu parâmetro
de retorno e entrada - "{? = Call GetPrimaryKey( [arg1, arg2, ...] )}". Depois dizemos
que o primeiro parâmetro da procedure é um parâmetro de saída e que é do tipo inteiro -
registerOutParameter(1, java.sql.Types.INTEGER) e então atribuímos um valor
apropriado para o parâmetro de entrada. Feito isso, basta executarmos a procedure com
o método execute() e então ler o valor retornado - getInt(1).
A classe ResultSet
Por último, mas não menos importante, vamos aprender um pouco sobre um dos
componentes mais importantes quando estamos trabalhando com banco de dados, o
result set. Quem já desenvolveu uma aplicação que acessa um banco de dados, com
qualquer tecnologia que seja, já deve ter se deparado com algo similar a classe
ResultSet do java. A grosso modo, um result set é uma estrutura de dados em memória,
78
uma matriz que armazena o resultado de uma consulta SQL. Um CURSOR em Oracle é
um result set, o componente Query do Delphi representa um result set, uma classe que
implementa a interface ResultSet do java implementa um result set.
Nas aplicações, muito frequentemente precisamos iterar sobre um result set para
apresentar o resultado de uma consulta, fazer buscas por dados específicos no seu
repositório sem a necessidade de acessar o banco novamente e, quando a tecnologia
permite, alterar os dados diretamente no result set, alterações estas que serão
automaticamente replicadas no banco de dados.
Mostraremos nesta sessão como ler o conteúdo de um objeto ResultSet. Apesar dos
métodos aqui definidos fazerem parte da especificação 1.0 de JDBC, eles são
equivalentes para a 2.0.
É possível referenciar uma coluna pelo seu nome ou pelo seu índice. Isso é
particularmente útil quando temos duas colunas com o mesmo nome num result set.
Assim, no exemplo acima os métodos get ficariam getString(1), para obter o valor da
coluna COF_NAME e getFloat(2) para obter o valor de PRICE.
Existe uma grande variedade de métodos get para convertemos os diferentes tipos de
dados SQL para tipos da linguagem java. O método getSring pode ser usado para obter
qualquer tipo, convertendo tudo para uma String. Abaixo segue uma tabela com um
79
resumo dos principais métodos get. Um “x” significa que o método pode ser usado para
obter aquele tipo e um “X” significa que o método é recomendado para aquele tipo.
L
L O
O V N T
S
T I D N V N A G I
M B D B
I N F E U A G R V M
A I R O C I D T
N T L C M B R V B A E
L G E U H N A I
Y E O I E I C A I R S
L I A B A A T M
I G A M R T H R N B T
I N L L R R E E
N E T A I A C A I A
N T E Y
T R L C R H R N M
T
A Y A P
R R
Y
getInt x x X x x x x x x x x x x
getFloat x x x x X x x x x x x x x
getDouble x x x x x X X x x x x x x
getBoolean x x x x x x x x x X x x x
getString x x x x x x x x x x X X x x x x x x x
getBytes X X x
getDate x x x X x
getTime x x x X x
getTimestamp x x x x x X
getAsciiStream x x X x x x
getUnicodeStream x x X x x x
getBinaryStream x x X
getObject x x x x x x x x x x x x x x x x x x x
80
• ResultSet.TYPE_SCROLL_SENSITIVE : com este parâmetro o ResultSet poderá
ser navegável para qualquer direção, e será sensível a mudanças feitas por outras
transações ou por outros Statements da mesma transação. Isto significa que, se o
ResultSet for updateable e sofrer uma modificação, uma leitura no valor modificado
já será visível logo após.
Método Descrição
boolean first() posiciona o cursor na primeira linha do ResultSet e retorna true, caso não exista
linhas, retorna false.
boolean last() posiciona o cursor na última linha do ResultSet e retorna true, caso não exista
linhas, retorna false.
boolean previous() posiciona o cursor para a linha anterior a posição corrente, retorna true caso a
linha seja válida e false caso contrário.
boolean absolute(int row) posiciona o cursor corrente para a linha especificada pelo parâmetro tendo
como referência o início e o fim do resultset, retorna true caso a linha é valida
ou false caso contrário. Se o valor for negativo, o cursor moverá o valor
especificado a partir do final.
boolean relative(int offset) posiciona o cursor corrente para a linha especificada pelo parâmetro tendo
como referência a posição corrente do cursor, retorna true caso a linha é valida
ou false caso contrário.
void beforeFirst() posiciona o cursor antes da primeira linha.
void afterLast() posiciona o cursor depois da última linha.
boolean isFirst() retorna true caso o cursor corrente está posicionado na primeira linha.
boolean isLast() retorna true caso o cursor corrente está posicionado na última linha.
boolean isBeforeFirst() retorna true caso o cursor corrente está posicionado antes da primeira linha.
boolean isAfterLast() retorna true caso o cursor corrente está posicionado após a última linha.
Int getRow() retorna o número da linha corrente do cursor.
81
Com um ResultSet do tipo updatable podemos executar as operações de INSERT,
DELETE e UPDATE sem precisar criar os comandos SQL. Utilizando métodos do
próprio ResultSet, podemos inserir, deletar e alterar seus valores e depois refletir estas
operações para o banco de dados.
Método Descrição
updateBoolean(String columnName, boolean Atualiza a coluna com um booleano
x)
updateDate(String columnName, Date x) Atualiza a coluna com uma data
updateDouble(String columnName, double x) Atualiza a coluna com um double
updateInt(String columnName, int x) Atualiza a coluna com um int
updateNull(String columnName) Atualiza a coluna com um valor nulo
updateObject(String columnName, Object x) Atualiza a coluna com um objeto
updateString(String columnName, String x) Atualiza a coluna com uma string
updateTimestamp(String columnName, Atualiza a coluna com um Timestamp
Timestamp x)
Como nos métodos getters do ResultSet, todos os métodos acima possuem uma versão
onde, ao invés de passarmos o nome da coluna, passamos o seu índice no result set.
Uma vez alterado o valor de uma coluna, para que a alteração seja refletida na base de
dados utilizamos o método: updateRow(). Este método propaga a alteração feita no
ResultSet para a linha no banco de dados e efetua o commit.
rs.updateFloat("PRICE", 10.99);
rs.updateRow();
Se uma alteração for efetuada e o cursor se mover daquela linha antes do método
updateRow() ser invocado, a alteração é perdida. É possível também cancelarmos
alterações realizadas em uma linha chamando o método cancelRowUpdates().
82
uprs.updateString("COF_NAME", "Kona");
uprs.updateInt("SUP_ID", 150);
uprs.updateFloat("PRICE", 10.99);
uprs.updateInt("SALES", 0);
uprs.updateInt("TOTAL", 0);
uprs.insertRow();
Para fazer a deleção (DELETE) de uma linha do ResultSet, tudo que temos a fazer é
posicionar o cursor na linha a ser excluída e então chamar o método deleteRow().
Considerações Finais
• É importante estar ciente que apenas especificar que um ResultSet seja updatable
não garante que ele o seja. Se o driver não suporta result sets atualizáveis, ele irá
retornar um apenas para leitura.
• A consulta especificada para criação do result set implica se este poderá ser
atualizável. É aconselhável que a consulta sempre inclua os nomes das colunas e não
o “*” e uma restrição é que não pode haver join entre tabelas e esta deve ter ao
memos uma chave primária definida.
83
Exercícios :
COLUNA TIPO
COD_EMP NUMBER(4) NOT NULL
NOME_EMP VARCHAR(100) NOT NULL
SALARIO_EMP FLOAT
DT_INICIO_EMP DATE
4 – Faça uma página JSP que cria um objeto ResultSet scrollable e updatable com todos
os registros da tabela e realize as seguintes operações com ele :
84
VIII - Java Util
Em projetos de software, freqüentemente usamos diversas estruturas de dados. Não
seria interessante ter que a cada estrutura necessária termos que implementá-la, uma vez
que sempre precisamos de rapidez e agilidade no desenvolvimento. Para auxiliar nosso
desenvolvimento usando estruturas de dados prontas existe um pacote na API da
plataforma Java chamado util. Neste pacote encontram-se várias estruturas de dados,
utilitários para manipulação de data e hora, e diversas outras classes utilitárias. Neste
capítulo veremos algumas destas classes a saber : as classes Vector e StringTokenizer,
como também a interface Enumeration.
A classe Vector implementa um vetor que cresce dinamicamente de acordo com as
necessidades e pode armazenar qualquer tipo de dado. Enumeration não é uma classe,
mas sim uma interface. Ela descreve estruturas que devem ser acessadas
sequencialmentes, uma por vez. A classe StringTokenizer é útil para quebrar a string em
partes menores também chamadas de tokens.
A classe Vector
O uso de arrays na maioria das linguagens deve ter o seu tamanho definido no momento
da alocação de espaço de memória ocupado por esta estrutura. Por exemplo, se
quisermos usar o array de 50 posições inteiras fazemos :
Esta instrução aloca 50 inteiros na memória e torna esta área de memória acessível
através do identificador myArray. No entanto, o que acontece se a nossa lista de inteiros
for maior que 50 posições e eu não consiga conhecer o tamanho no momento da criação
do programa ? Uma alternativa para este problema é usar a classe Vector. Esta classe
fornece uma implementação para arrays que podem crescer dinamicamente. O Vector,
como um array, acessa seus elementos através de um índice e fornece diversos métodos
que auxiliam o seu uso.
Nesta estrutura há um gerenciamento dinâmico do tamanho. Ocorre que quando é
atingido um limite máximo de ocupação da estrutura, ela inclui mais alguns elementos
para manter a possibilidade de novas inserções. Quando deseja-se usar um Vector para
armazenar grandes quantidades de dados podemos definir seu tamanho inicial, evitando
assim que este reajuste de tamanho seja realizado várias vezes, uma vez que o tamanho
inicial de um Vector padrão é baixo (10 elementos).
A classe Vector possui, dentre outros, os seguintes métodos para a sua utilização :
Construtores:
Vector() Cria um Vector de tamanho 10
Vector (int initialCapacity, Cria um vetor com a capacidade inicial e capacidade de
int CapacityIncrement) incremento especificados
Cria um vetor com o tamanho indicado e capacidade de
Vector(int initialCapacity)
incremento igual a 0
85
Métodos para inserção e exclusão:
boolean add(Object obj) Inclui o objeto obj no fim do Vector
Inclui o objeto no Vector na posição indicada por
index. Caso a posição indicada seja inexistente no
boolean add(int index, Object
obj) Vector uma exceção do tipo
ArrayIndexOutOfBoundsException é
disparada.
Inclui o objeto no fim do Vector incrementa ndo seu
boolean addElement(Object obj)
tamanho em 1.
boolean remove(int index) Remove o elemento do índice index
Remove a primeira ocorrência do elemento, caso ele
boolean remove(Object obj)
não exista o vetor é inalterado
void clear() Remove todos os elementos do vetor
void removeAllElements() Remove todos os elementos do Vector e passa
seu tamanho para 0
Note que todos os objetos que são passados para o Vector são da classe Object. Por
padrão, todo objeto em Java herda da classe Object, logo, por herança, você pode
guardar qualquer objeto dentro de um Vector.
Exemplo:
import java.util.*;
}
86
O programa exemplo acima inclui dois objetos no Vector, imprime o tamanho do
Vector e procura pelo inteiro incluído. Note que não podemos incluir um int ou um
double no Vector pelo fato de tipos primitivos em Java não serem objetos. Por isso, foi
usado Integer e Double, classes que representam um inteiro e um número de ponto
flutuante respectivamente.
Note que na retirada dos elementos do Vetor o casting deve ser realizado. Isto se deve
ao fato do método elementAt retornar um Object que deve ser "convertido" para a classe
que ele realmente representa.
A Interface Enumeration
import java.util.*;
while ( enum.hasMoreElements() )
System.out.println( enum.nextElement() );
}
}
Neste exemplo, o Vector retorna uma enumeração de todos os seus elementos. O while
imprime os elementos da enumeração enquanto ainda existir elementos .
A classe StringTokenizer
87
A String "aaa/bbb/ccc/ddd" pode ser quebrada em quatro Strings "aaa", "bbb", "ccc" e
"ddd" através do delimitador "/". A realização desta separação com o StringTokenizer é
mostrado abaixo:
import java.util.*;
while ( st.hasMoreTokens() )
System.out.println ( st.nextToken() );
}
}
Como pode ser visto no exemplo acima, a classe StringTokenizer tem um
comportamento muito parecido com a interface Enumeration, de fato ele implementa
esta interface. Abaixo está a descrição desta classe:
88
Apêndice A
Tratando Formulários
Os formulários são ferramentas úteis e muito usados em diversas aplicações: cadastro de
registros em um banco de dados, validação de um login/senha, envio de email, envio de
dados de um pesquisa, etc. Hoje é difícil desenvolver uma aplicação para Web que não
exija o uso de formulários. Pois bem, na lição de hoje vamos aprender manipular
formulários em aplicações JSP.
Apresentamos abaixo um código para mostrar o formato de um formulário HTML e de
seus objetos.
<html>
<body>
<!- objeto hidden, para enviar dados que o usuário não vê no formulário -->
<input type="hidden" name="asd" value="asd">
</form>
</body>
</html>
</body>
</html>
A página jsp acima, chamada "teste.jsp", contém um formulário que envia para ela
mesma. O valor digitado em uma caixa de texto será mostrado como título da página.
Observe como fizemos isso:
- a página para qual nós enviaremos os dados do formulário é designada no cabeçalho
do formulário:
<form action="teste.jsp" method=get>
90
(com T maiúsculo), a página não iria retornar o valor digitado na caixa de texto.
O próximo exemplo é formado por dois arquivos. O primeiro contém apenas códigos
HTML e o segundo contém códigos HTML e JSP.
Arquivo "envia_mês.htm":
<html>
<body>
</body>
</html>
Arquivo "recebe_mês.jsp":
<%@ page import=java.util.Date %>
<%@ page import=java.lang.String %>
<%
String msg = "";
String mesString = request.getParameter("mesNasceu");
int mes = Integer.parseInt(mesString);
Date dateNow = new Date();
int monthNow = dateNow.getMonth() + 1;
mes -= monthNow;
if (mes == 1)
msg = "Falta apenas "+ mes +" mês para o seu aniversário.";
if (mes == -1)
msg = "Seu aniversário foi no mês passado";
91
if (mes > 1)
msg = "Faltam "+ mes +" meses para o seu aniversário.";
if (mes == 0)
msg = "Oba... estamos no mês do seu aniversário.";
%>
<html>
<body>
<center>
<h3><%= msg %></h3>
<br><br><br>
<a href="Javascript:history.back(-1)">voltar</a>
</center>
</body>
</html>
- nas primeira linhas utilizamos as tags "page import" para indicar quais classes iremos
utilizar em nossa página:
<%@ page import=java.util.Date %>
<%@ page import=java.lang.String %>
92
classe java.util.Date na primeira linha de nossa página). Ele é inicializado com a hora
local do servidor. : Date dateNow = new Date();
- Cinco teste são efetuados dentro de um scriptlet (<% e %>). Eles são usados para
definir o valor que a variável "msg" terá, ou seja, a partir dos testes, decidiremos qual
mensagem será exibida na tela.
- Uma expressão (<%= %>) é usada para exibir o valor da variável "msg": <%= msg
%>
93
Apêndice B
1. Instalação do java
1.1 – Baixar o pacote SDK 1.4 de http://java.sun.com/j2se/1.4/download.html
1.2 – Descompactar o tar.gz em /usr/local
1.3 – Criar um link simbólico chamado jdk para /usr/local/j2sdk1.4.1_01
1.4 – Editar o /etc/profile acrescentando as seguintes linhas :
JAVA_HOME=/usr/local/jdk
PATH="$PATH:/usr/local/jdk/bin"
Export JAVA_HOME
3. Descompactá-lo em /usr/local
4. Criar um link simbólico chamado tomcat para /usr/local/jakarta-tomcat-4.1.18/
5. Editar o arquivo /etc/profile acrescentando as seguintes linhas ;
TOMCAT_HOME=/usr/local/tomcat
CATALINA_HOME=/usr/local/tomcat
CLASSPATH=.
export TOMCAT_HOME CATALINA_HOME CLASSPATH
<IfModule !mod_jk.c>
LoadModule jk_module /usr/local/tomcat/mod_jk.so
</IfModule>
JkWorkersFile "/usr/local/tomcat/workers.properties"
JkLogFile "/usr/local/tomcat/mod_jk.log"
94
JkMount /jsp_dev/* ajp13
8. Criar o arquivo workers.properties em /usr/local com o conteúdo :
worker.list=ajp12, ajp13
worker.ajp12.port=8007
worker.ajp12.host=localhost
worker.ajp12.type=ajp12
worker.ajp12.lbfactor=1
worker.ajp13.port=8009
worker.ajp13.host=localhost
worker.ajp13.type=ajp13
worker.ajp13.lbfactor=1
worker.loadbalancer.type=lb
worker.loadbalancer.balanced_workers=ajp12, ajp13
worker.inprocess.type=jni
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)classes
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)jaxp.jar
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)parser.jar
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)jasper.jar
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)servlet.jar
worker.inprocess.class_path=$(workers.tomcat_home)$(ps)lib$(ps)webserver.jar
worker.inprocess.class_path=$(workers.java_home)$(ps)lib$(ps)tools.jar
worker.inprocess.cmd_line=-config
worker.inprocess.cmd_line=$(workers.tomcat_home)$(ps)conf$(ps)jni_server.xml
worker.inprocess.cmd_line=-home
worker.inprocess.cmd_line=$(workers.tomcat_home)
worker.inprocess.jvm_lib=$(workers.java_home)$(ps)jre$(ps)bin$(ps)classic$(ps)jvm.dll
worker.inprocess.stdout=$(workers.tomcat_home)$(ps)inprocess.stdout
worker.inprocess.stderr=$(workers.tomcat_home)$(ps)inprocess.stderr
worker.inprocess.sysprops=tomcat.home=$(workers.tomcat_home)
/var/www/default/jsp_dev
/var/www/default/jsp_dev/WEB-INF
/var/www/default/jsp_dev/WEB-INF/classes
/var/www/default/jsp_dev/WEB-INF/lib
<!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>
<!-- Define servlets that are included in the jsp_dev application -->
<servlet>
<servlet-name>
login
</servlet-name>
<servlet-class>
login.login
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/servlet/login.login</url-pattern>
</servlet-mapping>
</web-app>
96
Apêndice C
O HTTP é o protocolo mais usado na Web, mas você precisará conhecê-lo em detalhes
apenas se for desenvolver um browser ou um servidor Web. No entanto, um
conhecimento básico é muito útil se você desenvolve programas CGI ou mesmo se
apenas deseja inserir em suas páginas HTML META Tags do tipo Http Equivalent . Ele
é um protocolo do nível de aplicação para sistemas de informação distribuídos,
colaborativos e hipermédia, que tem sido usado na World Wide Web desde 1990. É um
protocolo do tipo requisição/resposta. O programa Cliente (normalmente um navegador
- Internet Explorer ou Netscape Navigator são os mais difundidos) envia ao programa
Servidor uma requisição com o seguinte formato:
• OPTIONS
• GET
• HEAD
• POST
• PUT
• DELETE
• TRACE
• CONNECT
• Previsão para extensões dos métodos.
97
O Cabeçalho de uma mensagem HTTP pode conter um ou mais campos no formato
nome_do_campo:valor_do_campo .
Os campos do Cabeçalho de uma mensagem de requisição são classificados nos
seguintes grupos:
• Cache-Control
• Connection
• Date
• Pragma
• Trailer
• Transfer-Encoding
• Upgrade
• Via
• Warning
• Accept
• Accept_Charset
• Accept_Encoding
• Accept_Language
• Authorization
• Expect
• From
• Host
• If-Match
• If-Modified-Since
• If-None-Match
• If-Range
• If-Unmodified-Since
• Max-Forwards
98
• Proxy-Authorization
• Range
• Referer - Endereço (URI) da página onde está o link que levou a essa requisição.
• TE
• User-Agent - Identificação do Navegador (Netscape Navigator, Internet
Explorer, etc.) ou robot que originou a requisição.
• Allow
• Content-Encoding
• Content-Language
• Content-Length
• Content-Location
• Content-MD5
• Content-Range
• Content-Type - Content-Type: text/html; charset=ISO-8859-4
• Expires - Data/hora após a qual a resposta não deve ser obtida de um cache sem
antes verificar no Servidor de origem se esta continua atual.
• Last-Modified
• Previsão para extensões do cabeçalho.
• Accept-Ranges
• Age
• ETag
• Location - Usado para redirecionar o navegador para uma outra URI.
• Proxy_Authenticate
• Retry-After
• Server
• Vary
• WWW-Authenticate
99