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.xml
e todos incluídos web-fragment.xml
arquivos é analisado, e cada um <servlet>
, <filter>
e <listener>
encontrado (ou cada classe anotada com @WebServlet
, @WebFilter
e @WebListener
respectivamente) é 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 Servlet
tem 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 ( 1
1º, 2
2º, 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.xml
ou @WebServlet
classloading. 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
, Filter
e Listener
instâ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 HttpServletRequest
e HttpServletResponse
objetos e passa-los através de qualquer definido Filter
na cadeia e, por fim, a Servlet
instâ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 HttpSession
objeto, 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 Cookie
no Set-Cookie
cabeçalho da resposta HTTP com JSESSIONID
como 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 Cookie
cabeç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 Cookie
cabeçalho de cada solicitação HTTP recebida quanto à presença do cookie com o nome JSESSIONID
e usará seu valor (o ID da sessão) para obter o associado HttpSession
da memória do servidor.
As HttpSession
permanece 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 HttpSession
seja criado, com um cookie de sessão totalmente novo sendo usado.
Em poucas palavras
- A
ServletContext
vida útil enquanto durar o aplicativo da web. É compartilhado entre todos os pedidos em todas as sessões.
- A
HttpSession
vida ú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
HttpServletRequest
e HttpServletResponse
vive 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
, Filter
e Listener
casos viver tanto tempo quanto o aplicativo web vive. Eles são compartilhados entre todas as solicitações em todas as sessões.
- Qualquer
attribute
que está definido no ServletContext
, HttpServletRequest
e HttpSession
vai 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 attribute
dos 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: