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:
PHPSESSID
cookie, ASP.NET comASP.NET_SessionID
cookie, etc. É também por isso que a reescrita de URLs;jsessionid=xxx
como algumas estruturas JSP / Servlet MVC fazem automaticamente é desaprovada. Apenas certifique-se de que o ID da sessão nunca seja exposto na URL ou por outros meios nas páginas da Web, para que o usuário final inconsciente não seja atacado.Sessões
Em resumo: o servidor da web emite um identificador exclusivo para cada visitante em sua primeira visita. O visitante deve trazer de volta esse ID para que ele seja reconhecido na próxima vez. Esse identificador também permite que o servidor separe adequadamente os objetos pertencentes a uma sessão e a de outra.
Instanciação de Servlet
Se o carregamento na inicialização for falso :
Se o carregamento na inicialização for verdadeiro :
Quando ele estiver no modo de serviço e no ritmo, o mesmo servlet funcionará nas solicitações de todos os outros clientes.
Por que não é uma boa ideia ter uma instância por cliente? Pense nisso: você contratará um entregador de pizza para cada pedido que vier? Faça isso e você estará fora do negócio em pouco tempo.
Ele vem com um pequeno risco. Lembre-se: esse indivíduo único mantém todas as informações do pedido no bolso: portanto, se você não for cuidadoso com a segurança de threads nos servlets , ele poderá acabar dando o pedido errado a um determinado cliente.
fonte
to many requests at this moment. try again later
Sessão em servlets Java é igual à sessão em outras linguagens, como PHP. É exclusivo para o usuário. O servidor pode acompanhá-lo de diferentes maneiras, como cookies, reescrita de URL, etc. Este artigo sobre documentos em Java explica no contexto de servlets Java e indica que exatamente como a sessão é mantida é um detalhe de implementação deixado para os projetistas do servidor. A especificação apenas estipula que deve ser mantida como exclusiva para um usuário em várias conexões com o servidor. Confira este artigo da Oracle para obter mais informações sobre as duas perguntas.
Editar Há um excelente tutorial aqui sobre como trabalhar com sessões dentro de servlets. E aqui está um capítulo da Sun sobre Java Servlets, o que são e como usá-los. Entre esses dois artigos, você poderá responder a todas as suas perguntas.
fonte
ServletContext
objeto. Esse objeto possui zero, um ou mais objetos de sessão - uma coleção de objetos de sessão. Cada sessão é identificada por algum tipo de sequência identificadora, como visto nos desenhos animados em outra resposta. Esse identificador é rastreado no cliente por cookie ou reescrita de URL. Cada objeto de sessão possui suas próprias variáveis.Quando o contêiner de servlet (como o Apache Tomcat) for iniciado, ele lerá o arquivo web.xml (apenas um por aplicativo) se algo der errado ou aparecer um erro no console do lado do contêiner; caso contrário, ele implementará e carregará toda a web aplicativos usando web.xml (denominado como descritor de implementação).
Durante a fase de instanciação do servlet, a instância do servlet está pronta, mas não pode atender à solicitação do cliente porque está ausente com duas informações:
1: informações de contexto
2: informações de configuração inicial
O mecanismo do servlet cria o objeto de interface servletConfig que encapsula as informações ausentes acima nele, o mecanismo do servlet chama init () do servlet fornecendo referências ao objeto servletConfig como argumento. Depois que init () é completamente executado, o servlet está pronto para atender à solicitação do cliente.
P) Durante a vida útil do servlet, quantas vezes a instanciação e a inicialização ocorrem?
A) apenas uma vez (para cada solicitação de cliente, um novo encadeamento é criado) apenas uma instância do servlet atende a qualquer número da solicitação do cliente, ou seja, depois de atender a um servidor de solicitação do cliente não morre. Ele aguarda outras solicitações do cliente, ou seja, qual limitação de CGI (para cada solicitação de cliente é criada) é superada com o servlet (o mecanismo interno do servlet cria o encadeamento).
Q) Como o conceito de sessão funciona?
A) sempre que getSession () é chamado no objeto HttpServletRequest
Etapa 1 : o objeto de solicitação é avaliado para o ID da sessão recebida.
Etapa 2 : se o ID não disponível, um novo objeto HttpSession é criado e seu ID de sessão correspondente é gerado (por exemplo, de HashTable). O ID da sessão é armazenado no objeto de resposta httpservlet e a referência do objeto HttpSession é retornada ao servlet (doGet / doPost) .
Etapa 3 : se o ID disponível, o novo objeto de sessão não for criado, o ID da sessão será escolhido na pesquisa de objeto de solicitação feita na coleção de sessões, usando o ID da sessão como chave.
Depois que a pesquisa for bem-sucedida, o ID da sessão é armazenado no HttpServletResponse e as referências do objeto da sessão existentes são retornadas ao doGet () ou doPost () do UserDefineservlet.
Nota:
1) quando o controle sai do código do servlet para o cliente, não esqueça que o objeto da sessão está sendo mantido pelo contêiner do servlet, ou seja, o mecanismo do servlet
2) o multithreading é deixado para os desenvolvedores de servlets implementarem, por exemplo, manipular as múltiplas solicitações do cliente, nada para se preocupar com o código multithread
Formulário inshort:
Um servlet é criado quando o aplicativo é iniciado (implementado no contêiner do servlet) ou quando é acessado pela primeira vez (dependendo da configuração de carregar na inicialização) quando o servlet é instanciado, o método init () do servlet é chamado então o servlet (sua única e única instância) manipula todas as solicitações (seu método service () sendo chamado por vários encadeamentos). É por isso que não é aconselhável ter nenhuma sincronização, e você deve evitar variáveis de instância do servlet quando o aplicativo não estiver implementado (o contêiner do servlet para), o método destroy () é chamado.
fonte
Sessões - o que Chris Thompson disse.
Instanciação - um servlet é instanciado quando o contêiner recebe a primeira solicitação mapeada para o servlet (a menos que o servlet esteja configurado para carregar na inicialização com o
<load-on-startup>
elemento inweb.xml
). A mesma instância é usada para atender solicitações subsequentes.fonte
A especificação de servlet JSR-315 define claramente o comportamento do contêiner da Web nos métodos de serviço (e doGet, doPost, doPut etc.) (2.3.3.1 Problemas de multithreading, página 9):
fonte
Como ficou claro nas explicações acima, implementando o SingleThreadModel , um servlet pode ter segurança de thread garantida pelo contêiner do servlet. A implementação do contêiner pode fazer isso de duas maneiras:
1) Serializando solicitações (enfileiramento) para uma única instância - é semelhante a um servlet que NÃO implementa o SingleThreadModel, MAS sincroniza os métodos service / doXXX; OU
2) Criando um conjunto de instâncias - que é uma opção melhor e uma troca entre o esforço de inicialização / inicialização / hora do servlet e os parâmetros restritivos (tempo de memória / CPU) do ambiente que hospeda o servlet.
fonte
Não. Servlets não são seguros para threads
Isso permite acessar mais de um thread por vez
se você quiser torná-lo Servlet como Thread safe., U pode ir para
Implement SingleThreadInterface(i)
que é uma interface em branco, não hámétodos
ou podemos ir para métodos de sincronização
podemos fazer todo o método de serviço como sincronizado usando sincronizado
palavra-chave na frente do método
Exemplo::
ou podemos colocar o bloco do código no bloco Sincronizado
Exemplo::
Eu sinto que o bloco sincronizado é melhor do que fazer todo o método
Sincronizado
fonte