Buscar

Introdução aos Servlets em Java

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

*
Java Avançado
Java Servlets
Guilherme Kely de Melo Oliveira
gkmo@cin.ufpe.br
Jobson Ronan Jeronimo da Silva
jrjs@cin.ufpe.br
Material cedido por: 
	Daniel Arraes Pereira
	dap@cin.ufpe.br
*
*
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.
*
*
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.
*
*
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.
*
*
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
*
*
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();
 } 
}
*
*
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)
*
*
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, ...
*
*
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>
*
*
Servlet Hello World
Executando
http://localhost:8080/HelloWorld/HelloWorldServlet
*
*
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.
*
*
Ciclo de vida de um Servlet
*
*
Ciclo de Vida de Um Servlet
*
*
Método service()
*
*
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.
*
*
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</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup> // preloading
</servlet>
</web-app>
*
*
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(...)
*
*
Servlets e requisições
*
*
Servlets e requisições
Exemplos
GET
	http://www.cin.ufpe.br/servlet/ServletProcurar?numero=12&codigo=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>
*
*
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.*;
*
*
ServletRequest
*
*
HttpServletRequest
*
*
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”);
 } 
*
*
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
*
*
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.*;
*
*
ServletResponse
*
*
HttpServletResponse
*
*
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();
}
*
*
Prática 2
Crie um servlet que retorne uma imagem. 
*
*
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.
*
*
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.
*
*
ServletContext
*
*
ServletContext
*
*
ServletContext
*
*
ServletContext
*
*
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()
*
*
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. 
*
*
Sessões : Introdução
Motivação:
Guardar informações entre requisições de um cliente
Problema:
HTTP não mantém estado.
Soluções.
Campos ocultos em formulário.
Cookies
Reescrita de URLs
Sessões
*
*
Sessões
É uma série de interações request-response 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
*
*
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.
*
*
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");
 }
}
*
*
HttpSession : Métodos
*
*
HttpSession : Métodos
*
*
HttpSession : Métodos
*
*
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>
*
*
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)
*
*
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.
*
*
Cookie
Classe
javax.servlet.http.Cookie
Criação	
Cookie c = new Cookie(“chave”, “valor”);
Obtenção
Cookie[ ] cs = request.getCookies();
Persistindo
response.addCookie(cookie);
*
*
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
*
*
Cookie : métodos
*
*
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");
 }
}
*
*
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
*
*
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.
*
*
Método sendError() 
try {
 //processamento
 } 
 catch(Exception e) {
 String msg = “Erro“
 res.sendError(res.SC_NOT_FOUND, msg );
 }
*
*
Método sendError() 
*
*
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)
*
Servlets e Threads
*
*
O Modelo MultiThreaded
*
*
O Modelo MultiThreaded
Deve ser utilizado para grandes aplicações.
Padrão 
Eficiente
Difícil de preservar a consistência.
*
*
O Modelo SingleThreaded
*
*
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
*
*
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
*
*
Context scope
 Não é Thread-Safe.
 Usado para compartilhar dados que são raramente modificados.
*
*
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)
*
*
Request scope
 É Thread-Safe.
 Deve se usado apenas no escopo do método service(...).
*
*
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.
*
Upload
*
*
Upload
 Submissão de arquivos do cliente para o servidor.
 Utilização da biblioteca commons-fileupload-1.0 da apache foundation.
Import org.apache.commons.fileupload.*;
*
*
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>
*
*
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)));
 } …
 }
*
*
Prática 5
 Escreva um servlet e uma página para realizar uploads de arquivos.
*
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.
*
*
Filtros
*
*
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.
*
*
Filtros: implementação
Todos os filtros:
Devem implementar a interface Filter (init(), doFilter(), destroy())
Estarem corretamente mapeados no descritor da aplicação 
*
*
Filtros: API
*
*
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
 }
 ...
}
*
*
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>
*
*
Filtros
Pode-se encadear um conjunto de filtros
*
*
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.
*
*
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>
*
*
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.
*
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:
*
*
Eventos
ServletContextListener
*
*
Eventos
ServletContextAttributeListener
*
*
Eventos
HttpSessionListener
*
*
Eventos
HttpSessionAttributeListener
*
*
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.
*
*
Eventos
Existem outras interfaces de eventos:
HttpSessionBindingListener
HttpSessionActivationListener
Não serão abordadas nesse curso.
*
*
Eventos
Existem outras interfaces de eventos:
HttpSessionBindingListener
HttpSessionActivationListener
Não serão abordadas nesse curso.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Continue navegando