1 João Carlos Pinheiro Julho / 2004
2
����������������
Apresentar
Os benefícios de servlets
A arquitetura de aplicativo servlet
Como funciona um Servlet
Os pacotes javax.servlet e
javax.servlet.http
Como escrever e executar o seu primeiro aplicativo
servlet
3
���� �������� ����
A tecnologia Servlets foi introduzida pela SUN em 1996
com intuito de gerar código HTML
Servlets são classes Java mantidas e executadas por
um conteiner de servlet
Estendem servidores orientados a requisição/resposta,
que recebe chamadas de diversas clientes
4
����������������� �������������������������� ���������
Ler dados enviados pela aplicação cliente
Ler informações anexadas a página
Podem ser cookies, identificação da máquina cliente,
resposta a pedido de autenticação, etc.
Geração de resultados
Formatação do resultado e envio para o cliente
5
���������� ������������������� ���������
DesempenhoDepois que um Servlet termina de processar uma solicitação, ele permanece na memória, aguardando por uma outra solicitação
PortabilidadePode-se movê-los entre diferentes plataformas sem problemas
6
���������� ������������������� ���������
RobustezServlets são gerenciados pela JVM.
Não existe a preocupação com deslocação de memória ou coleta de lixo
Aceitação Difundida
7
���������� ������������������� ���������
Suporte a Grandes SistemasAs Servlets aproveitam o modelo OO que facilita a organização do sistema, reaproveitamento de código, divisão das tarefas em equipe, etc
CustoExistem um grande número de servidores Web gratuitos disponíveis que podem rodar servlets
8
������� ���������������������� ���������������
Servlets interagem com clientes por meio de um modelo solicitação-resposta baseado em HTTP
9
������� ���������������������� ���������������
Para executar Servlets e JSP é preciso implantá-los em um Container Web, que é responsável:
pela delegação de requisição HTTP para os servletsexistentes
pelo controle dos servlets
além da criação de pool de threads para o processamento das requisições, sendo cada requisição é atendida em uma thread própria
10
������� ���������������������� ���������������
Seis etapas para executar um servlet
1. Crie uma estrutura de diretório para o seu aplicativo Tomcat
O diretório webapps é onde fica armazenado os aplicativos web
1. Crie o contexto (diretório) meusServlets(aparece na URL)
2. Crie o sub-diretório WEB-INF e classes (fica as classes Java),
conforme apresentado na figura ao lado
11
�� �!���������" �#�������� ����������� �!���������" �#�������� ���������
import java.io.*; import javax.servlet.*;
import javax.servlet.http.*;
public class PrimeiroServlet extends HttpServlet {
protected void doGet(HttpServletRequest req,HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter out = resp.getWriter();
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE> Meu primeiro Servlet</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("Bem vindo ao meu primeiro servlet");
out.println("</BODY>");
} }
Este arquivo (PrimeiroServlet.class) deve ser salvo em meusServlets/WEB-INF/classes
13
(��!����%�&������ ����������� �������������)�����*'���������*�!�+,-*.�� /'�(��!����%�&������ ����������� �������������)�����*'���������*�!�+,-*.�� /'�
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN“ "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>Exemplo1</servlet-name>
<servlet-class>PrimeiroServlet</servlet-class>
</servlet><servlet-mapping>
<servlet-name>Exemplo1</servlet-name><url-pattern>/servlet/Exemplo1</url-pattern>
</servlet-mapping>
</web-app>
15
2��!����%�&3�'��������������������� ���'�����#� ���.��2��!����%�&3�'��������������������� ���'�����#� ���.��
17
��������������������
A API dos servlets estão definidas no pacote javax.servlet. Contém: 7 interfaces, 3 classes e 2 exceçõesInterfaces
RequestDispatcher, Servlet, ServletConfig, ServletContext, ServletRequest, ServletResponse, SingleThread
ClassesGenericServlet (Abstrata)ServletInputStream
ServletOutputStream
ExceçõesServletException
UnavailableException
18
�����������4������������������������5�����������4������������������������5
Classe
Interface
Legenda
<<interface>>�������
���������������������
������������
�����������������������
<<interface>>���� ���������
<<interface>>��������������
�� ��������������
<<interface>>������������������
<<interface>>������������������
�����������
����������
������
javax.servlet
javax.servlet.http
19
��&����� ��6� �� ���'����������&����� ��6� �� ���'��������
A interface Servlet é a abstração central da
tecnologia Servlet
Cada aplicação Servlet que você escrever
implementa esta interface, direta ou indiretamente
O ciclo de vida de um servlet é determinado por três
dos métodos definidos na interface Servlet
init(), service() e destroy()
20
��&����� ��6� �� ���'����������&����� ��6� �� ���'��������
O ciclo de vida é controlado pelo container, que:
1. Carrega a classe na memória
2. Cria uma instância da classe do servlet
3. Inicializa a instância chamando o método init()
O método init() é chamado apenas uma vez,
para indicar que o servlet esta sendo colocado em
serviço
21
78�� ������4�578�� ������4�5
É importante para escrever código de inicialização, como:
carregar um driver de banco de dados
Iniciar atributos e assim por diante ...
Assinatura do método init()public void init(ServletConfig config)
throws ServletException
OBS: SevletException é a exceção mais
importante em programação servlet
22
��'8�� ��������4�5��'8�� ��������4�5
Depois que o servlet foi iniciado, se torna possível
responder a uma solicitação através do método
service()
O objeto ServletRequest – contém a solicitação do cliente
O objeto ServletResponse – contém a resposta do servlet
public void service(ServletRequest req, ServletResponse resp)
throws ServletException, java.io.IOException
23
��'8�� ��9����:4�5��'8�� ��9����:4�5
Quando o container decidir remover o servlet da
memória, ele o finaliza chamando destroy()
Este método só poderá ser chamado depois que todas
as threads que os referencia terem executadas
Este método da uma chance de limpar quaisquer
recursos que estejam sendo mantidos
24
&����� ��6� �� ���'���������4;������'����5&����� ��6� �� ���'���������4;������'����5
Container ServletContainer Servlet
Primeira chamada?
A Servlet éinstanciada
O método init() é executado
Uma thread éalocada para
executar o Servlet
O método Service() é executado
destroy( )
Libera aMemória
não
Sim
Gera a resposta (HTML, XML,...)
RespostaHTTP
A Servlet ésolicitada
pelo cliente
25
9�'��������� �������� ���� �� ���'��������9�'��������� �������� ���� �� ���'��������
public class DemoCicloServlet implements Servlet {
public void init(ServletConfig arg0) throws ServletException {
System.out.println("init");
}
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
System.out.println("service");
}
public void destroy() {
System.out.println("destroy");
}
public ServletConfig getServletConfig() { return null; }
public String getServletInfo() {return null; }
}
26
&�'���<�����������'8�� ��getServletInfo() ��getServletConfig()&�'���<�����������'8�� ��getServletInfo() ��getServletConfig()
String getServletInfo()
Deve retornar um String que contém informações do
servlet, tais como o autor e a versão do servlet
ServletConfig getServletConfig( )
Retorna um objeto que implementa a interface
ServletConfig que fornece acesso às informações de
configuração do servlet, tais como os parâmetros de
inicialização e o ServletContext do servlet
27
�������/��� ���'���������������/��� ���'��������
O contexto de um servlet é o ambiente onde ele executa
Containers Web suportam a implantação de múltiplas aplicações
Definem contextos separados para execução de servlets
No Tomcat, essas aplicações estão na pasta webapps/
Veja o conteúdo de webapps no seu servidor
28
�������/��� ���'���������������/��� ���'��������
Todo diretório de contexto tem uma estrutura definida, que
consiste de:
Área de documentos do contexto (/), acessível externamente
Área inaccessível (/WEB-INF), que possui pelo menos um
arquivo de configuração padrão (web.xml)
O WEB-INF pode conter ainda dois diretórios reconhecidos pelo
servidor:
1. Um diretório que pertence ao CLASSPATH da aplicação (/WEB-INF/classes) e
2. outro onde podem ser colocados JARs para inclusão no CLASSPATH ( /WEB-INF/lib)
29
&�'�������������'����� �������#������=&�'�������������'����� �������#������=
Para cada servlet registrado no arquivo web.xml,
você tem a opção de especificar um conjunto de
parâmetros iniciais de pares nome/valor que pode ser
recuperado pelo servlet
Exemplo
30
&�'�������������'����� �������#������=&�'�������������'����� �������#������=
<web-app>
<servlet>
<servlet-name>Testando</servlet-name>
<servlet-class>PrimeiroServlet</servlet-class>
<init-param>
<param-name>adminEmail</param-name>
<param-value>[email protected]</param-value>
</init-param>
<init-param>
<param-name>adminContato</param-name>
<param-value>0982345678</param-value></init-param>
</servlet>
</web-app>
������������ ����� � � � ���� ��� � � ��� �� � � �� � � � �
� � ��� ��� � � ����� ��� � ���� ��� ����� ���� � �� � �
� � � �� � ��� ��! � � ��� ! ���� ��� ��� �"
31
&�'�������������'����� �������#������=&�'�������������'����� �������#������=
������ �������� ����������������������������
������ ������������������ ���� � �������������������� �
�������������������������� � �� ���!��������"������#
��������������������$ ������������� �
����� ���������� ������ � ������������������������#
�%����������������&!������������'�& ( ����������#
�%����������������&!�������������'�& (
���� � �� ���!��������������������#
)
�������
)
A Saída do código na console é a seguinte:Parameter name : adminEmailParameter value: [email protected] name : adminContatoParameter value: 0982345678
32
&�'�������������'����� �������#������=&�'�������������'����� �������#������=
Qual é a vantagem disto?
O arquivo web.xml é texto puro, sendo possível editar
o seu conteúdo facilmente
Enquanto codificar este parâmetros dentro do servlet
significa que você precisaria recompilar caso as
informações mudem
33
��������������>�������������������>�����
As solicitações e as respostas são tudo do que trata um aplicativo web
Em um paradigma de servlet a solicitação do usuário é representada pelo objeto ServletRequest
passado pelo Container como primeiro argumento ao método service()
O segundo argumento é um objeto ServletResponse, que representa a resposta ao
usuário
34
������������������������������������������������
Define um objeto usado para encapsular informações sobre a solicitação do usuário
Esta interface oferece métodos importantes, que lhes permite acessar informações sobre o usuário. Por exemplo, os métodos:
getParameterNames() – retorna um Enumarationcontendo os parâmetros de nome para solicitação atualgetParameter( String name )
Retorna o valor associado com um parâmetro. O argumento namerepresenta o nome do parâmetro
getRemoteAddress() e getRemoteHost() recupera o IP da máquina e o nome do Host
Confira o exemplo: RequestDemoServlet.java
35
������������������������ �������������������������� ��
Representa a resposta ao usuário
No caso de HTTP isto consiste de preencher os cabeçalhos de
resposta
O método mais importante desta interface é getWriter() a
partir do qual você pode obter um stream de resposta (objetos de java.io.PrintWriter) e escrever os dados no
stream através do método println()
Confira o exemplo: ResponseDemoServlet.java
PrintWriter out = response.getWriter();out.println("<HTML>");
36
�������������"����;��������������������������"����;�������������
Em todos os exemplos anteriores era necessáriafornece uma implementação aos 5 métodos da interface Servlet, o que torna o código
desnecessariamente complicado
O objeto ServletConfig é passado ao método init(). Você precisa ? ...
Um servlet genérico deve estenderGenericServlet e implementar seu método service()
37
�������������"����;��������������������������"����;�������������
Confira o exemplo: Ex6GenericServlet.java
39
�������������/ ������ 3����������������/ ������ 3���
Neste pacote a classe
HttpServlet representa um
servlet, estendendo
javax.servlet.GenericServlet e
fornece métodos próprios que
são mais ricos e convenientes
de usar
40
�������HttpServlet�������HttpServlet
Essa classe sobrescreve o método service() com uma
implementação padrão
Todos os métodos da classe HttpServlet recebem
parâmetros do tipo HttpServletRequest e
HttpServletResponse e retornam void)
Os dois principais métodos [doGet() e doPost()] são
utilizados para tratar os dois principais tipos de requisições
dos clientes GET e POST
41
�����������?����������>�)��� ��?����������>����������������?����������>�)��� ��?����������>�����
HttpServletRequest
Define métodos que permitem o acesso aos parâmetros da solicitação, a cookies que podem estar armazenados no cliente e à sessão em que o usuário daquele servlet se encontra
HttpServletResponse
Contém métodos que permitem a manipulação de dados referentes ao resultado da solicitação, a criação de cookies no computador do cliente, e uma referência ao objeto que realmente “escreve” os caracteres de resposta ao usuário
!/�'����?����������!/�'����?����������
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ExemploHttpServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType(“text/html”);
PrintWriter out = resp.getWriter();
out.println("<HTML>");
out.println("<HEAD>");
out.println("<TITLE> Meu primeiro Servlet</TITLE>");
out.println("</HEAD>");
out.println("<BODY>");
out.println("Bem vindo ao meu primeiro servlet");
out.println("</BODY>");
out.close();
} }
Os métodos init() e service() são herdados
de HttpServlet
Saída é uma página html
Fecha o fluxo de saída e envia a página montada para o cliente
43
@�� �� � �� ��-��'��<���@�� �� � �� ��-��'��<���
Os dados provenientes de formulários em páginas
web são enviados para o servidor HTTP de duas
formas: Método GET e POST
Método GET
Os dados a serem enviados são colocados no final da URL
que faz a referência a Servlet que receberá as informações
44
����A'�� ���'��B>@�����A'�� ���'��B>@�
Exemplohttp://www.empresa.com.br/validacao?usuario=maria&senha=joao+da+silva
Podemos dividir a URL em várias partes:http://www.empresa.com.br: indica o servidor web que processa o pedidovalidacao: o nome da servlet que receberá a solicitação
?: marca o início dos dados que estão sendo enviadoschave=valor: onde a chave representa o nome da variável e valor, o conteúdo&: é o separador entre chaves e valores“+”: todo espaço em branco é substituído por +
Os dados enviados após este sinal corresponde a informações
enviadas ao servidor
45
@�� �� � �� ��-��'��<�������A'�� ���'��B>@@�� �� � �� ��-��'��<�������A'�� ���'��B>@
Método POST
Os dados são enviados separados do endereço da
página
Não existe limitação do número de caracteres enviados
Dentro da servlet a leitura das informações enviadas é
independente do método de envio, é feita da mesma
forma:
request.getParameter( nomeDoParametro )
46
!/�'����C >������ �������'�������'���'8�� ��;!1!/�'����C >������ �������'�������'���'8�� ��;!1
<html><head> <title>Envio de Dados - GET</title> </head>
<body><form name="form" method=“GET"
action="/exemplos_servlets/servlet/formulario/RecebeGet">Nome:
<input name="nome" type="text" id="nome">Senha: <input name="senha" type="text" id="senha"> <input type="submit" name="Submit" value="Enviar">
</form></body></html>
Servlet que receberá as informações
47
!/�'����C >������ �������'�������'���'8�� ��;!1!/�'����C >������ �������'�������'���'8�� ��;!1
public class RecebeGet extends HttpServlet {protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");PrintWriter out = response.getWriter();//obtém o escritorout.println("<HTML><HEAD>");out.println("<TITLE> Recebe Dados </TITLE>");out.println("</HEAD>");out.println("<BODY>");out.println("<BR>Nome :" + request.getParameter("nome"));out.println("<BR>Senha:"+request.getParameter("senha"));out.println("</BODY>");out.println("</HTML>");out.close();
} // fim do método doGet}
Os dados do formulário são lidos com o método getParameter()
48
>������ �������'������������>������ �������'������������
Caso as informações tenham sido enviadas pelo método POST devem ser lidas dentro do método doPost() do Servlet
49
>������ �������'������� ���� ����� �����'�� �������>������ �������'������� ���� ����� �����'�� �������
public class RecebeGet extends HttpServlet {
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response)
}
protected void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// A implementação fica aqui
}
50
9��#��'�� ����)�D�������'����)�������;!19��#��'�� ����)�D�������'����)�������;!1
:Browser:HttpServlet :RecebeGet
:Servlet:ContainerWeb
1:GET/RecebeGet
2:service()
3:service()
4:doGet()
5:resposta da requisição
52
;�������'����� ������;�������'����� ������
Como o HTTP não mantém estado de sessão, são as aplicações Web que precisam cuidar de mantê-lo quando necessário
Uma sessão pode ser compreendida como o local onde todas as ações realizadas por um determinado usuário podem ser acessadas
Cada usuário que utiliza um Servlet possuirá a sua própria sessão
54
&��E��&��E��
São pequenos arquivos textos gravados pelo browser, a pedido do servidor web, no HD do usuário
Estes arquivos podem ser posteriormente alterados ou lidos pelo servidor web
Foram especificado pela Nestcape e se transformouem um padrão Internet, conforme especificado na RFC 2109
55
&��E��&��E��
Alguns inconvenientes desta solução:Como os arquivos ficam disponíveis para serem lidos após a visita do usuário, qualquer pessoa com acesso ao computador do cliente poderia ver, por exemplo:
A lista de produtos comprados em uma sessão
Identificação do usuário no site
Preferências do usuário
O usuário pode ter desativado a opção de escrever cookie do navegador
etc.
56
&��E��&��E��
OBS: Como os cookies são carregados nos cabeçalhos das solicitação e resposta, não é possível acrescentá-lo depois de uma saída ter sido escrita no objeto HttpServletResponse, caso contrário será
lançada uma exceção
57
&��E��&��E��
Os cookies são transmitidos do servidor para o cliente ou virse-versa no cabeçalhos HTTP
Em programação Servlet um cookie é representado pela classe javax.servlet.http.Cookie
Exemplo de criação de Cookies:Cookie cookie =new Cookie(“myCookie”,“secreto”);
myCookie : nome de identificação
secrecto : valor do cookie (informações)
58
&��E��&��E��
Para criar cookies que duram mais que uma sessão
(cookies persistentes no disco do cliente) é preciso:
Criar um novo objeto Cookie
Definir a duração do cookie com o método setMaxAge()
Definir outros métodos se necessário
Adicionar o cookie à resposta
59
&��E��%�� ������� �&��E��%�� ������� �
// definir um cookie que contenha o nome do
// usuário recebido como parâmetro na requisição
String nome = request.getParameter("nome");
Cookie cookie =new Cookie(“usuario”,nome);
//tempo em segundos até o cookie ser removido
cookie.setMaxAge(7 * 24 * 60 * 60); // 7 dias
// Adicionar o cookie à resposta
response.addCookie(cookie );
// Como cookies são enviados ao cliente como parte do
// cabeçalho HTTP deve preceder getWriter
output = response.getWriter();
. . .
60
&��E��%���� �&��E��%���� �
// obtém os cookies dos clientes
Cookie cookies[] = request.getCookies();
response.setContentType("text/html");
output = response.getWriter();
if (cookies != null) {
// obtém o nome de cada cookie
for (int i = 0; i < cookies.length; i++)
output.println(cookies[i].getName()+
cookies[i].getValue());
}
61
��������
Toda aplicação Servlet faz parte de um único contexto e utiliza várias sessões (uma para cada usuário)
62
�������'�������������?���������������'�������������?��������
O objeto sessão é uma instância da classe HttpSession
É acessível por outros servlets no mesmo aplicativo e são
obtidas a partir de uma requisição
HttpSession session = request.getSession(false);
Se a sessão não existir, retorna null, caso contrário retorna sessão
HttpSession session = request.getSession();
Retorna a sessão ou cria uma nova. Mesmo que getSession(true)
63
�������'�������������?���������������'�������������?��������
Um objeto de HttpSession age como um HashMap,
onde você pode armazenar qualquer quantidade de
chaves/objetos
Para recuperar um objeto é necessário somente passar a
chave
É acessível a partir de outros servlets no mesmo
aplicativo
64
&�'������3�'����� ���������������&�'������3�'����� ���������������
Principais métodos:Retorna o objeto associado a stringpublic Object getAttribute(String name)
throws IllegalStateException
Adiciona um objeto a sessão do usuário, associado a uma stringpublic void setAttribute(String name,
Object value) throws IllegalStateException
Principais VantagensPermitem, além de strings, o compartilhamento de objetos na sessão
Como são armazenados no servidor, não precisam ser reenviados ao cliente toda hora
65
&�'������3�'����� ���������������&�'������3�'����� ���������������
Requisição 1String[] vetor = {"um", "dois", "tres"};HttpSession session = request.getSession();session.setAttribute("dados", vetor);
Requisição 2HttpSession session = request.getSession();String[] dados = (String[])session.getAttribute("dados");
Exemplo:
66
>�'����� ��������� �����>�'����� ��������� �����
Como a sessão pode persistir além do tempo de uma
requisição, é possível que a persistência de alguns
objetos não sejam desejáveis
Use: public removeAttribute(String name)
throws IllegalStateException
67
;��D����� ������;��D����� ������
Não há como saber que cliente não precisa mais da sessão
Pode-se definir um timeout em minutos para a duração de uma sessão desde a última requisição do cliente
define novo valor para timeoutpublic void setMaxInactiveInterval(int)
Nota: Passar um número negativo fara com que esse objeto HttpSessionnunca encerre
recupera valor de timeoutpublic int getMaxInactiveInterval()
Timeout default pode ser definido no web.xml para todas as
sessões
68
;��D����� ������;��D����� ������
Para destruir uma sessão use session.invalidate();
<session-config><session-timeout>10</session-timeout>
</session-config>
������������������������� ������������� ����������
define o tempo de duraçãodefault da sessão em 10 minutos para todas as sessões