You are on page 1of 120

Aplicaes Web em Java

Servlets e JSP
Aula 1
Software tradicional vs. Aplicaes
Web
SW tradicional: cdigo binrio instalado e executando no
cliente.
Ex.: PhotoShop, CorelDraw, Microsoft Office, ...

Aplicao Web: software disponvel como um servio na


Internet acessado via um software leve e genrico como um
navegador Web.
Ex.: GMail, Facebook, Twitter, Microsoft Office 365, ...
Vantagens

Sem preocupao sobre requisitos de hardware ou sistema


operacional
Sem preocupao sobre quebra ou perda do hardware ou
sistema operacional
Mais fcil de compartilhar dados entre pessoas
Mais fcil manter uma nica cpia dos dados
Mais fcil manter uma nica verso do software e em um
ambiente de hardware controlado
Mais fcil atualizar para uma nova verso do software
Potencialmente mais usurios podem usar o mesmo sofware
Por que Java, Servlets e JSPs?

Portabilidade
Dinamicidade
Interatividade
Flexibilidade
Escalabilidade
A World Wide Web (WWW)

Zilhes de clientes (navegador Chrome, Firefox, Safari ou


Internet Explorer) e servidores (servidor web Apache)
conectados atravs de redes com e sem fio (banda larga fixa e
mvel) que se comunicam atravs de protocolos de
comunicao (TCP/IP, HTTP).
O servidor

um computador conectado Web que executa um software


chamado servidor web que recebe requisies de um
navegador (cliente) e retorna os recursos (documentos,
pginas...) solicitados.
O que o servidor web faz?

1. O servidor web recebe uma requisio do navegador


2. O servidor web encontra o recurso solicitado
3. O servidor web retorna o recurso solicitado para o cliente
Que recursos podem ser solicitados
pelo cliente?
Pgina do Facebook, Twitter ou Gmail
Foto do Flickr ou Picasa
Vdeo do Youtube
Documento PDF
E se o recurso solicitado no for
encontrado?
O servidor web retorna um cdigo de erro e uma mensagem
explicativa.

Ex.: "404 Pgina no encontrada."


A requisio

Contm o nome e o endereo (URL) do recurso que se quer


obter
formatada e enviada pelo navegador em uma requisio
HTTP
A resposta

Contm o recurso solicitado pelo navegador ou um cdigo


e mensagem de erro
formatada e enviada pelo servidor web em uma resposta
HTTP
O navegador

Permite ao usurio solicitar um recurso do servidor web


Apresenta ao usurio o resultado da sua solicitao
Como o navegador e o servidor web
interagem?
1. O usurio clica em um link ou digita um endereo (URL) no
navegador
2. O navegador formata a requisio (requisio HTTP) e a
envia ao servidor web
3. O servidor web encontra o recurso solicitado (pgina HTML)
4. O servidor web formata a resposta (resposta HTTP) e a
envia ao navegador
5. O navegador recebe, processa e apresenta a pgina HTML
ao usurio
HTML (HyperText Markup Language)

Linguagem de marcao de pginas da web.


Contm instrues de formatao e contedo que so
usadas pelo navegador para apresentar a pgina web ao
usurio.

Ex.:
<html>
<head>
<title>ttulo da pgina</title>
</head>
<body>contedo da pgina</body>
</html>
HTTP (HyperText Transfer Protocol)

Protocolo (linguagem comum) usado para comunicao


entre navegador e servidor web.
Permite interaes simples de requisio (requisio HTTP)
e resposta (resposta HTTP).

Ex. 1: navegador usa requisio HTTP para solicitar uma


pgina HTML ao servidor web.

Ex. 2: servidor web usa resposta HTTP para retornar uma


pgina HTML ao navegador.
Aula 2
Tags HTML
Tag Descrio
<html> define os limites do documento HTML
<head> define os limites do cabealho do documento
<title> define o ttulo do documento HTML
<body> define os limites do corpo do documento
<h1> um cabealho de primeiro nvel
<p> um novo bloco
<br> uma quebra de linha
<a> ncora para inserir links
<center> centraliza o contedo
<form> define um formulrio para campos de entrada

<input> define um campo de entrada de um formulrio


<img> insere uma imagem
Atributos de tags HTML
Tag Atributo Descrio
<h1>,<p> align alinha texto: esq., dir., centro, justificado
<a> href define a pgina que deve ser acessada
<form> method tipo de requisio HTTP
<form> action recurso que deve ser contactado
<input> type tipo de campo de entrada
<input> name nome do campo de entrada
<input> value contedo do campo de entrada
<img> src local e nome do arquivo de imagem
Um exemplo de documento HTML

<html><!-- isto um comentrio -->


<head><title>Pgina Pessoal</title></head>
<body>
<h1 align="center">Pgina Pessoal de Alisson</h1>
<p align="right"><img src="eu.jpg"/><br/>
<a href="http://goo.gl/WnuAH">Veja aqui o meu perfil</a>
</p>
<center>
<form method="POST" action="loginServlet">
Nome: <input type="text" name="pNome"/><br/>
Senha: <input type="password" name="pSenha"/><br/>
<input type="submit" value="Login"/>
</form>
</center>
</body>
</html>
Um exemplo de documento HTML
Como o navegador e o servidor web
interagem? (relembrando)
1. O usurio clica em um link ou digita um endereo (URL) no
navegador
2. O navegador formata a requisio (requisio HTTP) e a
envia ao servidor web
3. O servidor web encontra o recurso solicitado (pgina HTML)
4. O servidor web formata a resposta (resposta HTTP) e a
envia ao navegador
5. O navegador recebe, processa e apresenta a pgina HTML
ao usurio
A resposta HTTP

Elementos principais:

status code (cdigo de retorno)


tipo de contedo (texto, imagem, HTML, etc.)
o contedo (o contedo do texto, da imagem, do HTML, etc.)
Exemplo de resposta HTTP

HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=0AAB6C8DE; Path=/testEL
Content-Type: text/html
Content-Length: 397
Date: Wed, 19 Nov 2003 03:25:40 GMT
Server: Apache-Coyote/1.1
Connection: close

<html><!-- uma pgina HTML de exemplo -->


<head><title>Pgina Pessoal</title></head>
<body><h1 align="center">Pgina Pessoal de
Alisson</h1>
...
A requisio HTTP

Elementos principais:

mtodo HTTP (a ao a ser realizada: GET, POST...)


o recurso a ser acessado (uma URL)
parmetros de formulrio (como argumentos de um mtodo)
Exemplo de requisio HTTP GET

GET /loginServlet?pNome=alisson&pSenha=123 HTTP/1.1


Host: localhost
User-Agent: Mozilla/4.0 (Ubuntu Linux...)
Accept: text/html,application/xml,image/jpeg,video/x-png...
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8,q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Exemplo de requisio HTTP POST

POST /loginServlet HTTP/1.1


Host: localhost
User-Agent: Mozilla/4.0 (Ubuntu Linux...)
Accept: text/html,application/xml,image/jpeg,video/x-png...
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8,q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

pNome=alisson&pSenha=123
Requisio GET ou POST?

O nmero total de caracteres em uma requisio GET


limitado

As informaes enviadas em uma requisio GET aparecem


na barra de endereos do navegador

O usurio pode criar bookmarks para requisies GET, mas


no para requisies POST
Exerccio: GET ou POST?

1. Usurio envia nome de usurio e senha.


2. Usurio solicita nova pgina via hyperlink.
3. Usurio envia mensagem em uma sala de bate-papo.
4. Usurio aperta um boto para visualizar a prxima pgina.
5. Usurio aperta um boto para se deslogar de um site.
6. Usurio aperta o boto "voltar" no navegador.
7. Usurio envia nome e endereo ao servidor.
Aula 3
Uniform Resource Locator (URL)

http://www.google.com:80/calendar/b/0/render?tab=mc&pli=1

Protocolo - informa ao servidor o protocolo de comunicao


que deve ser usado (http, https, ftp...)
Servidor - o nome que identifica o servidor fsico a ser
contactado (mapeia para um nico endereo IP)
Porta (opcional) - a porta que identifica a aplicao a ser
contactada no servidor fsico (80 por padro)
Caminho (opcional) - a hierarquia de diretrios onde est
localizado o recurso no servidor (diretrio raiz por padro).
Recurso (opcional) - o nome do recurso que se deseja
recuperar do servidor (index.html por padro)
Parmetros (opcional) - os parmetros de uma requisio do
tipo GET (inicia com "?" e cada par separado por "&")
Servidor web Apache

Ubuntu:

sudo apt-get install apache2


sudo /etc/init.d/apache2 start | stop | restart
diretrio raiz do servidor: /var/www/

Windows:

acessar http://httpd.apache.org/
fazer download e instalar o servidor

Testando a instalao:
acessar http://localhost
O que servidores web no fazem?

Servidores web no criam pginas ou recursos que no


existem antes da requisio.

Servidores web no escrevem informaes em arquivos ou em


bancos de dados.
Como mostrar contedo dinmico em
uma pgina HTML?
<html>
<head/>
<body>
A data/hora atual 17/08/2011 21h30min
</body>
</html>
Precisamos de algo mais do que um
servidor web
Precisamos de um servidor web que gere recursos ou pginas
HTML dinamicamente, no momento da requisio.

O cliente (navegador) no precisa saber se o recurso ou a


pgina retornada j existia ou foi gerada no momento da
requisio.
Precisamos de um continer web

um servidor web que recebe uma requisio HTTP e retorna


uma resposta HTTP contendo um recurso j existente ou
criado dinamicamente para atender quela requisio
especfica.

O recurso retornado por um continer web geralmente criado


por uma aplicao web (no caso de Java, so servlets).

Um continer web pode conter diversas aplicaes web


(servlets), cada uma responsvel por atender certos tipos de
requisio HTTP e criar certos tipos de recursos.
Como o navegador e o continer web
interagem?
1. Usurio clica em um link ou digita um endereo (URL) no
navegador
2. Navegador formata a requisio (requisio HTTP) e a
envia ao continer web
3. O continer web encaminha a requisio HTTP aplicao
web (servlet) que deve tratar aquela requisio
4. A aplicao web (servlet) gera a pgina solicitada e a
devolve ao continer web
5. O continer web formata a resposta (resposta HTTP) e a
envia ao navegador
6. O navegador recebe, processa e apresenta a pgina
HTML ao usurio
O que o continer faz com uma
requisio HTTP?
1. Verifica que a URL de uma servlet, e no de uma pgina
2. Cria um objeto HttpServletRequest contendo as informaes e
parmetros da requisio HTTP
3. Cria um objeto HttpServletResponse vazio
4. Invoca o mtodo service() da servlet, passando os 2 objetos
5. O mtodo service() invoca o mtodo doGet() ou o mtodo doPost()
da servlet, dependendo do tipo da requisio HTTP
6. O doGet() ou doPost() cria o recurso dinamicamente e o insere no
objeto HttpServletResponse
7. O continer converte o objeto HttpServletResponse em uma
resposta HTTP e a envia ao navegador
8. O continer destri os objetos HttpServletRequest e
HttpServletResponse
Como o cdigo de uma servlet?

// arquivo MinhaServlet.java
import javax.servlet.http.*;
import java.io.*;

public class MinhaServlet extends HttpServlet {


public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
java.util.Date agora = new java.util.Date();
out.println("<html><head/><body>A data/hora atual " +
agora + "</body></html>");
}
}
Tomcat: um continer web de
aplicaes Java
acessar http://tomcat.apache.org/
fazer download e descompactar o continer web

Ubuntu:
executar $TOMCAT_HOME/bin/startup.sh

Windows:
executar %TOMCAT_HOME%/bin/startup.bat

Testando a instalao:
acessar http://localhost:8080
Estrutura de diretrios do Tomcat

- <diretrio_instalao_tomcat>
- webapps
- <diretrio_aplicao_web> // document root
- index.html // pginas HTML
- hora.jsp // pginas JSP
- WEB-INF // tudo maisculo com hfen
- web.xml // descritor de implantao/tudo
minsculo
- classes // tudo minsculo
- MinhaServlet.class // servlets compiladas
- lib // opcional
- biblioteca1.jar // dependncias (.jar)
Estrutura de diretrios no Eclipse

Tipo de projeto: Dynamic Web Project

- <nome_projeto_web_dinamico>
- Java Resources/src
- MinhaServlet.java // cdigo da servlet
- Web Content
- index.html // pginas HTML
- hora.jsp // pginas JSP
- WEB-INF
- web.xml // descritor de implantao
- lib
- biblioteca1.jar // dependncias (.jar)
Mapeando uma URL para a servlet
usando o Descritor de Implantao
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1">
<!-- arquivo web.xml -->
<web-app>
<servlet>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<servlet-class>MinhaServlet</servlet-class> <!-- real -->
</servlet>

<servlet-mapping>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<url-pattern>/hora</url-pattern> <!-- externo -->
</servlet-mapping>
</web-app>
Criando uma pgina HTML para
chamar a servlet
<!-- arquivo index.html -->
<html>
<head/>
<body>
<a href="hora">Clique para ver a data/hora</a>
</body>
</html>
Aula 4
Recuperando parmetros passados a
uma servlet
// arquivo MinhaServlet.java
import javax.servlet.http.*;
import java.io.*;

public class MinhaServlet extends HttpServlet {


public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
String paramNome = request.getParameter("pNome");
PrintWriter out = response.getWriter();
out.println("<html><head/><body>O nome digitado "
+ paramNome + "</body></html>");
}
}
Exerccio: servlet

Crie uma servlet para imprimir o seu nome e uma pgina


HTML para invocar a sua servlet.

Obs.: no esquea de criar o descritor de implantao da


servlet.
Aula 5
Inserir HTML em cdigo Java fede!!

Difcil de ler
Difcil de manter
Impossvel de reusar o cdigo HTML em outro contexto
Impossvel de reusar a lgica de negcio em uma aplicao
Swing ou J2ME
Alto acoplamento entre as camadas de apresentao e de
negcio
E se inserssemos cdigo Java em
pginas HTML?
<html>
<head/>
<body>
A data/hora atual <!-- cdigo Java aqui -->
</body>
</html>
Mas isso uma pgina JSP!!!

<!-- arquivo hora.jsp usando scriptlet -->


<html>
<head/>
<body>
A data/hora atual
<%
// insira o cdigo Java aqui
%>
</body>
</html>
Mas isso uma pgina JSP!!!

<!-- arquivo hora.jsp usando scriptlet -->


<html>
<head/>
<body>
A data/hora atual
<%
// isso um scriptlet que cria um objeto com a hora
atual do servidor e a imprime
java.util.Date agora = new java.util.Date();
out.print(agora);
%>
</body>
</html>
Inserir lgica de aplicao em cdigo
HTML tambm fede!!
Difcil de ler
Difcil de manter
Impossvel de reusar o cdigo HTML em outro contexto
Impossvel de reusar a lgica de negcio em uma aplicao
Swing ou J2ME
Alto acoplamento entre as camadas de apresentao e de
negcio
hora.jsp: apenas apresenta resultado
da lgica (camada de apresentao)
<!-- arquivo hora.jsp usando scriplet -->
<html>
<head/>
<body>
A data/hora atual
<%
// isso um scriptlet que imprime atributo chamado
"dataHoraAtual" mas no contm lgica da aplicao
out.print(request.getAttribute("dataHoraAtual"));
%>
</body>
</html>
MinhaServlet.java: lgica da aplicao
+ encaminhamento para pgina JSP
// arquivo MinhaServlet.java contendo lgica da aplicao
import javax.servlet.*; import javax.servlet.http.*; import java.io.*;
public class MinhaServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws IOException, ServletException {
java.util.Date agora = new java.util.Date(); // lgica da aplic.
request.setAttribute("dataHoraAtual", agora); // insere atributo
RequestDispatcher dispatcher =
request.getRequestDispatcher("hora.jsp"); // aponta p/ hora.jsp
dispatcher.forward(request, response); // encaminha p/ JSP
}}
hora.jsp usando expresso

<!-- arquivo hora.jsp usando expresso -->


<html>
<head/>
<body>
A data/hora atual
<%=
// isso uma expresso que imprime atributo
chamado "dataHoraAtual"
request.getAttribute("dataHoraAtual")
%>
</body>
</html>
hora.jsp usando Expression Language
(EL)
<!-- arquivo hora.jsp usando Expression Language (EL) -->
<html>
<head/>
<body>
A data/hora atual
<!--
isso uma Expression Language (EL) que imprime
atributo chamado "dataHoraAtual"
-->
${dataHoraAtual}
</body>
</html>
Mas como podemos reusar tambm a
lgica de negcio da aplicao?
Vamos dividir a aplicao em trs camadas:

Model - encapsula o estado da aplicao e a sua lgica de


atualizao (POJO, conexo com banco de dados)

View - contm as pginas que so apresentadas ao usurio


atravs do navegador (HTML, JSP)

Controller - recebe requisies, solicita a atualizao ou


recupera estado do Model e disponibiliza o estado do Model
para a View (servlet)
index.html (pgina inicial)

<!-- arquivo index.html -->


<html>
<head />
<body>
<form method="GET" action="calculadoraServlet">
Nmero 1: <input type="number" name="num1" />
Nmero 2: <input type="number" name="num2" />
Somar <input type="radio" name="operacao" value="somar" />
Multiplicar <input type="radio" name="operacao"
value="multiplicar" />
<input type="submit" value="Calcular" />
</form>
</body>
</html>
ServletCalculadoraWeb.java em
padro Model-View-Controller
// arquivo ServletCalculadoraWeb.java (camada Controller)
package controller;
import javax.servlet.*;import javax.servlet.http.*;import java.io.*;import model.*;
public class ServletCalculadoraWeb extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse
resp) throws IOException, ServletException {
String paramNum1 = req.getParameter("num1");
String paramNum2 = req.getParameter("num2");
String paramOperacao = req.getParameter("operacao");
Calculadora calculadora = new Calculadora();
int total = calculadora.calcular(paramNum1, paramNum2, paramOperacao);
req.setAttribute("totalCalculo", total);
RequestDispatcher reqDispatcher =
req.getRequestDispatcher("resultado.jsp");
reqDispatcher.forward(req, resp);
}}
Criando o objeto Calculadora da
camada Model
// arquivo Calculadora.java (camada Model)
package model; // coloque a classe dentro de um pacote
public class Calculadora {
public int calcular(String paramNum1, String paramNum2, String
paramOperacao) {
int num1 = Integer.parseInt(paramNum1);
int num2 = Integer.parseInt(paramNum2);
int total = 0;
if (paramOperacao.equals("somar")) {
total = num1 + num2;
} else {
total = num1 * num2;
}
return total;
}}
resultado.jsp em padro
Model-View-Controller usando scriptlet
<!-- arquivo resultado.jsp usando EL -->
<html>
<head />
<body>O resultado do clculo ${totalCalculo}.
</body>
</html>
web.xml (descritor de implantao)

<!-- arquivo web.xml -->


<web-app>
<servlet>
<servlet-name>MinhaServlet</servlet-name>
<servlet-class>controller.ServletCalculadoraWeb</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>MinhaServlet</servlet-name>
<url-pattern>/calculadoraServlet</url-pattern>
</servlet-mapping>
</web-app>
Aula 6
Uma servlet genrica da camada
Controller
import javax.servlet.*;import javax.servlet.http.*;import java.io.*;
public class ControllerServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
// recupera os parmetros da requisio
// invoca um objeto do Model passando os parmetros
// insere o estado do Model em um atributo da requisio
// encaminha a requisio para uma pgina JSP
}
}
Recuperando parmetros da requisio
na servlet
import javax.servlet.*;import javax.servlet.http.*;import java.io.*;
public class ControllerServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {
String param = request.getParameter("<nomeParam>");
// invoca um objeto do Model passando os parmetros
// insere o estado do Model em um atributo da requisio
// encaminha a requisio para uma pgina JSP
}
}
Exerccio: JSP

Crie uma pgina HTML com um formulrio que possui uma


caixa de entrada de texto e um boto de envio.

Crie uma servlet que (i) recebe o texto do formulrio da pgina


HTML, (ii) cria um objeto do tipo "Usuario" para armazenar o
texto recebido em um atributo chamado "nome" e (iii)
encaminha o objeto criado para uma pgina JSP.

Crie 3 pginas JSP que apresentam o contedo do


atributo "nome" do objeto recebido da servlet, sendo uma
usando scriptlet, outra usando expresso e a ltima usando
Expression Language.
Aula 7
Implantando aplicaes web

O arquivo WAR um arquivo ZIP com a extenso ".war".

Contm os arquivos e os diretrios que esto dentro do


diretrio da aplicao web (sem contar com o prprio diretrio
raiz da aplicao web).

Alm disso, pode conter um diretrio "META-INF" com um


arquivo "MANIFEST.MF", que descreve as dependncias de
biblioteca da aplicao web.

O arquivo .war deve ser colocado no diretrio "webapps" do


Tomcat e o seu nome ser utilizado como nome da aplicao
web.
MANIFEST.MF

Manifest-Version: 1.0
Class-Path: lib/mysql-connector-java-3.0.11-stable-bin.jar
lib/forms-1.0.5.jar theme/alloy.jar
Acessibilidade de arquivos da
aplicao web
Recursos (pginas HTML, JSP...) acessveis diretamente aos
usurios so colocados na raiz do arquivo .war ou na raiz do
diretrio da aplicao web.

Recursos localizados no diretrio "WEB-INF" ou no diretrio


"META-INF" no so acessveis diretamente pelos usurios.

Portanto, todos os arquivos que no devem ser acessados


diretamente pelos usurios devem ser colocados dentro do
diretrio "WEB-INF" ou do diretrio "META-INF".
Mapeando URLs a servlets:
combinao exata
<!-- arquivo web.xml -->
<web-app>
<servlet>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<servlet-class>MinhaServlet</servlet-class> <!-- real -->
</servlet>

<servlet-mapping>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<url-pattern>/virtual/hora.do</url-pattern> <!-- comea sempre
com "/" e pode conter diretrios virtuais e extenses virtuais -->
</servlet-mapping>
</web-app>
Mapeando URLs a servlets:
combinao por diretrio
<!-- arquivo web.xml -->
<web-app>
<servlet>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<servlet-class>MinhaServlet</servlet-class> <!-- real -->
</servlet>

<servlet-mapping>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<url-pattern>/virtual/*</url-pattern> <!-- comea sempre
com "/", pode conter diretrios virtuais e termina sempre com
"*" -->
</servlet-mapping>
</web-app>
Mapeando URLs a servlets:
combinao por extenso
<!-- arquivo web.xml -->
<web-app>
<servlet>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<servlet-class>MinhaServlet</servlet-class> <!-- real -->
</servlet>

<servlet-mapping>
<servlet-name>ServletHora</servlet-name> <!-- interno -->
<url-pattern>*.do</url-pattern> <!-- comea sempre com "*" e
seguido por uma extenso -->
</servlet-mapping>
</web-app>
Mapeando URLs a servlets

O continer busca por combinaes de URLs na seguinte


ordem: combinao exata, combinao por diretrio,
combinao por extenso.

Se uma requisio corresponde a mais de um tipo de


combinao, a mais especfica escolhida pelo continer.
Exemplo: /foo/bar/myStuff.do mapeada para /foo/bar/* ao
invs de /foo/*.
Qual servlet ser invocada?

<web-app>...
<servlet-mapping>
<servlet-name>ServletUm</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletDois</servlet-name>
<url-pattern>/fooStuff/bar</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ServletTres</servlet-name>
<url-pattern>/fooStuff/*</url-pattern>
</servlet-mapping>
</web-app>
Qual servlet ser invocada?

1. http://localhost:8080/MapTest/blue.do
2. http://localhost:8080/MapTest/fooStuff/bar
3. http://localhost:8080/MapTest/fooStuff/bar/blue.do
4. http://localhost:8080/MapTest/fooStuff/blue.do
5. http://localhost:8080/MapTest/fred/blue.do
6. http://localhost:8080/MapTest/fooStuff
7. http://localhost:8080/MapTest/fooStuff/bar/foo.fo
8. http://localhost:8080/MapTest/fred/blue.fo
Qual servlet ser invocada?

1. ServletUm
2. ServletDois
3. ServletTres
4. ServletTres
5. ServletUm
6. ServletTres
7. ServletTres
8. 404 no encontrado
Configurando pginas de boas-vindas

Arquivos de boas-vindas so procurados sempre que a URL da


requisio no aponta para uma servlet ou recurso especfico,
mas para um diretrio ou para a raiz do servidor.

<web-app>
...
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>
Qual pgina ser retornada?

- webapps <web-app>
- MyTestApp ...
- index.html <welcome-file-list>
- search <welcome-file>index.html</welcome-file
- default.jsp >
- registration <welcome-file>default.jsp</welcome-file
- index.html >
- newMember </welcome-file-list>
- foo.txt </web-app>

1. http://localhost:8080/MyTestApp/
2. http://localhost:8080/MyTestApp/registration/
3. http://localhost:8080/MyTestApp/search
4. http://localhost:8080/MyTestApp/registration/newMember/
Qual pgina ser retornada?

1. MyTestApp/index.html
2. MyTestApp/registration/index.html
3. MyTestApp/search/default.jsp // se existe um "index.html"
dentro de "search", este seria retornado ao invs de
"default.jsp
4. 404 no encontrado // ou a lista de arquivos do diretrio
Configurando pginas de erro

<web-app>
...
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/paginaErro.jsp</location>
</error-page>

<error-page>
<error-code>404</error-code>
<location>/naoEncontrado.jsp</location>
</error-page>
</web-app>
Configurando parmetros de
inicializao das servlets
Um parmetro de inicializao de servlet um par chave-valor que
disponibilizado servlet no momento de sua inicializao.

<web-app>
<servlet>
<servlet-name>ServletHora</servlet-name>
<servlet-class>MinhaServlet</servlet-class>
<init-param>
<param-name>adminEmail</param-name>
<param-value>admin@servidor.com</param-value>
</init-param>
</servlet>
...
</web-app>
Recuperando parmetro de
inicializao na servlet
// arquivo MinhaServlet.java
import javax.servlet.http.*;
import java.io.*;

public class MinhaServlet extends HttpServlet {


public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
out.println(getServletConfig().getInitParameter("adminEmail")
);
}
}
Configurando parmetros de
inicializao das aplicaes web
Um parmetro de inicializao de aplicao um par
chave-valor que disponibilizado a todos os recursos da
aplicao web no momento de sua inicializao.
<web-app>
<servlet>
<servlet-name>ServletHora</servlet-name>
<servlet-class>MinhaServlet</servlet-class>
</servlet>
<context-param>
<param-name>adminEmail</param-name>
<param-value>admin@servidor.com</param-value>
</context-param>
...
</web-app>
Recuperando parmetro de
inicializao de aplicao na servlet
// arquivo MinhaServlet.java
import javax.servlet.http.*;
import java.io.*;

public class MinhaServlet extends HttpServlet {


public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();

out.println(getServletContext().getInitParameter("adminEmail")
);
}
}
Aula 8
Problema: como implementar um
carrinho de compras?
O protocolo HTTP usa conexes sem estado (stateless
connections): o cliente/navegador cria uma conexo HTTP com
o servidor, envia a requisio, recebe a resposta e fecha a
conexo.

Assim, cada requisio HTTP tratada pelo continer Web


como uma requisio de um novo cliente/navegador.

Como possvel, ento, implementar um carrinho de compras


ao qual um cliente adiciona itens em requisies distintas
sem que o carrinho de um cliente receba itens adicionados por
outro cliente?
Em outras palavras...

Como o continer pode reconhecer qual o cliente que est


fazendo a requisio e adicionar/retirar um item apenas do
carrinho daquele cliente especfico?

O continer precisa identificar os clientes que fazem


requisies e manter um estado de conversao (armazenar
informaes) para cada cliente!

Solues erradas:
- usar o endereo IP como identificador
- solicitar ao usurio para se logar antes de usar o carrinho
Soluo

Na primeira requisio do cliente, o continer gera um ID de


sesso nico e o entrega ao cliente junto com a resposta
HTTP.

O cliente envia de volta esse ID de sesso a cada requisio


HTTP subsequente.

O continer verifica o ID de sesso na requisio HTTP,


encontra a sesso correspondente e associa a sesso com a
requisio atual.
A soluo em ao

1. Cliente A faz primeira requisio a MinhaServlet, a qual


armazena as informaes em uma nova sesso, cria o ID de
sesso e o retorna na resposta requisio.
2. Cliente A faz nova requisio a MinhaServlet passando o ID
de sesso, a qual recupera a sesso do cliente A, armazena
novas informaes e retorna a resposta requisio.
3. Cliente B faz primeira requisio a MinhaServlet, a qual
armazena as informaes em uma nova sesso, cria o ID de
sesso e o retorna na resposta requisio.
4. Cliente A faz nova requisio a MinhaServlet passando o ID
de sesso, a qual recupera a sesso do cliente A, armazena
novas informaes e retorna a resposta requisio.
O objeto HTTPSession para
implementar a soluo
Um objeto HTTPSession pode armazenar estado de
conversao atravs de mltiplas requisies do mesmo
cliente.

Ele permanece ativo e disponvel durante toda a sesso de um


cliente especfico.

Podemos us-lo para armazenar tudo o que recebido do


cliente em todas as requisies que este faz durante uma
sesso.
Exemplo usando o objeto
HTTPSession
import javax.servlet.http.*; import java.io.*;
public class MinhaServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
HttpSession session = request.getSession(); // recupera a
sesso existente do cliente; se no existe, cria nova sesso
String atributo = (String)session.getAttribute("atrib");
session.setAttribute("atrib", "valorNovoAtributo");
if (atributo != null) {
session.invalidate(); // destri a sesso do cliente
}
PrintWriter out = response.getWriter();
out.println(atributo);
}}
Mas como o continer reconhece cada
cliente? Onde esto os IDs de sesso?
Os IDs de sesso so trocados entre continer e navegador
atravs de informaes colocadas dentro das requisies e
respostas HTTP.

Essas informaes extras so pares chave-valor chamados


genericamente de cookies. O cookie de ID de sesso se
chama JSESSIONID.

Quando o continer recebe uma requisio HTTP sem o


cookie JSESSIONID, ele adiciona o cookie JSESSIONID na
resposta HTTP, contendo o novo ID de sesso daquele cliente.

Na prxima requisio, o cliente deve adicionar o cookie


JSESSIONID com o seu ID de sesso na requisio HTTP.
A resposta HTTP contendo o novo ID
de sesso do cliente
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=0AAB6C8DE415
Content-Type: text/html
Content-Length: 397
Date: Wed, 19 Nov 2003 03:25:40 GMT
Server: Apache-Coyote/1.1
Connection: close

<html>
...
</html>
A requisio HTTP contendo o ID de
sesso do cliente
POST /usuarioServlet HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0
Cookie: JSESSIONID=0AAB6C8DE415
Accept: text/xml,application/xml,application/xhtml+xml,text/...
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
No se preocupe! O continer cuida
dos IDs de sesso para voc!
Voc s precisa dizer ao continer que quer usar uma sesso
invocando request.getSession().

Se a requisio HTTP inclui um cookie JSESSIONID, o


continer encontra o objeto HTTPSession correspondente.

Seno, o continer cria um objeto HTTPSession, gera um ID


de sesso, cria o cookie JSESSIONID e o adiciona resposta
HTTP a ser enviada ao cliente.
E se eu quiser saber se a sesso j
existia ou se ela acaba de ser criada?
import javax.servlet.http.*; import java.io.*;
public class MinhaServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
HttpSession session = request.getSession(); // recupera a
sesso existente do cliente; se no existe, cria nova sesso
String atributo = (String)session.getAttribute("atrib");
session.setAttribute("atrib", "valorNovoAtributo");
if (!session.isNew()) { // verifica se uma nova sesso
session.invalidate(); // destri a sesso do cliente
}
PrintWriter out = response.getWriter();
out.println(atributo);
}}
E se eu quiser usar uma sesso
apenas se ela j existir?
import javax.servlet.http.*; import java.io.*;
public class MinhaServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
PrintWriter out = response.getWriter();
HttpSession session = request.getSession(false); //
recupera sesso existente ou null
if (session == null) { // no existe sesso deste cliente
request.getSession(); // cria nova sesso para o cliente
out.println("Uma nova sesso foi criada para o cliente.");
} else { // j existe sesso deste cliente
session.invalidate(); // destri a sesso existente
out.println("A sesso existente do cliente foi destruda.");
}}}
E se o cliente/navegador no aceitar
cookies?
Os cookies tm prazo de validade e podem precisar ser
armazenados em arquivos no ambiente do cliente.

Por questes de segurana ou limitaes do ambiente, alguns


navegadores tm a aceitao de cookies desabilitada.

A desativao de cookies no navegador impossibilita que os


IDs de sesso sejam enviados ao continer na requisio
HTTP.

Nesses casos, o continer no consegue identificar o cliente e


sempre cria uma nova sesso, "esquecendo" o histrico de
requisies anteriores.
Soluo: reescrita de URLs (URL
rewriting)
Ao invs de adicionar o ID de sesso em um cookie, vamos
adicion-lo ao final de todas as URLs da aplicao Web para
as quais queremos manter a sesso ativa.

O navegador ir receber uma pgina Web com todas as URLs


contendo uma informao extra: o ID da sesso.

Quando o usurio clicar nessas URLs "ampliadas", o continer


ir receber o ID da sesso como parte da URL na requisio
HTTP.

Apesar de ser mais complicado, esse tipo de tratamento para


os IDs de sesso sempre funciona!
Resposta HTTP com reescrita de URLs

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 397
Date: Wed, 19 Nov 2003 03:25:40 GMT
Server: Apache-Coyote/1.1
Connection: close

<html>
<body>
<a
href="http://localhost/usuarioServlet;jsessionid=0AAB6C8DE41
5"> clique aqui</a>
</body>
</html>
Requisio HTTP

GET /usuarioServlet;jsessionid=0AAB6C8DE415 HTTP/1.1


Host: localhost
User-Agent: Mozilla/5.0
Accept: text/xml,application/xml,application/xhtml+xml,text/...
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Ativando a reescrita de URL em uma
servlet
import javax.servlet.http.*; import java.io.*;
public class MinhaServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
response.setContentType("text/html");
HttpSession session = request.getSession();
response.getWriter().println(session.isNew());
if (!session.isNew()) {
session.invalidate();
}
response.getWriter().println("<html><body><a href=\"" +
response.encodeURL("usuarioServlet") + "\">clique
aqui</a></body></html>");
}}
Ativando a reescrita de URL em uma
JSP
Copie o arquivo taglibs-standard-impl-1.2.5.jar do diretrio
<TOMCAT_HOME>/webapps/examples/WEB-INF/lib para o diretrio
WEB-INF/lib da sua aplicao.

<!-- arquivo usuario.jsp -->


<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html><body>
<%
out.print(session.isNew());
if (!session.isNew()) {
session.invalidate();
}
%>
<a href="<c:url value='/usuario.jsp'/>">clique aqui</a>
</body></html>
Destruindo um sesso inativa

Alm de destruir imediatamente uma sesso atravs do mtodo


invalidate(), possvel especificar um tempo limite de inatividade (falta
de requisies) at que uma sesso expire.

Na servlet, invoque session.setMaxInactiveInterval(20*60); para


expirar a sesso atual do cliente em 20 minutos de inatividade.

No descritor de implantao, para expirar qualquer sesso em 20


minutos de inatividade:
<web-app><servlet>...</servlet>
<session-config>
<session-timeout>20</session-timeout>
</session-config>
</web-app>
Usando cookies para outras funes

Voc pode usar cookies para trocar quaisquer pares


chave-valor entre continer e navegador.

O continer envia o cookie ao cliente, e o cliente o envia de


volta a cada requisio subsequente.

Por padro, cookies de sesso expiram quando o navegador


fechado, mas possvel configurar um cookie para persistir no
cliente mesmo aps o fechamento do navegador.

Cookies podem ser criados ou recuperados tanto em servlets


como em pginas JSP.
Adicionando um cookie na resposta
HTTP a partir de uma servlet
import javax.servlet.http.*; import java.io.*;
public class MinhaServlet extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
Cookie cookie = new Cookie("nomeCookie",
"valorCookie"); // cria um cookie de nome "nomeCookie" e
valor "valorCookie"
cookie.setMaxAge(60); // o tempo de vida do cookie de 1
minuto; use -1 para expirar com o fechamento do navegador
response.addCookie(cookie); // adiciona o novo cookie
resposta HTTP
response.getWriter().println("Cookie adicionado:" +
cookie.getName() + "/" + cookie.getValue());
}}
Recuperando um cookie da requisio
HTTP a partir de uma JSP
<!-- arquivo usuario.jsp -->
<html><body>
<%
Cookie[] cookies = request.getCookies();
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookie.getName().equals("nomeCookie")) {
out.print("Cookie recuperado: " + cookie.getName() +
"/" + cookie.getValue());
break;
}
}
%>
</body></html>
Aula 9
Conectando a aplicao Web a um
banco de dados MySQL via Tomcat
Baixe e instale o servidor MySQL a partir
de http://www.mysql.com/downloads/mysql/ ou via "sudo
apt-get install mysql-server mysql-client".

Execute $MYSQL_HOME/bin/mysql -u root -p


($MYSQL_HOME o diretrio de instalao do MySQL) ou
apenas mysql -u root -p no Linux.

Execute GRANT ALL PRIVILEGES ON *.* TO


usuario@localhost IDENTIFIED BY 'senha' WITH GRANT
OPTION; CREATE DATABASE baseDados; USE
baseDados; CREATE TABLE tabela (id int not null
auto_increment primary key, nome varchar(25)); INSERT INTO
tabela VALUES(null, 'hello'); SELECT * FROM tabela;
Conectando a aplicao Web a um
banco de dados MySQL via Tomcat
Baixe e descompacte o conector JDBC para MySQL disponvel
em http://www.mysql.com/downloads/connector/j/

Copie o arquivo "mysql-connector-java-5.1.44-bin.jar" para


"$TOMCAT_HOME/lib" ($TOMCAT_HOME o diretrio de
instalao do Tomcat) ou para o diretrio WEB-INF/lib do seu
projeto web.

Edite o arquivo "$TOMCAT_HOME/conf/server.xml",


adicionando uma tag "<Context>" para a sua aplicao entre
as tags "<Host appBase='webapps'...>" e "</Host>".
Conectando a aplicao Web a um
banco de dados MySQL via Tomcat
// arquivo $TOMCAT_HOME/conf/server.xml
<Host appBase='webapps'...>
...
<Context docBase="app1" path="/app1" reloadable="true"
source="org.eclipse.jst.jee.server:app1">
<Resource name="jdbc/Teste"
auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="usuario"
password="senha" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/baseDados?autoReconnect=true" />
</Context>
...
</Host>
Conectando a aplicao Web a um
banco de dados MySQL via Tomcat
Edite o arquivo "WEB-INF/web.xml" da sua aplicao,
adicionando o seguinte cdigo entre as tags "<web-app>" e
"</web-app>".

// arquivo WEB-INF/web.xml
<web-app>
...
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/Teste</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
Conectando a aplicao Web a um
banco de dados MySQL via Tomcat
import javax.sql.*; import java.sql.*; import javax.naming.*; ...
public void doGet(HttpServletRequest request, ...) throws ... {
try {
Context ctx = new InitialContext(); // cria um contexto
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/Teste"); //
URL p/ recuperar DataSource especificado no arquivo "server.xml"
Connection conn = ds.getConnection(); // cria conexo
Statement st =
conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet result = st.executeQuery("select * from tabela;");
result.first();
response.getWriter().println(result.getString(2));
conn.close(); // fecha a conexo
} catch(Exception e) { // captura algum erro, se ocorrer
response.getWriter().println(e.getMessage()); }}
Exerccio: carrinho de compras

Uma pgina HTML com caixa de texto e botes adicionar e


checkout. O usurio digita o nome do produto e o adiciona ao
carrinho. A qualquer momento, pode realizar checkout.
Uma servlet para adicionar o produto ao carrinho.
Uma pgina JSP para listar os produtos do carrinho sempre que o
usurio adicionar um produto.
Uma servlet para realizar checkout. O checkout o registro dos
produtos do carrinho em tabela de banco de dados. A URL do
DataSource deve ser um parmetro de inicializao da servlet.
Uma pgina JSP para confirmar ou no o checkout. Em caso de
checkout confirmado, listar os produtos da tabela.

Use Eclipse para resolver o exerccio. Clique aqui e veja como!


Exerccio: carrinho de compras

<!-- arquivo index.html -->


<html>
<body>
<form method="POST" action="servletAdicionar">
<input type="text" name="produto" />
<input type="submit" value="adicionar" />
</form>
<form method="POST" action="servletCheckout">
<input type="submit" value="checkout" />
</form>
</body>
</html>
Exerccio: carrinho de compras

<!-- arquivo checkoutRealizado.jsp -->


<%@ page import="javax.naming.*,javax.sql.*,java.sql.*"%><%@
page import="java.util.*"%>
<html><body>
<% if ((Boolean) request.getAttribute("checkoutRealizado") == false) {
%>
Ateno! O checkout no pde ser concludo com sucesso!
<% } else { %>
Checkout realizado com sucesso!<br/><br/>Os itens comprados
foram:<br/>
<%
List produtosBanco = (List) request .getAttribute("produtosBanco");
for (int i = 0; i < produtosBanco.size(); i++) {
out.println(produtosBanco.get(i) + "<br/>");
}}
%></body></html>
Exerccio: carrinho de compras

<!-- arquivo web.xml --><web-app>


<servlet>
<servlet-name>adicionar</servlet-name>
<servlet-class>AdicionarServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>adicionar</servlet-name>
<url-pattern>/servletAdicionar</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>checkout</servlet-name>
<servlet-class>CheckoutServlet</servlet-class>
insira aqui o cdigo do parmetro de inicializao da servlet
</servlet>
<servlet-mapping>
<servlet-name>checkout</servlet-name>
<url-pattern>/servletCheckout</url-pattern>
</servlet-mapping>
insira aqui o cdigo da tag <resource-ref> para acesso ao banco de dados
</web-app>
FIM

You might also like