ServletContext
Quando o contêiner de servlet (como o Apache Tomcat ) for iniciado, ele implementará e carregará todos os seus aplicativos da web. Quando um aplicativo da web é carregado, o contêiner do servlet cria o ServletContextúnico e o mantém na memória do servidor. Do aplicativo web web.xmle todos incluídos web-fragment.xmlarquivos é analisado, e cada um <servlet>, <filter>e <listener>encontrado (ou cada classe anotada com @WebServlet, @WebFiltere @WebListenerrespectivamente) é instanciado uma vez e mantidos na memória do servidor também. Para cada filtro instanciado, seu init()método é chamado com um novo FilterConfig.
Quando a Servlettem um valor <servlet><load-on-startup>ou @WebServlet(loadOnStartup)maior que 0, seu init()método também é chamado durante a inicialização de um novo ServletConfig. Esses servlets são inicializados na mesma ordem especificada por esse valor ( 11º, 22º, etc). Se o mesmo valor é especificada por mais de um servlet, então cada um desses servlets é carregado na mesma ordem em que aparecem na web.xml, web-fragment.xmlou @WebServletclassloading. Caso o valor "carregar na inicialização" esteja ausente, o init()método será chamado sempre que a solicitação HTTP atingir esse servlet pela primeira vez.
Quando o contêiner do servlet terminar com todas as etapas de inicialização descritas acima, ele ServletContextListener#contextInitialized()será chamado.
Quando o recipiente servlet é desligado, ele descarrega todas as aplicações web, invoca o destroy()método de todos os seus servlets e filtros inicializados, e todos ServletContext, Servlet, Filtere Listenerinstâncias são lixeira. Finalmente, o ServletContextListener#contextDestroyed()será invocado.
HttpServletRequest e HttpServletResponse
O contêiner de servlet está conectado a um servidor da Web que atende solicitações HTTP em um determinado número de porta (a porta 8080 geralmente é usada durante o desenvolvimento e a porta 80 em produção). Quando um cliente (por exemplo, usuário com um navegador web ou por meio de programação usandoURLConnection ) envia uma solicitação HTTP, o recipiente servlet cria novo HttpServletRequeste HttpServletResponseobjetos e passa-los através de qualquer definido Filterna cadeia e, por fim, a Servletinstância.
No caso de filtros , o doFilter()método é chamado. Quando o código do contêiner do servlet chama chain.doFilter(request, response), a solicitação e a resposta continuam no próximo filtro ou atingem o servlet se não houver filtros restantes.
No caso de servlets , o service()método é chamado. Por padrão, esse método determina qual dos doXxx()métodos chamar com base em request.getMethod(). Se o método determinado estiver ausente no servlet, um erro HTTP 405 será retornado na resposta.
O objeto de solicitação fornece acesso a todas as informações sobre a solicitação HTTP, como URL, cabeçalhos, cadeia de caracteres e corpo da consulta. O objeto de resposta fornece a capacidade de controlar e enviar a resposta HTTP da maneira que você deseja, por exemplo, permitindo definir os cabeçalhos e o corpo (geralmente com conteúdo HTML gerado a partir de um arquivo JSP). Quando a resposta HTTP é confirmada e concluída, os objetos de solicitação e resposta são reciclados e disponibilizados para reutilização.
HttpSession
Quando um cliente visita o aplicativo da Web pela primeira vez e / ou HttpSessioné obtido pela primeira vez request.getSession(), o contêiner do servlet cria um novo HttpSessionobjeto, gera um ID longo e exclusivo (que você pode obter session.getId()) e o armazena no servidor. memória. O contêiner de servlet também define um Cookieno Set-Cookiecabeçalho da resposta HTTP com JSESSIONIDcomo nome e o ID da sessão exclusivo como valor.
De acordo com a especificação do cookie HTTP (um contrato que qualquer navegador e servidor da web decente deve aderir), o cliente (o navegador da web) deve enviar esse cookie de volta nas solicitações subsequentes no Cookiecabeçalho enquanto o cookie for válido ( ou seja, o ID exclusivo deve se referir a uma sessão não expirada e o domínio e o caminho estão corretos). Usando o monitor de tráfego HTTP interno do seu navegador, você pode verificar se o cookie é válido (pressione F12 no Chrome / Firefox 23+ / IE9 + e verifique a guia Rede / Rede ). O contêiner do servlet verificará o Cookiecabeçalho de cada solicitação HTTP recebida quanto à presença do cookie com o nome JSESSIONIDe usará seu valor (o ID da sessão) para obter o associado HttpSessionda memória do servidor.
As HttpSessionpermanece viva até que tenha sido ocioso (ou seja, não usado em uma solicitação) para mais do que o valor limite especificado no <session-timeout>, uma configuração no web.xml. O valor do tempo limite é padronizado em 30 minutos. Portanto, quando o cliente não visita o aplicativo da Web por mais tempo que o especificado, o contêiner do servlet descarta a sessão. Cada solicitação subsequente, mesmo com o cookie especificado, não terá mais acesso à mesma sessão; o contêiner de servlet criará uma nova sessão.
No lado do cliente, o cookie da sessão permanece ativo enquanto a instância do navegador estiver em execução. Portanto, se o cliente fechar a instância do navegador (todas as guias / janelas), a sessão será lixeira no lado do cliente. Em uma nova instância do navegador, o cookie associado à sessão não existiria, portanto não seria mais enviado. Isso faz com que um inteiramente novo HttpSessionseja criado, com um cookie de sessão totalmente novo sendo usado.
Em poucas palavras
- A
ServletContextvida útil enquanto durar o aplicativo da web. É compartilhado entre todos os pedidos em todas as sessões.
- A
HttpSessionvida útil enquanto o cliente estiver interagindo com o aplicativo Web com a mesma instância do navegador e a sessão não tiver atingido o tempo limite no servidor. É compartilhado entre todas as solicitações na mesma sessão.
- O
HttpServletRequeste HttpServletResponsevive desde o momento em que o servlet recebe uma solicitação HTTP do cliente, até a resposta completa (a página da web) chegar. É não compartilhada em outro lugar.
- Todos
Servlet, Filtere Listenercasos viver tanto tempo quanto o aplicativo web vive. Eles são compartilhados entre todas as solicitações em todas as sessões.
- Qualquer
attributeque está definido no ServletContext, HttpServletRequeste HttpSessionvai viver tanto tempo quanto o objeto na vida de interrogação. O objeto em si representa o "escopo" nas estruturas de gerenciamento de beans, como JSF, CDI, Spring, etc. Essas estruturas armazenam seus beans com escopo definido como um attributedos seus escopos correspondentes mais próximos.
Segurança da linha
Dito isto, sua principal preocupação é possivelmente a segurança do thread . Agora você deve saber que servlets e filtros são compartilhados entre todas as solicitações. Essa é a coisa boa do Java, é multithread e threads diferentes (leia-se: solicitações HTTP) podem fazer uso da mesma instância. Caso contrário, seria muito caro recriar, init()e destroy()eles para cada solicitação.
Você também deve perceber que nunca deve atribuir nenhum pedido ou dados com escopo de sessão como uma variável de instância de um servlet ou filtro. Será compartilhado entre todos os outros pedidos em outras sessões. Isso não é seguro para threads! O exemplo abaixo ilustra isso:
public class ExampleServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
Veja também: