Formação Java Enterprise Edition Módulo II: Camada Web Formador João Paulo Fernandes NOTA: NOTA: Proibida a reprodução (total ou ou parcial) parcial) ou a distribuição deste deste documento documento sem sem a autorização a autorização da Altran da UBI e UBI e Altran Versão: 1.0 Data:25/01/2011 Versão: 1.0 Data: 16/01/2012 1
Informações pré-tutorial Esta apresentação (bem como a de quarta-feira) está disponível no tab Java EE: http://www.di.ubi.pt/~jpf Nesta mesma página vão encontrar: Vários exemplos de aplicações implementadas em ambiente Java EE (5) [alguns vão ser estudados no módulo]: link exemplos Os exercícios relativos à parte prática, e que terão de resolver; 1ª tarefa: Acederem ao link exemplos e descarregarem o seu conteúdo para o Ambiente de trabalho; Descomprimirem o ficheiro descarregado; 2
Agenda 1. Introdução 2. Tecnologia de Servlets Java O ciclo de vida de um Servlet Partilha de Informação Inicialização de um Servlet Escrita de métodos de Serviço Filtragem de pedidos e respostas Invocação de outros recursos Web Acesso ao contexto Web Manutenção do estado no cliente Finalização de um Servlet NOTA: Proibida a reprodução (total ou parcial) ou distribuição deste documento sem a autorização da UBI e Altran Versão: 1.0 Data: 25/01/2011 Área de Negócio: N.A. 3
1. Introdução 4
Aplicações WEB Uma aplicação web é uma extensão dinâmica de um servidor aplicacional ou de um servidor web. As aplicações web podem ser de um de dois tipos: Presentation-oriented: A presentation-oriented web application generates interactive web pages containing various types of markup language (HTML, XHTML, XML, and so on) and dynamic content in response to requests. Service-oriented: A service-oriented web application implements the endpoint of a web service. Presentation-oriented applications are often clients of service-oriented web applications. 5
Aplicações WEB, processamento de pedidos Os componentes Web podem ser: - Servlets Java - Java Server pages Os componentes Web podem interagir com componentes JavaBeans ou uma base de dados para gerar conteúdo dinâmico. 6
Componentes Web: Servlets Java e Java Server Pages Servlets Java Classes na linguagem Java que processam pedidos e produzem respostas, dinamicamente; Java Server Pages Documentos constituídos essencialmente por texto que são executados como servlets mas que permitem uma abordagem mais natural à criação de conteúdo estático; Apesar de ambos poderem ser utilizados indistintamente, cada um destes componentes tem vantagens próprias. Por exemplo, servlets são ideais para aplicações orientadas ao serviço, e server pages para gerar linguagens como HTML e XML. 7
Componentes Web: Servlets Java e Java Server Pages 8
Componentes Web: Servlets Java GreetingServlet.java public class GreetingServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws...{ response.setcontenttype("text/html"); response.setbuffersize(8192); PrintWriter out = response.getwriter(); out.println("<html>" + "<head><title>hello</title></head>"); out.println("<body bgcolor=\"#ffffff\">" + "<img src=\"duke.waving.gif\" alt=\"duke waving\">" + "<h2>hello, my name is Duke. What's yours?</h2>" + "<form method=\"get\">" + "<input type=\"text\" name=\"username\" size=\"25\">" + "<p></p>" + "<input type=\"submit\" value=\"submit\">" + "<input type=\"reset\" value=\"reset\">" + "</form>"); } String username = request.getparameter("username"); if ((username!= null) && (username.length() > 0)) { RequestDispatcher dispatcher = getservletcontext(). getrequestdispatcher("/response"); if (dispatcher!= null) { dispatcher.include(request, response); } } out.println("</body></html>"); out.close(); } Código disponível no material pedagógico fornecido. 9
Componentes Web: Servlets Java ResponseServlet.java public class ResponseServlet extends HttpServlet { public void doget(httpservletrequest request, HttpServletResponse response) throws { PrintWriter out = response.getwriter(); String username = request.getparameter("username"); if ((username!= null) && (username.length() > 0)) { } } } out.println("<h2>hello, " + username + "!</h2>"); Código disponível no material pedagógico fornecido. 10
Componentes Web: Java Server Pages index.jsp <html> <head><title>hello</title></head> <body bgcolor="white"> <img src="duke.waving.gif"> <h2>hello, my name is Duke. What's yours?</h2> <form method="get"> <input type="text" name="username" size="25"> <p></p> <input type="submit" value="submit"> <input type="reset" value="reset"> </form> <c:if test="${fn:length(param.username) > 0}" > <%@include file="response.jsp" %> </c:if> </body> </html> response.jsp <h2><font color="black">hello, ${param.username}!</font></h2> Código disponível no material pedagógico fornecido. 11
Componentes Web: Servlets Java e Java Server Pages Servlets Java são a base de todas as tecnologias de desenvolvimento de aplicações Web. Cada tecnologia construída sobre servlets adiciona um nível de abstracção que torna a prototipagem e desenvolvimento de aplicações mais rápido, ao mesmo tempo que as aplicações desenvolvidas se tornam mais fáceis de manter, são mais escaláveis e robustas. 12
2. Tecnologia de Servlets Java Desde que a internet começou a ser utilizada como um ambiente de prestação de serviços que se sentiu a necessidade de criar (e apresentar) conteúdos dinâmicos; A tecnologia de servlets foi criada como uma forma portável de fornecer conteúdos dinâmicos e orientados ao utilizador. Mas afinal o que é um servlet? Um servlet é uma classe na linguagem Java que se utiliza para estender as funcionalidades dos servidores (tipicamente web) que as aplicações acedem seguindo o modelo de programação request-response; Para as aplicações web, a tecnologia de servlets de Java define um conjunto de classes específicas para o protocolo HTTP: As packages javax.servlet e javax.servlet.http providenciam interfaces e classes para implementar servlets; Todos os servlets devem implementar a interface Servlet Por agora, vamos focar-nos na escrita de servlets que geram respostas a pedidos HTTP. 13
Tecnologia de Servlets Java Para ilustrar os conceitos associados à implementação de servlets, vamos utilizar um exemplo concreto: o de uma livraria (directoria bookstore); Associados a esta livraria estão várias tarefas/funcionalidades, cada uma implementada por um ou mais servlets: 14
O Ciclo de Vida de um servlet...... é controlado pelo container onde o servlet é despoletado; Existem três métodos (detalhados mais à frente) que são centrais ao ciclo de vida de um servlet: init, service e destroy Um cenário típico da utilização destes métodos seria: 1. Assume that a user requests to visit a URL. The browser then generates an HTTP request for this URL. This request is then sent to the appropriate server. 2. The HTTP request is received by the web server and forwarded to the servlet container. The container maps this request to a particular servlet. The servlet is dynamically retrieved and loaded into the address space of the container. 3. The container invokes the init() method of the servlet. This method is invoked only when the servlet is first loaded into memory. It is possible to pass initialization parameters to the servlet so that it may configure itself. 4. The container invokes the service() method of the servlet. This method is called to process the HTTP request. The servlet may read data that has been provided in the HTTP request. The servlet may also formulate an HTTP response for the client. 15
O Ciclo de Vida de um servlet...... é controlado pelo container onde o servlet é despoletado; Existem três métodos (detalhados mais à frente) que são centrais ao ciclo de vida de um servlet: init, service e destroy Um cenário típico da utilização destes métodos seria: 5. The servlet remains in the container's address space and is available to process any other HTTP requests received from clients. The service() method is called for each HTTP request. 6. The container may, at some point, decide to unload the servlet from its memory. The algorithms by which this decision is made are specific to each container. 7. The container calls the servlet's destroy() method to relinquish any resources such as file handles that are allocated for the servlet; important data may be saved to a persistent store. 8. The memory allocated for the servlet and its objects can then be garbage collected 16
Gestão dos eventos relacionados com o Ciclo de Vida de Servlets É possível monitorizar e reagir a eventos do ciclo de vida de servlets através da definição de objectos listener cujos métodos são invocados quando esses eventos ocorrem. Classes listener são definidas como implementações de uma interface listener. 17
Gestão dos eventos relacionados com o Ciclo de Vida de Servlets Quando um método listener é invocado, é-lhe passado um Event que contém informação apropriada relativamente a esse evento. Exemplos: a) monitorizar a inicialização do contexto Web implica implementar a interface ServletContextListener, sendo que aos seus métodos é passado um evento ServletContextEvent; b) aos métodos em HttpSessionListener são passados HttpSessionEvents, contendo uma HttpSession; 18
19
20
Especificação de Classes Event Listener É possível especificar event listeners utilizando o descriptor que é utilizado na fase de deployment da seguinte forma: 1. Expand your application s project node. 2. Expand the project s Web Pages and WEB-INF nodes. 3. Double-click web.xml. 4. Click General at the top of the web.xml editor. 5. Expand the Web Application Listeners node. 6. Click Add. 7. In the Add Listener dialog, click Browse to locate the listener class. 8. Click OK. 21
Partilha de Informação entre componentes Web Tal como a maior parte dos objectos, os componentes Web normalmente interagem com outros componentes com o objectivo de cumprir uma tarefa; Estes componentes partilham informação através de objectos que são mantidos em atributos de 4 objectos de âmbito : Estes atributos são acedidos através de métodos [get set]attribute 22
De volta à nossa livraria... 23
Gestão de acessos concorrentes a recursos partilhados Num ambiente multithreaded, é possível que recursos partilhados sejam acedidos concorrentemente. Para além de atributos de objectos de âmbito, recursos partilhados podem ser variáveis em memória e objectos externos como ficheiros, ligações a bases de dados e ligações de rede. Acessos concorrentes podem ocorrer em várias situações, quando: 1. mais do que um componente Web acede a objectos armazenados no contexto Web; 2. mais do que um componente Web acede a objectos armazenados na sessão; 3. Múltiplas threads de um mesmo componente Web acedem a variáveis de instância. Na nossa aplicação vimos 5 atributos de âmbito partilhados por mais do que um servlet: bookdb, cart, currency, hitcounter, and ordercounter. Os valores destes últimos 4 atributos podem ser definidos e lidos por múltiplos servlets multithreaded. 24
Gestão de acessos concorrentes a recursos partilhados Na nossa aplicação vimos 5 atributos de âmbito partilhados por mais do que um servlet: bookdb, cart, currency, hitcounter, and ordercounter. Os valores destes últimos 4 atributos podem ser definidos e lidos por múltiplos servlets multithreaded. Para evitar que estes objectos se tornem inconsistentes, o seu acesso é controlado por métodos sincronizados : 25
Gestão de acessos concorrentes a recursos partilhados Não é possível que se misturem duas invocações de métodos sincronizados que occorram no mesmo objecto. Isso quer dizer que quando uma thread está a executar um método sincronizado num objecto, todas as outras threads que invoquem outros métodos sincronizados no mesmo objecto sejam bloqueadas (suspensas) até que a primeira thread liberte o objecto; Quando um método sincronizado retorna, ele automaticamente estabelece uma relação ocorre-antes com qualquer invocação subsequente de um método sincronizado no mesmo objecto. Isso garante que todas as alterações do estado ficam visíveis para todas as threads. 26
Acesso a bases de dados Os dados que são partilhados por diferentes componentes Web e que são persistentes entre invocações de uma aplicação Web são normalmente mantidos numa base de dados. Os componentes Web usam a Java Persitence API (apresentada mais à frente) para aceder a bases de dados relacionais. No caso da livraria em estudo, uma base de dados é acedida através da classe BookDBAO. Por exemplo, ReceiptServlet invoca BookDBAO.buybooks: 27
Acesso a bases de dados 28
Acesso a bases de dados Para garantir que uma ordem é completamente processada, a invocação de buybooks está encapsulada numa única transacção, no servlet ReceiptServlet: No código acima: as invocações de begin e de commit de UserTransaction marcam os limites da transacção; a invocação de rollback anula os efeitos de todas as instruções da transação para proteger a integridade dos dados. 29
Inicialização de um servlet Depois do web container carregar e instanciar uma classe servlet, e antes de essa instância poder fornecer serviços a um cliente, o web container inicializa o servlet; Como vimos, para especificar o processo de inicialização (permitindo que o serlvet leia informação persistente, para inicializar outros recursos ou para executar outras tarefas uma única vez), é necessário re-implementar o método init da interface Servlet; Um servlet que não consiga completar o processo de inicialização deve lançar uma excepção UnavailableException; Todos os servlets que acedem à base de dados da livraria (BookStoreServlet, CatalogServlet, BookDetailsServlet, e ShowCartServlet) inicializam, no seu método init, uma variável que aponta para o DBAO criado pelo web context listenter: 30
Implementação dos serviços de um servlet O serviço prestado por um servlet é implementado: - no método service de um GenericServlet; - num dos métodos domethod (Method pode tomar qualquer um dos valores: Get, Delete, Options, Post, Put ou Trace) de um HttpServlet; - num outro método de um protocolo específico definido numa classe que implemente a interface Servlet. De agora em diante chamaremos método de serviço a qualquer método de uma classe servlet que forneça um serviço a um cliente. O padrão típico de um método de serviço passa por: i) extrair informação/ compreender o pedido feito; ii) aceder a recursos externos; iii) construir uma resposta com base nessa informação; Para servlets Http, o procedimento correcto para construir a resposta envolve aceder a uma output stream da resposta, preencher os headers da resposta, e finalmente escrever o conteúdo para o body da resposta. 31
i) Extracção de informação dos pedidos Um pedido contém dados que são passados entre o cliente e o servlet. Todos os requests implementam a interface ServletRequest; esta interface define métodos que permitem aceder à informação seguinte: - parâmetros, que são tipicamente usados para passar informação entre cliente e servlet - atributos, que são usados para passar informação entre o servlet container e o servlet (ou servlets colaborantes) - informação sobre o protocolo utilizado para comunicar o pedido e acerca do cliente e servidor envolvidos - Por exemplo, no servlet CatalogServlet, o identificador do livro que um cliente deseja adquirir é incluído como um parâmetro no pedido. O código seguinte ilustra como se pode usar o método getparameter para extrair o identificador: É ainda possível aceder a uma input stream do pedido e extrair informação manualmente. Para ler informação textual, pode utilizar-se o objecto java.io.bufferedreader retornado pelo método getreader do pedido. Para ler dados binários, utilizar a ServletInputStream retornada pelo getinputstream. 32
i) Extracção de informação dos pedidos Aos servlets HTTP é passado um objecto HTTP request, HttpServletRequest, que contém o URL do pedido, headers HTTP, a string de query, Um URL de um pedido HTTP tem a seguinte estrutura: http://[host]:[port][request-path]?[query-string] http://localhost:8080/bookstore1/bookstore http://localhost:8080/bookstore1/bookcatalog?bookid=201 O request-path é composto pelos seguintes elementos: Context path: A concatenation of a forward slash (/) with the context root of the servlet s web application. Servlet path: The path section that corresponds to the component alias that activated this request. This path starts with a forward slash (/). Path info: The part of the request path that is not part of the context path or the servlet path. 33
i) Extracção de informação dos pedidos Aos servlets HTTP é passado um objecto HTTP request, HttpServletRequest, que contém o URL do pedido, headers HTTP, a string de query, Um URL de um pedido HTTP tem a seguinte estrutura: http://[host]:[port][request-path]?[query-string] http://localhost:8080/bookstore1/bookstore http://localhost:8080/bookstore1/bookcatalog?bookid=201 A query-string é composta por um conjunto de parâmetros e valores. Parâmetros individuais podem ser acedidos de um pedido utilizando o método getparameter. A forma que estudaremos para gerar query strings é a seguinte: A query string aparece explicitamente numa página web; Por exemplo, uma página HTML gerada por CatalogServlet podia conter o link <a href="/bookstore1/catalog?add=101">add To Cart</a> Neste caso, CatalogServlet extraíria o parâmetro com nome Add da seguinte forma: String bookid = request.getparameter("add"); 34
iii) Construção de respostas aos pedidos Uma resposta contém dados que são passados entre o servidor e o cliente; Todas as respostas implementam a interface ServletResponse; esta interface define métodos que permitem: - aceder a uma output stream que é utilizada para enviar dados aos clientes; para enviar texto, utilizar a java.io.printwriter retornada pelo método getwriter invocado na resposta; - indicar o tipo de conteúdo que é retornado como resposta (por exemplo, text/html), com o método setcontenttype(string); - indicar se se pretende utilizar um buffer, através do método setbuffersize(int); por defeito, qualquer conteúdo escrito na output stream é imediatamente enviada ao cliente. Buffering permite que se vá construíndo conteúdo sem que esse conteúdo seja de facto enviado ao cliente. Os objectos HttpServletResponse, que permitem construir respostas HTTP, contêm ainda campos representando headers HTTP tais como códigos de estado e cookies. 35
iii) Construção de respostas aos pedidos Na livraria em estudo, o servlet BookDetailsServlet gera uma página HTML que mosta a informação relativa a um livro, que o servlet acede na base de dados; Em primeiro lugar, o servlet define os headers da resposta: o tipo de conteúdo da resposta e o tamanho do buffer: A utilização de um buffer previne que o cliente veja o início de uma página correcta seguido uma página de erro no caso, por exemplo, de uma tentativa falhada de aceder a um livro; De seguida, o método doget acede a uma PrintWriter da resposta; 36
iii) Construção de respostas aos pedidos Para construir a resposta, o servlet começa por reencaminhar o pedido para o BannerServlet, que gera um banner comum a todos os servlets na aplicação: servlet De seguida, o servlet acede ao identificador do livro que se pretende consultar, acedendo ao parâmetro respectivo do pedido, e usa-o para aceder à informação do livro que consta da base de dados: 37
iii) Construção de respostas aos pedidos Finalmente, o servlet sinaliza que o código HTML que construiu deve ser enviado ao cliente, através da invocação do método close na PrintWriter: O servlet BookDetailsServlet gera uma página como a seguinte: 38
39
Filtragem de Pedidos e Respostas Um filtro é um objecto capaz de transformar tanto um header como o conteúdo (ou ambos) de um pedido ou resposta. Um filtro difere de um componente web uma vez que, normalmente, não cria ele próprio uma resposta; ao invés, fornece alguma funcionalidade que pode ser anexada a qualquer tipo de recurso web; As principais tarefas que um filtro pode executar são: Analizar o pedido e agir em conformidade; Bloquear o par pedido/resposta de serem passados; Modificar o header e os dados de um pedido; isto é feito criando uma versão particular de um pedido; Modificar o header e os dados de uma resposta; isto é feito criando uma versão particular de uma resposta Interagir com recursos externos Filtros podem ser utilizados em tarefas de logging, de conversão de imagens, cifragem de dados, etc É possível configurar um recurso web para ser filtrado por zero, um ou mais filtros, numa ordem específica. As tarefas envolvidas na utilização de filtros são: Programar o filtro Programar pedidos e respostas customizados Especificar a ordem de aplicação dos filtros, para cada recurso web 40
Programação de Filtros A API para definição de filtros está defina pelas interfaces Filter, FilterChain e FilterConfig da package javax.servlet; Um filtro define-se implementando a interface Filter. O método mais importante desta interface é o método dofilter, ao qual são passados o pedido, a resposta e objectos da cadeia de filtros. Este método pode efectuar as seguintes acções: Examinar headers de pedidos; Customizar o objecto do pedido(resposta), se o filtro pretender modificar os headers ou dados do pedido(resposta); Invocar a entidade seguinte na cadeia de filtros; Examinar headers de respostas depois de ter invocado o filtro seguinte na cadeia de filtros; Lançar uma excepção para indicar um erro de processamento. Para além de dofilter, é necessário implementar os métodos init e destroy; 41
Programação de Filtros A livraria que temos vindo a estudar utiliza dois filtros: HitCounterFilter e OrderFilter, para incrementar e registar (um log com) o valor de contadores sempre que a aplicação é acedida e um recibo é emitido, respectivamente. Nos respectivos métodos dofilter, ambos os filtros acedem ao contexto dos servlets a partir do objecto de configuração de filtros por forma a acederem aos contadores armazenados como atributos de contexto. Depois de executarem as suas tarefas específicas, os filtros invocam dofilter no objecto da cadeia de filtros passado ao método dofilter original. 42
Invocação de Outros Recursos Web Os componentes Web podem invocar outros recursos de duas formas distintas: Indirectamente: - quando o URL para um dado recurso web é embebido no conteúdo enviado ao cliente; - quase todos os componentes da livraria invocam outros recursos indirectamente; - p.e., ShowCartServlet invoca indirectamente o servlet CatalogServlet através do URL: /bookstore1/bookcatalog Directamente, de uma de duas formas: i) O componente web inclui o conteúdo de outro recurso ii) O componente web reencaminha um pedido para outro recurso - Para invocar um recurso disponível no servidor onde um componente web está a correr, é preciso obter um objecto RequestDispatcher invocando o método getrequestdispatcher("url ), e.g.: RequestDispatcher dispatcher = getservletcontext().getrequestdispatcher("/banner"); 43
Incorporação de Outros Recursos na Resposta É frequente incluir um outro recurso web (p.e., um banner) na resposta que é retornada por um componente web; para fazer isso, há que invocar o método include do objecto RequestDispatcher: RequestDispatcher dispatcher = getservletcontext().getrequestdispatcher("/banner"); dispatcher.include(request, response); Se o recurso é estático, o método include permite programar includes no lado do servidor Se o recurso é um componente web, o efeito deste método é o de enviar o pedido ao componente web que está a ser incluído, executar esse componente, e incluir o resultado dessa execução na resposta ao servlet que contém a invocação do método; 44
Incorporação de Outros Recursos na Resposta O banner da livraria em estudo é gerado pelo servlet BannerServlet: 45
Incorporação de Outros Recursos na Resposta E os restantes servlets incorporam o resultado de BannerServlet definindo o código: 46
Acesso ao contexto Web O contexto em que os componentes Web executam é um objecto que implementa a interface ServletContext; É possível aceder a este contexto utilizando o método getservletcontext; O contexto Web disponibiliza métodos para aceder a: Parâmetros de inicialização Recursos associados ao contexto web Atributos objecto-valor Iniciativas de logging Tal como foi apresentado, o contexto web é utilizado pelos filtros HitCounterFilter e OrderFilter; cada filtro armazena um contador sob a forma de um atributo de contexto; Relembra-se também que os métodos que acedem a esses contadores são sincronizados para prevenir operações incompatíveis dos servlets que a eles acedem concorrentemente; Um filtro acede a um contador utilizando o método de contexto getattribute; O valor do contador incrementado é registado no log; 47
Acesso ao contexto Web 48
Manutenção do Estado no Cliente Várias são as aplicações que necessitam que um conjunto de pedidos de um cliente sejam associados uns com os outros; No caso da livraria, é natural assumir que a aplicação guarde o estado do carrinho de compras de um utilizador entre pedidos; As aplicações Web-based são responsáveis pela manutenção desse estado, chamado uma sessão, uma vez que o protocolo HTTP não o permite manter; A tecnologia de Java Servlets fornece uma API que permite às aplicações que precisam de manter um estado gerir sessões e que permite vários mecanismos para implementar sessões; 49
Acesso a uma sessão Sessões são representadas por um objecto HttpSession; O acesso a uma sessão faz-se através do método getsession invocado no objecto de um pedido; Este método retorna a sessão corrente associada ao pedido, ou, se o pedido não tiver uma sessão associada, cria-a; 50
Associação de Objectos a uma sessão É possível associar atributos objecto-valor a uma sessão pelo seu nome; Estes atributos são acessíveis por qualquer componente web que pertença ao mesmo contexto web e que esteja a gerir um pedido que seja parte da mesma sessão; Na aplicação para gerir a livraria, o carrinho de compras é armazenado como um atributo de sessão: isso permite que o carrinho seja guardado entre pedidos e ainda que servlets cooperantes lhe acedam: o servlet CatalogServlet adiciona livros ao carrinho; antes disso, define um atributo de sessão, se ele não existir: 51
Associação de Objectos a uma sessão É possível associar atributos objecto-valor a uma sessão pelo seu nome; Estes atributos são acessíveis por qualquer componente web que pertença ao mesmo contexto web e que esteja a gerir um pedido que seja parte da mesma sessão; Na aplicação para gerir a livraria, o carrinho de compras é armazenado como um atributo de sessão: isso permite que o carrinho seja guardado entre pedidos e ainda que servlets cooperantes lhe acedam: o servlet CatalogServlet adiciona livros ao carrinho; o servlet ShowCartServlet mostra, remove livros do carrinho e reinicia o carrinho; CashierServlet calcula o custo total dos livros no carrinho; 52
Gestão de uma Sessão Uma vez que não existe nenhuma forma de um cliente HTTP sinalizar que não precisa mais de uma sessão, cada sessão tem associada a si um timeout a partir do qual os seus recursos são libertados ; Este período de timeout pode ser acedido utilizando os métodos: [get set]maxinactiveinterval É ainda possível definir o período de timeout utilizando o descritor de deployment: 1. Open the web.xml file in the web.xml editor. 2. Click General at the top of the editor. 3. Enter an integer value in the Session Timeout field. The integer value represents the number of minutes of inactivity that must pass before the session times out. Por forma a garantir que uma sessão activa não é interrompida por um timeout, devese aceder periodicamente à sessão utilizando métodos de serviço: estes reiniciam o contador do tempo de vida; 53
Gestão de uma Sessão Quando a interacção com um cliente terminar, utiliza-se o método invalidate para invalidar a sessão do lado do servidor e limpar quaisquer dados da sessão; O servlet ReceiptServlet é o último a aceder a uma sessão de um cliente, pelo que fica com a responsabilidade de invalidar a sessão: 54
Controlo de uma Sessão Um web container pode utilizar vários métodos para associar uma sessão a um utilizador, mas todos envolvem trocar um identificador entre o cliente e o servidor; O identificador pode ser mantido no cliente como um cookie, ou o componente web pode incluir o identificador em cada URL que é enviado ao cliente; Se uma aplicação usa objectos de sessão, é necessário garantir que o controlo da sessão está activado, forçando a aplicação a reescrever URLs sempre que o cliente desliga os cookies; Isso é feito invocando o método encodeurl(url) em todas as URLs produzidas por um servlet; Este método inclui o identificador da sessão no URL apenas no caso em que os cookies estejam desactivados; Caso contrário, os URLs são mantidos inalterados; 55
Controlo de uma Sessão O método doget de ShowCartServlet incorpora os 3 URLs no fundo da página que mostra o carrinho de compras da seguinte forma: Se os cookies estiverem desactivados, a sessão é embebida no URL de check out assim: http://localhost:8080/bookstore1/cashier;jsessionid=c0o7fszeb1 Se os cookies estiverem activos, então o URL é simplesmente: http://localhost:8080/bookstore1/cashier 56
Finalização de um servlet Quando um servlet container decide que um servlet deve ser removido de serviço (p.e., quando um container necessita da memória que o servlet está a utilizar ou quando está a ser desligado), o container invoca o método destroy da interface Servlet; Neste método, são libertados quaisquer recursos que estejam a ser utilizados pelo servlet e é armazenado qualquer estado persistente; O método seguinte liberta o objecto criado pelo método init para gerir a base de dados: 57