¿Cómo funcionan los servlets? Creación de instancias, sesiones, variables compartidas y subprocesos múltiples.

Resuelto Ku Jon asked hace 14 años • 8 respuestas

Supongamos que tengo un servidor web que contiene numerosos servlets. Para que la información pase entre esos servlets, estoy configurando variables de sesión e instancia.

Ahora bien, si 2 o más usuarios envían una solicitud a este servidor, ¿qué sucede con las variables de sesión?
¿Serán todos comunes para todos los usuarios o serán diferentes para cada usuario?
Si son diferentes, ¿cómo pudo el servidor diferenciar entre diferentes usuarios?

Una pregunta similar más: si hay nusuarios que acceden a un servlet en particular, entonces se crea una instancia de este servlet solo la primera vez que el primer usuario accedió a él o se crea una instancia para todos los usuarios por separado.
En otras palabras, ¿qué pasa con las variables de instancia?

Ku Jon avatar Jun 24 '10 07:06 Ku Jon
Aceptado

ServletContext

Cuando se inicia el contenedor de servlets (como Apache Tomcat ), implementará y cargará todas sus aplicaciones web. Cuando se carga una aplicación web, el contenedor de servlets crea una instancia de ServletContextuna vez y la mantiene en la memoria del servidor. Se analizan los archivos de la aplicación web web.xmly todos los incluidos , y cada uno y encontrado (o cada clase anotada con y respectivamente ) se creará una instancia una vez y también se mantendrá en la memoria del servidor, registrado a través del archivo . Para cada filtro instanciado, su método se invoca con una instancia de as argumento que a su vez contiene el archivo .web-fragment.xml<servlet><filter><listener>@WebServlet@WebFilter@WebListenerServletContextinit()FilterConfigServletContext

Cuando a Servlettiene un valor <servlet><load-on-startup>o mayor, su método también se invoca durante el inicio. Esos servlets se inicializan en el mismo orden especificado por ese valor. 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 , o carga de clases. En caso de que el valor "carga al inicio" esté ausente o sea negativo, el método se invocará cada vez que la solicitud HTTP llegue a ese servlet por primera vez. Hay dos métodos, uno que toma una instancia de como argumento que a su vez contiene el elemento involucrado y otro que no toma ningún argumento pero está disponible mediante un método heredado .@WebServlet(loadOnStartup)0init()web.xmlweb-fragment.xml@WebServletinit()init()ServletConfigServletContextServletContextgetServletContext()

Cuando el contenedor de servlets finalice con todos los pasos de inicialización descritos anteriormente, se ServletContextListener#contextInitialized()invocará con un ServletContextEventargumento que a su vez contiene el archivo ServletContext. Esto permitirá al desarrollador la oportunidad de registrar mediante programación otro archivo Servlet, Filtero Listener.

Cuando el contenedor de servlets se cierra, descarga todas las aplicaciones web, invoca el destroy()método de todos sus servlets y filtros inicializados, y todos los archivos Servlet, Filtery Listenerlas instancias registradas a través de se ServletContexteliminan. Finalmente ServletContextListener#contextDestroyed(), se invocará el will y ServletContextse eliminará.

HttpServletRequestyHttpServletResponse

El contenedor de servlets está conectado a un servidor web que escucha solicitudes HTTP en un número de puerto determinado (el puerto 8080 generalmente se usa durante el desarrollo y el puerto 80 en producción). Cuando un cliente (por ejemplo, un usuario con un navegador web o mediante programaciónURLConnection ) envía una solicitud HTTP, el contenedor de servlets crea nuevas instancias HttpServletRequesty HttpServletResponselas pasa a través de cualquiera definida Filteren la cadena y, eventualmente, la Servletinstancia.

En el caso de 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 con el siguiente filtro o llegan al servlet si no quedan filtros.

En el caso de servlets , service()se invoca el método. De forma predeterminada, este método determina cuál de los doXxx()métodos invocar en función de request.getMethod(). Si el método determinado no está en el 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 brinda 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, tanto los objetos de solicitud como de respuesta se reciclan y quedan disponibles para su reutilización.

HttpSession

Cuando un cliente visita la aplicación web por primera vez y/o la HttpSessionobtiene por primera vez a través de request.getSession(), el contenedor de servlets crea un nuevo HttpSessionobjeto, genera una identificación larga y única (que puede obtener mediante session.getId()) y lo almacena en el servidor. memoria. El contenedor de servlets también establece un Cookieen el Set-Cookieencabezado de la respuesta HTTP JSESSIONIDcomo nombre y el ID de sesión único como valor.

Según la especificación de cookies HTTP (un contrato que debe cumplir cualquier navegador web y servidor web decente), el cliente (el navegador web) debe enviar esta cookie de vuelta en solicitudes posteriores en el Cookieencabezado mientras la cookie sea válida ( es decir, el ID único debe hacer referencia a una sesión vigente y el dominio y la ruta son correctos). Usando el monitor de tráfico HTTP integrado de su navegador, puede verificar que la cookie sea válida (presione F12 en Chrome/Edge/Firefox 23+/IE9+ y verifique la pestaña Red/Red ). El contenedor de servlets comprobará el Cookieencabezado de cada solicitud HTTP entrante para detectar la presencia de la cookie con el nombre JSESSIONIDy utilizará su valor (el ID de la sesión) para obtener la asociada HttpSessionde la memoria del servidor.

Permanece HttpSessionactivo hasta que ha estado inactivo (es decir, no se ha utilizado en una solicitud) durante más del valor de tiempo de espera especificado en <session-timeout>, una configuración en web.xml. El valor de tiempo de espera predeterminado depende del contenedor de servlet y suele ser de 30 minutos. Entonces, cuando el cliente no visita la aplicación web durante más tiempo del especificado, el contenedor de servlets descarta la sesión . Cada solicitud posterior, incluso con la cookie especificada, ya no tendrá acceso a la misma sesión; el contenedor de servlets creará una nueva sesión.

En el lado del cliente, la cookie de sesión permanece mientras la instancia del navegador se esté ejecutando (normalmente). A menos que el navegador esté configurado para restaurar la última sesión del navegador , cuando el cliente cierra la instancia del navegador (todas las pestañas/ventanas), la sesión se pierde por parte 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 que HttpSessionse cree una cookie de sesión completamente nueva y se utilice una cookie de sesión completamente nueva.

En una palabra

  • Viven ServletContextmientras dure la aplicación web. Se comparte entre todas las solicitudes en todas las sesiones.
  • Vive HttpSessionmientras el cliente interactúe con la aplicación web con la misma instancia del navegador y la sesión no haya expirado en el lado del servidor. Se comparte entre todas las solicitudes en la misma sesión.
  • El HttpServletRequesty HttpServletResponseestá activo desde el momento en que el servlet recibe una solicitud HTTP del cliente hasta que llega la respuesta completa (la página web). No se comparte en ningún otro lugar.
  • Todas Servletlas instancias Filtery Listenertienen vigencia mientras dure la aplicación web. Se comparten entre todas las solicitudes en todas las sesiones.
  • Cualquiera attributeque esté definido en ServletContexty vivirá mientras viva el objeto en cuestión HttpServletRequest. HttpSessionEl objeto en sí representa el "alcance" en los marcos de administración de beans como JSF, CDI, Spring, etc. Esos marcos almacenan sus beans con alcance como attributesu alcance más cercano.

Seguridad del hilo

Dicho esto, su principal preocupación posiblemente sea la seguridad de los hilos . Ahora deberías saber que los servlets y 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()hacerlos para cada solicitud.

También debe tener en cuenta que nunca debe asignar datos de ámbito de solicitud o 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:

  • ¿Cuál es la diferencia entre JSF, Servlet y JSP?
  • La mejor opción para la gestión de sesiones en Java
  • Diferencia entre / y /* en el patrón de URL de mapeo de servlets
  • doGet y doPost en Servlets
  • Servlet parece manejar múltiples solicitudes simultáneas del navegador de forma sincrónica
  • ¿Por qué los servlets no son seguros para subprocesos?
  • Diferentes formas de obtener contexto de servlet
BalusC avatar Jun 24 '2010 02:06 BalusC

Sesiones

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

En resumen: el servidor web emite un identificador único a cada visitante en su primera visita. El visitante debe traer esa identificación para que lo reconozcan la próxima vez. Este identificador también permite al servidor segregar adecuadamente los objetos que pertenecen a una sesión frente a los de otra.

Creación de instancias de servlet

Si la carga al inicio es falsa :

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Si la carga al inicio es verdadera :

ingrese la descripción de la imagen aquí ingrese la descripción de la imagen aquí

Una vez que esté en el modo de servicio y en el ritmo, el mismo servlet funcionará en las solicitudes de todos los demás clientes.

ingrese la descripción de la imagen aquí

¿Por qué no es una buena idea tener una instancia por cliente? Piensa en esto: ¿contratarás a un pizzero por cada pedido que llegue? Haga eso y estará fuera del negocio en poco tiempo.

Sin embargo, conlleva un pequeño riesgo. Recuerde: este único tipo guarda toda la información del pedido en su bolsillo: por lo tanto, si no tiene cuidado con la seguridad de los subprocesos en los servlets , puede terminar dando el pedido incorrecto a un determinado cliente.

Jops avatar Jul 06 '2013 16:07 Jops

La sesión en los servlets de Java es la misma que la sesión en otros lenguajes como PHP. Es exclusivo del usuario. El servidor puede realizar un seguimiento de él de diferentes maneras, como cookies, reescritura de URL, etc. Este artículo del documento Java lo explica en el contexto de los servlets Java e indica que exactamente cómo se mantiene la sesión es un detalle de implementación que se deja a los diseñadores del servidor. La especificación sólo estipula que debe mantenerse como exclusivo para un usuario en múltiples conexiones al servidor. Consulte este artículo de Oracle para obtener más información sobre sus dos preguntas.

Editar Aquí hay un excelente tutorial sobre cómo trabajar con sesiones dentro de servlets. Y aquí hay un capítulo de Sun sobre los Servlets Java, qué son y cómo usarlos. Entre esos dos artículos, debería poder responder todas sus preguntas.

Chris Thompson avatar Jun 24 '2010 00:06 Chris Thompson