Material cedido por:
Daniel Arraes Pereira
[email protected]
Java Avançado
Java Servlets
Guilherme Kely de Melo Oliveira
[email protected]
Jobson Ronan Jeronimo da Silva
[email protected]
Servlets

É a tecnologia Java em resposta à CGI
(Common
Gateway
Interface).
São
programas que rodam no servidor Web,
atuando como camada intermediária entre
uma requisição vinda de um cliente HTTP
e banco de dados ou aplicações no
servidor Web.
Common Gateway Interface: É uma especificação que permite que um
programa, escrito em uma linguagem de programação qualquer, possa
responder a requisições HTTP encaminhadas por um servidor web.
2
Servlets

Suas tarefas são:
Ler todos os dados enviados pelo
usuário.
 Gerar resultados.
 Formatar os resultados.
 Ajustar
os parâmetros da resposta
HTTP.
 Enviar a resposta ao cliente.

3
Servlets

Por que usá-los?
Facilidade de uso.
 Facilidade de desenvolvimento.
 Maturidade da linguagem Java. Servlets
são classes Java.
 Eficientes
 Independentes de browsers.
 Robustez,
segurança, Multiplataforma,
possuem
praticamente
toda
a
plataforma Java disponível.

4
Servlets

Como usá-los?



Escreve uma classe que extenda a classe
Servlet sobrescrevendo os métodos relativos
ao tipos de requisição.
Cria a estrutura de dirétorios necessária e faz
o deploy do servlet em tal estrutura.
Realiza o mapeamento do servlet em uma(s)
URL através do deployment descriptor da
aplicação
5
Servlet Hello World
public class HelloWorldServlet extends HttpServlet {
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><head><title>Hi</title></head>");
out.println("<body>");
out.println("Hello World!!");
out.println("</body>");
out.println("</html>");
out.close();
}
6
Servlet Hello World - Deploy

webapps
ROOT – Contexto principal. URL default.
 [Nome do contexto]

• Arquivos JSP
• META-INF
• WEB-INF
– classes – Classes da aplicação (Servlets, ...)
– lib – bibliotecas específicas da aplicação. *.jar.
– Deployment Descriptor (web.xml)
7
Servlet Hello World
Deployment Descriptor (web.xml)

Arquivo que faz o mapeamento entre
URLs e Servlets além de
configurações de segurança,
eventos, filtros, ...
8
Servlet Hello World
Deployment Descriptor (web.xml)
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>HelloWorld</display-name>
<servlet>
<description></description>
<display-name>HelloWorldServlet</display-name>
<servlet-name>HelloWorldServlet</servlet-name>
<servlet-class>HelloWorldServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloWorldServlet</servlet-name>
<url-pattern>/HelloWorldServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
9
Servlet Hello World

Executando

http://localhost:8080/HelloWorld/Hello
WorldServlet
10
Ciclo de vida de um Servlet

Antes que o Servlet esteja pronto para
atender as requisições do cliente, o
container precisa realizar algumas
tarefas para levar o Servlet até um
estado no qual este possa atender tais
requisições.
11
Ciclo de vida de um Servlet
12
Ciclo de Vida de Um Servlet
Método
Descrição
void init(ServletConfig)
Invocado pelo container para iniciar o
servlet. Recebe parâmetros
especificados no deployment descriptor
da aplicação
void
service(ServletRequest,
Invocado pelo container para servir
requisições dos clientes. Ele é quem na
verdade intercepta as chamadas.
Delega essas aos métodos
correspondentes (doGet, doPost, ...)
ServletResponse)
void destroy( )
Invocado pelo container quando decide
descarregar o servlet.
13
Método service()
14
A interface ServletConfig
Método
Descrição
String getInitParameter(String nome)
Retorna o valor do parâmetro. Se o
parâmetro não estiver disponível este
método retorna null.
Enumeration getInitParameterNames( )
Retorna uma enumeração de Strings
com todos os nomes dos parâmetros.
String getServletName( )
Retorna o nome do servlet especificado no arquivo web.xml.
15
Parâmetros de inicialização
<web-app>
<servlet>
<servlet-name>exemplo</servlet-name>
<servlet-class>curso.ExemploServlet</servlet-class>
<init-param>
<param-name>JDBCDriver</param-name>
<param-value>sun.jdbc.odbc.JdbcOdbcDriver</paramvalue>
</init-param>
<load-on-startup>1</load-on-startup> // preloading
</servlet>
</web-app>
16
Servlets e requisições

Suportam todos os tipos de requisições.
Mapeadas em chamadas de métodos na
instancia do Servlet em questão.







GET – doGet(...)
POST – doPost(...)
PUT – doPut(...)
DELETE – doDelete(...)
TRACE – doTrace(...)
HEAD – doHead(...)
OPTIONS – doOptions(...)
17
Servlets e requisições
Características
GET
POST
Tipo de dados
Texto
Texto ou binário
Quantidade de
dados
Máximo de 255
caracteres
Ilimitado
Visibilidade
Dados fazem
parte da URL e
podem ser
vistos
Dados não fazem
parte da URL e sim
do corpo da
mensagem. Não
podem ser vistos
18
Servlets e requisições

Exemplos

GET
http://www.cin.ufpe.br/servlet/ServletProcurar?numero=12&c
odigo=1

POST
<form method=“POST”
action=“http://www.cin.ufpe.br/servlet/ServletProcurar”>
<input type=“text” name=“numero”>
<input type=“text” name=“codigo”>
<input type=“submit”>
</form>
19
Servlets e requisições: analisando

Interface ServletRequest



Provê métodos de acesso ao conteúdo da
requisição que são relevantes a qualquer
protocolo.
Pacote javax.servlet.*;
Interface HttpServletRequest



Extende ServletRequest
Provê métodos relativos ao protocolo HTTP.
Pacote javax.servlet.http.*;
20
ServletRequest
Método
Descrição
String getParameter(String
paramName)
Retorna o valor associado ao
determinado parâmetro.
String[]
getParameterValues(String
name)
Retorna todos os valores associados
ao determinado parâmetro. (List
boxes, Check boxes)
Enumeration
getParameterNames()
Retorna os nomes dos parâmetros
passados na requisição.
21
HttpServletRequest
Método
Descrição
String getHeader(String
headerName)
Retorna um dos valores associados
ao Header.
Enumeration
getHeaderValues(String
headerName)
Retorna todos os valores associados
ao Header
Enumeration
getHeaderNames()
Retorna os nomes dos Headers.
22
Servlets e requisições: Exemplo
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException {
String nome = request.getParameter(“name”);
int idade =
Integer.parseInt(request.getParameter(“age”));
fachada.cadastrarCliente(new Cliente(nome, idade));
response.sendRedirect(“sucesso.jsp”);
}
23
Prática 1

Escreva um servlet que receba o nome e o
telefone do usuário e retorne tais dados
formatados em uma string passada ao
servlet como parâmetro de inicialização

Use o método estático format da classe
String
24
Servlets - Enviando respostas

Interface ServletResponse
Provê métodos de resposta que são
relevantes a qualquer protocolo.
 Pacote javax.servlet.*;


Interface HttpServletResponse
Extende ServletResponse
 Provê métodos relativos ao protocolo
HTTP.
 Pacote javax.servlet.http.*;

25
ServletResponse
Método
Descrição
PrintWriter getWriter()
Retorna um java.io.PrintWriter, que
pode ser usado para enviar texto ao
cliente.
ServletOutputStream
getOutputStream()
Retorna um
javax.servlet.ServletOutputStream, que
pode ser usado para enviar dados
binários ao cliente.
void
setContentType(String
type)
Usado para ajustar o tipo do conteúdo
da resposta. Ex: “text/html”,
“image/jpeg”, “application/jar”
26
HttpServletResponse
Método
Descrição
void setXXXHeader(...)
Seta pares nome / valor para o Header.
(String, Inteiros, Datas)
boolean
containsHeader(String
name)
Retorna se um header com este nome
já está setado.
void sendRedirect(String
location)
Redireciona a chamada à URL
especificada.
27
Servlets – Enviando Repostas:
Exemplo
protected void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
{
res.setContentType("application/jar");
File f = new File("test.jar");
byte[] bytearray = new byte[(int) f.length()];
FileInputStream is = new FileInputStream(f);
is.read(bytearray);
OutputStream os = res.getOutputStream();
os.write(bytearray);
os.flush();
}
28
Prática 2

Crie um servlet que retorne uma
imagem.
29
Contextos
O contexto de uma aplicação é,
fisicamente,
o
conjunto
de
componentes, arquivos: recursos que a
compõem. (dentro do diretório do
contexto).
 Toda aplicação web deve possui um
contexto único.
 http://localhost:8080/contexto/hello
 No caso da API de J2EE, os contextos
são
representados
pela
classe
ServletContext.

30
ServletContext
Classe que representa o contexto
de uma aplicação.
 Serve
para comunicação entre
servlets da mesma aplicação
(através do próprio contexto) e
servlets de aplicações diferentes
(acessando diferentes contextos)
entre outras funcionalidades.

31
ServletContext
Método
Descrição
Object getAttribute(String
name)
Retorna o objeto mapeado ao nome
passado como parâmetro.
void setAttribute(String
name, Object value)
Associa um objeto a um nome no
contexto.
Enumeration
getAttibuteNames()
Lista os nomes de todos os atributos
presentes no contexto.
32
ServletContext
Método
Descrição
Enumeration
getInitParameterNames()
Retorna o nome de todos os
parâmetros de inicialização.
URL getResource(String path)
Retorna um recurso da aplicação.
Podem acessar arquivos dentro de
*.jar, *.war... Livre do sistema de
arquivos
InputStream
getResourceAsStream(String
path)
Retorna um recurso da aplicação.
Podem acessar arquivos dentro de
*.jar, *.war... Livre do sistema de
arquivos
33
ServletContext
Método
Descrição
ServletContext getContext(String uri) Retorna o contexto da URI
passada como parâmetro.
String getServerInfo()
Retorna uma string contendo
informações sobre o
container web.
void log(String msg, Throwable t)
Loga uma exceção com uma
devida mensagem.
34
ServletContext
Método
Descrição
String getMimeType(String file)
Retorna o mime do arquivo
especificado ou null se o mime
não eh conhecido
String getRealPath(String path)
Retorna uma string contendo o
caminho real do caminho relativo
passado como parâmetro.
35
Interface ServletContext
 As
maneiras mais comuns de
acessá-la são:
Através da requisição: … =
request.getServletContext()
 Através do próprio servlet: … =
this.getServletContext()
 Através da configuração: … =
config.getServletContext()

36
Prática 3

Mude o servlet do exercício passado
para que este carregue a image
como um recurso do contexto e para
que descubra o mime da mesma em
tempo de execução.
37
Sessões : Introdução

Motivação:


Problema:


Guardar informações entre requisições de
um cliente
HTTP não mantém estado.
Soluções.




Campos ocultos em formulário.
Cookies
Reescrita de URLs
Sessões
38
Sessões


É uma série de interações requestresponse sem interrupções, ou seja, para
cada requisição parte da sessão, o
servidor pode identificar que a requisição
vem do mesmo cliente
Características:





Armazenadas no lado do servidor.
Possibilidade de se armazenar objetos Java.
Única de cada cliente.
Normalmente implementadas indiretamente
através de Cookies ou reescrita de URLs.
Representada pela classe HttpSession
39
HttpSession
Classe que representa uma sessão.
 Criação / Aquisição


HttpSession s =
request.getSession(boolean create)
• create = true – se a sessão não existir,
esta é criada e depois retornada; caso
exista é, simplesmente, retornada.
• create = false – se a sessão não existir,
retorna null; caso exista retorna a sessão
existente.
40
HttpSession : Exemplo
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException{
HttpSession session = request.getSession(true);
Usuario user = (User) session.getAttribute("usuario");
if (user != null){
//Faça alguma coisa
}else{
session.invalidate();
response.sendRedirect("login.jsp");
}
}
41
HttpSession : Métodos
Método
Descrição
void setAttribute(String alias,
Object objeto)
Armazena um objeto na sessão
corrente. A princípio, só o dono
da sessão pode ter acesso a tal
objeto.
Object getAttribute(String alias)
Retorna o objeto armazenado
com tal apelido.
void removeAttribute(String alias) Remove o objeto armazenado
com tal apelido
42
HttpSession : Métodos
Método
Descrição
void setMaxInactiveInterval(int
segundos)
Define quanto tempo a sessão
poderá ficar inativa.
int getMaxInactiveInterval ()
Retorna quanto tempo a sessão
poderá ficar inativa.
boolean isNew(String alias)
Retorna se uma sessão é válida.
43
HttpSession : Métodos
Método
Descrição
Enumeration
getAttributesNames()
Retorna uma enumeração com
todos os nomes(alias) dos
atributos armazenados na sessão.
void invalidate ()
Invalida a sessão e remove todos
os objetos associados a ela.
44
HttpSession

Pode-se definir o Timeout de uma sessão
no deploymente descriptor da aplicação.
<web-app>
…
<session-config>
<session-timeout>30</session-timeout>
</session-config>
…
<web-app>
45
Sessões

Importante:

A sessão não é enviada a cada requisição / resposta
(lento e inseguro). Apenas o ID da sessão é
transmitido através de um cookie com nome
JSESSIONID.

A API de servlets permite o uso de sessões mesmo
que o navegador do usuário nao suporte cookies. É
preciso passar o valor do JSESSIONID como um
parâmetro especial da requisição. Isso pode ser feito
utilizando
o
método
HttpServletResponse.encodeURL(). (URL rewriting)
46
Cookies
 Dados
permanentes mantidos em
um browser do cliente entre várias
sessões.
 Informações do tipo nome / valor.
 Usados para armazenar perfis de
usuários entre outras
funcionalidades.
47
Cookie

Classe


Criação


Cookie c = new Cookie(“chave”,
“valor”);
Obtenção


javax.servlet.http.Cookie
Cookie[ ] cs = request.getCookies();
Persistindo

response.addCookie(cookie);
48
Cookie


Por padrão, existem enquanto a sessão
existir.
Pode-se configurar o tempo de expiração
de um Cookie através do método
setMaxAge(int intervalo)



Intervalo > 0: tempo de vida em segundos.
Intervalo = 0: apaga o cookie
instantaneamente.
Intevalo < 0: remove o cookie ao fim da
sessão
49
Cookie : métodos
Método
Descrição
String getName()
Retorna a chave do cookie.
String/void get/setValue ()
Retorna ou ajusta o valor do
cookie.
50
Cookie : Exemplo
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException{
HttpSession session = request.getSession(true);
Perfil p = (Perfil) session.getAttribute(“perfil");
if (p != null){
//Atualiza o perfil
response.addCookie(new Cookie(“perfil”,
p.toString()));
}else{
response.sendRedirect(“cadastroPerfil.jsp");
}
}
51
Prática 4


Crie um pequeno sistema (uma funcionalidade), que
só possa ser usada caso o usuário esteja logado.
Deverão ser criados:





Um servlet de login
Um HTML com um form de login.
Um servlet para a aplicacao em si.
Um HTML de front-end da aplicação
Uma página de erro com um link para a página de login
52
Método sendError()

Métodos sendError() da interface
HttpServletResponse:
public void sendError(int sc) throws IOException
public void sendError(int sc, String msg) throws
IOException


Envia um erro como resposta para o cliente
utilizando o código de status e limpa o buffer de
saída.
Caso a resposta já tenha sido enviada, este
método lança a exceção IllegalStateException.
53
Método sendError()
try {
//processamento
}
catch(Exception e) {
String msg = “Erro“
res.sendError(res.SC_NOT_FOUND,
msg );
}
54
Método sendError()
55
Códigos





200 – ok
400 – Requisição mal formada
403 – Acesso negado
404 – Recurso inexistente
500 – Erro no servidor (requisição não
pode ser tratada)
56
Servlets e Threads
O Modelo MultiThreaded
58
O Modelo MultiThreaded
Deve ser utilizado para grandes
aplicações.
Padrão
 Eficiente
 Difícil de preservar a consistência.

59
O Modelo SingleThreaded
60
O Modelo SingleThreaded
Deve-se
implementar a interface
SingleThreadModel
Apesar de conveniente não é
aconselhável utilizar pelas seguintes
razões:
Pode ocupar muita memória.
 Falsa sensação de segurança de thread.
 Falta de compartilhamento de dados.
 Extremamente ineficiente

61
Variáveis X Segurança
Tipo da variável
Segura (thread-safe)
De classe
Não
De instância
Não
Context
Não
Session
Não
Request
Sim
62
Context scope
Não é Thread-Safe.
 Usado para compartilhar dados
que são raramente modificados.

63
Session scope
Não é Thread-Safe. O usuário pode
abrir várias janelas do browser
simultaneamente.
 Geralmente sincroniza-se o acesso
a sessão. (Não causa perda de
eficiência relevante)

64
Request scope
É Thread-Safe.
 Deve se usado apenas no escopo do
método service(...).

65
Observação.
Existe
uma
outra
variação
do
comportamento de um servlet. Quando o
elemento servlet do descritor web declara
o sub-elemento <distributable/>. Essa
marcação é útil em ambiente distribuído.
Ela indica que cada JVM do cluster
possuirá sua própria instancia do servlet.

66
Upload
Upload
Submissão de arquivos do cliente para o
servidor.
 Utilização da biblioteca commonsfileupload-1.0 da apache foundation.


Import org.apache.commons.fileupload.*;
68
Upload: o html
<form action="/curso/up"
enctype="multipart/form-data" method="post">
<input type="file" name="datafile" size="40">
<input type="submit" value="Send">
</form>
69
Upload: o servlet
public void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException{
DiskFileUpload fu = new DiskFileUpload();
try{
fu.setSizeMax(1000000);
fu.setSizeThreshold(4096);
fu.setRepositoryPath(this.getServletContext().getRealPath("/tmp"));
List fileItems = fu.parseRequest(request);
Iterator i = fileItems.iterator();
while (i.hasNext()){
FileItem fi = (FileItem)i.next();
String fileName = fi.getName();
fi.write(new File(this.getServletContext().getRealPath("/tmp") +
getRelativePath(fileName)));
}…
}
70
Prática 5
Escreva um servlet e uma página para
realizar uploads de arquivos.

71
Filtros
Filtros
Para uma aplicação web, um filtro é um
componente que reside no servidor e atua
intermediando (filtrando) as mensagens
trocadas por tal servidor e pelo cliente.
 Previne
que informações indesejadas
transitem livremente.

73
Filtros
74
Filtros: funcionamento
Quando
o
container
recebe
uma
requisição de um recurso, ele checa se
existe um filtro associado a tal recurso.
Em caso positivo, ele direciona a
requisição para tal filtro. Este, depois de
processar a requisição, pode:



Gerar a resposta ele mesmo.
Passa a requisição (modificada ou não) para
o recurso requisitado.
Repassar a requisição para outro recurso.
75
Filtros: implementação
Todos
os filtros:
Devem implementar a interface
Filter (init(), doFilter(), destroy())
 Estarem corretamente mapeados no
descritor da aplicação

76
Filtros: API
Interface / Classe Descrição
javax.servlet.Filter
Interface implementada
para construir os filmes
javax.servlet.FilterChain
Representa a cadeia de
filtros.
javax.servlet.FilterConfig
Similar ao ServletConfig.
77
Filtros: exemplo
public class ExFilter implements Filter{
public void doFilter(ServletRequest req,
ServletResponse res, FilterChain fc){
// processa a requisição e faz a validação
// dos parâmetros
fc.doFilter(req, res);//passa o controle para
// o próximo filtro ou para o recurso
}
...
}
78
Filtros: implementação
<filter>
<filter-name>validar</filter-name>
<filter-class>curso.ExFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>validar</filter-name>
<url-pattern>/secure/*</url-pattern>
</filter-mapping>
OBS: O mapeamento pode ser feito pelo nome do servlet também.
<filter-mapping>
<filter-name>validar</filter-name>
<url-pattern>loginServlet</url-pattern>
</filter-mapping>
79
Filtros
Pode-se
encadear um conjunto de filtros
80
Filtros: encadeando

Quando o container recebe, ele acha todos os
filtros que mapeiam a máscara da url do recurso
e forma o primeiro conjunto. Em seguida acha
todos os filtros que mapeiam o recurso no nome
do servlet. A ordem da cadeia é feita da seguinte
forma:



O primeiro conjunto antecede o segundo
Cada conjunto é ordenado de acordo com a declaração
dos filtros no descritor da aplicação.
Nesse caso, o método doFilter() passa a mensagem para
o próximo filtro ou para o recurso propriamente dito.
81
Filtros: encadeando
<filter>
<filter-name>ValidatorFilter</filter-name>
<filter-class>ValidatorFilter</filter-class>
</filter>
<filter>
<filter-name>SpamFilter</filter-name>
<filter-class>SpamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ValidatorFilter</filter-name>
<url-pattern>/secure/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SpamFilter</filter-name>
<url-pattern>/secure/*</url-pattern>
</filter-mapping>
82
Prática 6
 Escreva
uma pequena aplicação
que filtre um subconjunto de
requisições, redirecionando estas
para uma página de erro ou,
para o caso de uma requisição
aprovada, envie esta para um
servlet
que
realize
um
processamento simples.
83
Eventos de ciclo de vida
Eventos
A criação ou destruição, assim como a
manipulação de atributos, tanto no
contexto como na sessão, levantam
eventos que podem ser capturados
por classes implementadas pelo
desenvolvedor.
 Tais classes devem implementar as
respectivas classes:

85
Eventos

ServletContextListener
Método
Descrição
void contextDestroyed
(ServletContextEvent sce)
Chamado quando o contexto
é destruído.
void contextInitialized
(ServletContextEvent sce)
Chamado quando o contexto
é criado.
86
Eventos

ServletContextAttributeListener
Método
Descrição
void attributeAdded
(ServletContextAttributeEvent scae)
Chamado quando um atributo é
adicionado ao contexto
void attributeRemoved
(ServletContextAttributeEvent scae)
Chamado quando um atributo é
removido do contexto
void attributeReplaced
(ServletContextAttributeEvent scae)
Chamado quando um atributo é
substituído do contexto
87
Eventos

HttpSessionListener
Método
Descrição
void sessionCreated
(HttpSessionEvent se)
Chamado quando a sessão
é criada.
void sessionDestroyed
(HttpSessionEvent se)
Chamado quando a sessão
é destruida.
88
Eventos

HttpSessionAttributeListener
Método
Descrição
void attributeAdded
(HttpSessionBindingEvent scae)
Chamado quando um atributo é
adicionado à sessão
void attributeRemoved
(HttpSessionBindingEvent scae)
Chamado quando um atributo é
removido da sessão
void attributeReplaced
(HttpSessionBindingEvent scae)
Chamado quando um atributo é
substituído da sessão
89
Eventos
 Configurando:
<listener>
<listener-class>
com.abcinc.MyServletContextAttributeListener
</listener-class>
</listener>

OBS: Apenas o nome da classe
“ouvinte” precisa ser declarada, pois o
container faz as devidas inferências.
90
Eventos

Existem outras interfaces de eventos:
HttpSessionBindingListener
 HttpSessionActivationListener


Não serão abordadas nesse curso.
91
Eventos

Existem outras interfaces de eventos:
HttpSessionBindingListener
 HttpSessionActivationListener


Não serão abordadas nesse curso.
92
Download

Servlets