ServletContext
Cuando se inicia el contenedor de servlets (como Apache Tomcat ), desplegará y cargará todas sus aplicaciones web. Cuando se carga una aplicación web, el contenedor de servlet crea ServletContextuna vez y la mantiene en la memoria del servidor. La aplicación web de web.xmly todos incluidos web-fragment.xmlse analiza archivos, y cada uno <servlet>, <filter>y <listener>encontraron (o cada clase anotados con @WebServlet, @WebFiltery @WebListenerrespectivamente) se instancia una vez y se mantienen en la memoria del servidor también. Para cada filtro instanciado, su init()método se invoca con un nuevo FilterConfig.
Cuando a Servlettiene un valor <servlet><load-on-startup>o @WebServlet(loadOnStartup)mayor que 0, entonces su init()método también se invoca durante el inicio con un nuevo ServletConfig. Esos servlets se inicializan en el mismo orden especificado por ese valor ( 1es 1º, 2es 2º, etc.). Si se especifica el mismo valor para más de un servlet, entonces cada uno de esos servlets se carga en el mismo orden en que aparecen en el web.xml, web-fragment.xmlo @WebServletcarga de clase. En el caso de que el valor de "carga al inicio" esté ausente, el init()método se invocará siempre que la solicitud HTTP llegue a ese servlet por primera vez.
Cuando el contenedor de servlet finalice con todos los pasos de inicialización descritos anteriormente, ServletContextListener#contextInitialized()se invocará.
Al cerrarse la contenedor de servlets abajo, descarga todas las aplicaciones Web, invoca el destroy()método de todas sus servlets y filtros inicializados, y todo ServletContext, Servlet, Filtery Listenerlos casos están destrozados. Finalmente ServletContextListener#contextDestroyed()se invocará el.
HttpServletRequest y HttpServletResponse
El contenedor de servlet está conectado a un servidor web que escucha las solicitudes HTTP en un determinado número de puerto (el puerto 8080 generalmente se usa durante el desarrollo y el puerto 80 en producción). Cuando un cliente (por ejemplo, usuario con un navegador web, o mediante programaciónURLConnection ) envía una solicitud HTTP, el contenedor servlet crea nueva HttpServletRequesty HttpServletResponseobjetos y los pasa a través de cualquier definido Filteren la cadena y, eventualmente, la Servletinstancia.
En el caso de los filtros , doFilter()se invoca el método. Cuando el código del contenedor de servlet llama chain.doFilter(request, response), la solicitud y la respuesta continúan al siguiente filtro, o presionan el servlet si no hay filtros restantes.
En el caso de los servlets , service()se invoca el método. Por defecto, este método determina cuál de los doXxx()métodos invocar en función de request.getMethod(). Si el método determinado está ausente del servlet, se devuelve un error HTTP 405 en la respuesta.
El objeto de solicitud proporciona acceso a toda la información sobre la solicitud HTTP, como su URL, encabezados, cadena de consulta y cuerpo. El objeto de respuesta proporciona la capacidad de controlar y enviar la respuesta HTTP de la manera que desee, por ejemplo, permitiéndole configurar los encabezados y el cuerpo (generalmente con contenido HTML generado a partir de un archivo JSP). Cuando la respuesta HTTP se confirma y finaliza, los objetos de solicitud y respuesta se reciclan y se ponen a disposición para su reutilización.
HttpSession
Cuando un cliente visita la aplicación web por primera vez y / o HttpSessionse obtiene por primera vez a través de request.getSession(), el contenedor de servlet crea un nuevo HttpSessionobjeto, genera un ID largo y único (que puede obtener session.getId()) y lo almacena en el servidor memoria. El contenedor de servlets también establece una Cookieen la Set-Cookiecabecera de la respuesta HTTP con JSESSIONIDcomo su nombre y el identificador de sesión único como su valor.
Según la especificación de cookies HTTP (un contrato al que debe adherirse cualquier navegador web y servidor web decente), el cliente (el navegador web) debe enviar esta cookie en solicitudes posteriores en el Cookieencabezado mientras la cookie sea válida ( es decir, la ID única debe referirse a una sesión no vencida y el dominio y la ruta son correctos). Usando el monitor de tráfico HTTP incorporado de su navegador, puede verificar que la cookie sea válida (presione F12 en Chrome / Firefox 23+ / IE9 +, y verifique la pestaña Red / Red ). El contenedor del servlet verificará el Cookieencabezado de cada solicitud HTTP entrante en busca de la presencia de la cookie con el nombre JSESSIONIDy usará su valor (el ID de sesión) para obtener el asociado HttpSessionde la memoria del servidor.
El HttpSessionpermanece vivo hasta que haya estado inactivo (es decir, no utilizado en una solicitud) durante más tiempo que el valor de tiempo de espera especificado en <session-timeout>una configuración web.xml. El valor de tiempo de espera predeterminado es 30 minutos. Por lo tanto, cuando el cliente no visita la aplicación web durante más tiempo que el especificado, el contenedor de servlets destruye la sesión. Cada solicitud posterior, incluso con la cookie especificada, ya no tendrá acceso a la misma sesión; el contenedor de servlet creará una nueva sesión.
En el lado del cliente, la cookie de sesión permanece viva mientras se ejecuta la instancia del navegador. Entonces, si el cliente cierra la instancia del navegador (todas las pestañas / ventanas), la sesión se descarta del lado del cliente. En una nueva instancia del navegador, la cookie asociada con la sesión no existiría, por lo que ya no se enviaría. Esto hace HttpSessionque se cree una completamente nueva, con una cookie de sesión completamente nueva que se utiliza.
En una palabra
- La
ServletContextvida dura tanto como la aplicación web. Se comparte entre todas las solicitudes en todas las sesiones.
- La
HttpSessionvida dura mientras el cliente interactúa con la aplicación web con la misma instancia del navegador, y la sesión no ha expirado en el lado del servidor. Se comparte entre todas las solicitudes en la misma sesión.
- El
HttpServletRequesty HttpServletResponsevive desde el momento en que el servlet recibe una solicitud HTTP del cliente, hasta que llega la respuesta completa (la página web). Se no compartida en otro lugar.
- Todo
Servlet, Filtery Listenercasos viven tanto como vive la aplicación web. Se comparten entre todas las solicitudes en todas las sesiones.
- Cualquiera
attributeque esté definido en ServletContext, HttpServletRequesty HttpSessionvivirá mientras viva el objeto en cuestión. El objeto en sí mismo representa el "alcance" en los marcos de gestión de beans como JSF, CDI, Spring, etc. Esos marcos almacenan sus beans de ámbito como uno attributede sus ámbitos de coincidencia más cercanos.
Hilo de seguridad
Dicho esto, su mayor preocupación es posiblemente la seguridad del hilo . Ahora debe saber que los servlets y los filtros se comparten entre todas las solicitudes. Eso es lo bueno de Java, es multiproceso y diferentes subprocesos (léase: solicitudes HTTP) pueden hacer uso de la misma instancia. De lo contrario, sería demasiado costoso recrearlos init()y destroy()cada solicitud individual.
También debe darse cuenta de que nunca debe asignar ninguna solicitud o datos con alcance de sesión como una variable de instancia de un servlet o filtro. Se compartirá entre todas las demás solicitudes en otras sesiones. ¡Eso no es seguro para subprocesos! El siguiente ejemplo ilustra esto:
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.
}
}
Ver también: