Baixe o app para aproveitar ainda mais
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. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Compartilhar