Los servlets proporcionan una forma de comunicarse con las requests de los clientes y generar respuestas dinámicas basadas en el modelo de programación de solicitud-respuesta. Los servlets pueden responder a cualquier tipo de solicitud pero, en la mayoría de los casos, se utilizan en aplicaciones web alojadas en servidores web. Para estas aplicaciones, los Java Servlets definen HTTP: clases de servlet específicas. Para escribir Servlets, Java Servlet API proporciona interfaces y clases en paquetes javax.servlet y javax.servlet.http . La interfaz de servlet define el ciclo de vida del servlet. Debemos extender la clase GenericServlet o la clase HTTPServlet (específica de la solicitud/respuesta HTTP) para manejar las requests de los clientes en las aplicaciones web.
Flujo de Ejecución de Servlets
En la ejecución de un servlet para la solicitud del cliente proporcionada, el contenedor de servlet juega un papel crucial en el ciclo de vida del servlet.
Contenedor de servlets:
Es un contenedor web que forma parte de un servidor web que interactúa con los Java Servlets. El contenedor de servlet es responsable de
- Gestión del ciclo de vida de los servlets
- Creación de objetos de servlet, de solicitud y de respuesta
- Asignación de una URL a un servlet en particular
- Asegurarse de que el solicitante de la URL tenga los derechos de acceso correctos
- Administrar la ejecución de páginas JSP, etc.
Antes de que se pueda ejecutar un componente de cliente de aplicación, se debe implementar en el contenedor. Todos estos componentes web y el contenedor se ejecutan en el servidor web/de aplicaciones.
Programa de servlets:
Para comprender el flujo de ejecución del servlet, crearemos una aplicación web simple para mostrar el mensaje de saludo en el navegador del cliente. En este ejemplo, usaremos Eclipse IDE y el servidor Tomcat. Cree los siguientes archivos como se muestra en la siguiente estructura de directorios del paquete.
Ejemplo
Archivos para crear:
- Cree un proyecto de «aplicación web dinámica» en Eclipse.
- Cree el archivo » index.html» para recibir información del cliente en la solicitud.
- Cree “ HelloServlet.java” para procesar la solicitud y generar la respuesta.
- Cree un archivo » web.xml» para especificar la asignación de URL al servlet respectivo.
índice.html:
Cree el siguiente formulario para tomar el nombre de usuario como entrada del navegador del cliente.
HTML
<!DOCTYPE html> <html> <head> <meta charset="ISO-8859-1"> <title>Home</title> </head> <body> <form action="hello" method="post"> Enter your name and click on submit: <input type="text" name="name" /> <input type="submit" /> </form> </body> </html>
HolaServlet.java:
Cree a continuación el servlet para aceptar la solicitud del cliente, procesarla y generar la respuesta.
Java
package com; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // Get the client entered data from request object String name = request.getParameter("name"); // set the response content type response.setContentType("text/html"); PrintWriter out = response.getWriter(); // Print hello message to the client browser in // response object out.println("<h3>Hello " + name + "!!</h3>"); out.close(); } }
web.xml:
Cree un descriptor de implementación: archivo web.xml para mencionar el archivo de bienvenida y asignar la URL a la clase Servlet.
XML
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>ServletFlow</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>com.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HelloServlet</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
Ejecución del Programa
- Haga clic con el botón derecho en el proyecto, » Ejecutar como -> Ejecutar en el servidor»
- Mientras se inicia el servidor, la aplicación web se implementará en el servidor.
Paso 1:
A continuación se muestra el diagrama conceptual del contenedor de servlets después del despliegue de la aplicación.
Como se muestra en el diagrama anterior,
En el lado del servidor:
- El contenedor de servlet está disponible en el servidor principal y la aplicación web se implementa en un contenedor de servlet.
- Dentro del contenedor, tenemos la siguiente estructura de carpetas.
- Aplicación web: en este ejemplo, » ServletFlow»
- Dentro de esa carpeta WEB-INF, tenemos una asignación de URL al nombre del servlet.
- Dentro de WEB-INF, archivo web.xml y carpeta de clases para mantener el archivo .class de “ HelloServlet.java”
Del lado del cliente:
- Un navegador estará disponible para enviar los datos del cliente en una solicitud HTTP y recibir la respuesta HTTP del servidor.
- El protocolo establecerá una conexión de socket virtual entre el cliente y el servidor según la dirección IP y el número de puerto.
Paso 2:
Cuando iniciamos el servidor, el trabajo del contenedor de servlet es
- Reconocer todas las aplicaciones web
- Implementar esas aplicaciones web y
- Prepare un objeto separado para cada aplicación. Este objeto es un objeto » servletContext» .
Al implementar aplicaciones web,
- El contenedor reconocerá el archivo web.xml en la carpeta WEB-INF.
- Después de identificar el archivo web.xml, el contenedor realizará la carga, el análisis y la lectura del contenido del archivo web.xml.
- Si algún dato a nivel de aplicación, como nombres para mostrar o parámetros de contexto, está disponible en el archivo web.xml, el contenedor tomará esos datos de la aplicación y los almacenará en el objeto » servletContext «. Estos datos son administrados por un objeto de contexto de servlet.
Ahora, el contenedor identificará la página del archivo de bienvenida para mostrar en el navegador del cliente según la » lista de archivos de bienvenida» mencionada en el archivo » web.xml» . Aquí especificamos “ index.html” como un archivo de bienvenida. Entonces, muestra esa página HTML en el navegador. URL: http://localhost:8081/ServletFlow/
Una vez que ingresamos el nombre y hacemos clic en enviar, luego llegará una solicitud de protocolo con los datos ingresados por el cliente.
Paso 3:
- El protocolo preparará el formato de la solicitud, tiene 2 partes, el encabezado de la solicitud y el cuerpo de la solicitud.
- El encabezado de la solicitud contiene los detalles sobre el navegador del cliente.
- Por ejemplo: tipo de método de solicitud, información de protocolo, idiomas aceptados por el navegador del cliente, información de cookies, mecanismos de codificación admitidos por el navegador del cliente, etc.
- Los datos reales ingresados en el formulario de usuario se almacenarán en el cuerpo de la solicitud en forma de parámetros de solicitud.
- El protocolo llevará este formato de Solicitud al servidor principal.
- Luego, el servidor verificará si la solicitud es válida o no.
- Si es válido, reenviará esa solicitud al contenedor de servlets.
- Ahora, el contenedor identificará cuál es el nombre de la aplicación y el nombre del recurso para ejecutar.
- El contenedor verificará si la solicitud es una solicitud HTML según las extensiones y los nombres de los recursos.
- Como especificamos en el formulario, el contenedor identificará el servlet para ejecutar en función del patrón de URL (» hola») que está asociado con el archivo » HelloServlet.class» en la carpeta de clases.
- Para identificarlo, el contenedor irá por aplicación, carpeta WEB-INF y archivo web.xml.
- En el archivo web.xml, los detalles de asignación están disponibles. por lo tanto, el contenedor obtendrá ese servlet en particular según el patrón de URL y luego el contenedor buscará en la carpeta de clases y buscará el archivo .class requerido.
- Una vez que el contenedor identifique el archivo .class del servlet, comenzará el ciclo de vida del servlet.
Paso 4: ciclo de vida del servlet
Carga de servlets:
- El primer contenedor realizará la carga de Servlet.
- El contenedor verificará si el mismo servlet ya está disponible o no, si no, carga el archivo .class, el código de bytes en la memoria.
- Para realizar esto, el contenedor llamará a class c = class.forName(“helloServlet”); internamente.
Instanciación de Servlet:
- Después de cargar el servlet, crea un objeto para el servlet.
- Y crea un objeto » servletConfig» para ese servlet y almacena todos los datos de ese servlet en particular en él.
- Para realizar esto, el contenedor llamará al objeto obj = c.newInstance(); internamente.
Inicialización del servlet:
- Ahora necesitamos inicializar el servlet, el contenedor llamará a init() pasándole el objeto servletConfig .
- Primero, el contenedor ejecutará el método init() parametrizado. Dentro de eso, se llamará a otro método sin parámetro init() desde el servlet genérico y ese método también se ejecutará.
- Ahora, el contenedor creará objetos de solicitud HTTP y respuesta HTTP y un hilo para ejecutar el método dopost().
- En el caso de GenericServlet, el primer contenedor llamará al método service() en el servlet genérico, sin pasar por la solicitud del servlet y los objetos de respuesta del servlet como parámetros.
- Aquí, como se trata de una solicitud específica de HTTP, estamos usando HTTPServlet y necesitamos ejecutar el método doPost() pasando la solicitud del servlet Http y la respuesta del servlet Http.
- Entonces el contenedor accederá al método doPost(). Finalmente, esa solicitud llega al método dopost() del servlet.
- El propósito del objeto de solicitud HTTP es almacenar los datos especificados por el cliente. Se trata principalmente de 3 tipos de datos, encabezados de solicitud, datos de parámetros de solicitud y datos de atributos de solicitud.
- Encabezados de solicitud: para almacenar la información sobre el navegador del cliente.
- Solicitar datos de parámetros: Para almacenar la información real ingresada por el cliente para su procesamiento.
- Solicitar datos de atributos: para almacenar cualquier dato dinámico que se genere mientras se ejecuta el servlet.
- Una vez que se ejecuta el método “doPost()” , la respuesta se generará en el objeto de respuesta.
- Cuando el contenedor llega al final de la ejecución del método doPost(), ese hilo se destruirá y el contenedor enviará esa respuesta al servidor principal.
- El servidor principal transferirá la respuesta HTTP al protocolo.
- El protocolo preparará un formato de respuesta que tendrá un encabezado de respuesta y un cuerpo de respuesta.
- Encabezado de respuesta: contiene metadatos como qué tipo de respuesta está llegando, la duración de esa respuesta, etc.
- Cuerpo de respuesta: respuesta dinámica real que se mostrará en el navegador del cliente.
Paso 5:
- El protocolo llevará ese objeto de respuesta al navegador del cliente.
- El navegador obtendrá los datos del cuerpo de la respuesta y se mostrarán en el navegador.
- Cuando la respuesta se muestra en el lado del cliente, el protocolo destruirá la conexión entre el cliente y el servidor.
- Luego, el contenedor comprenderá que la respuesta se envía al cliente y destruirá el objeto de solicitud y los objetos de respuesta.
- Ahora el contenedor estará a la espera del estado para más requests.
- Según la implementación del contenedor y en función de los servidores de aplicaciones, el contenedor destruirá el servlet.
- Por ejemplo: en el caso del servidor Tomcat, el contenedor esperará hasta que se apague el servidor. En el caso del servidor Weblogic esperará el tiempo especificado en el servidor.
- Entonces, cuando la aplicación realiza el trabajo y el servidor se detiene, el contenedor destruirá el objeto de configuración del servlet y luego el objeto del servlet.
- Destruir un objeto de servlet no es más que eliminar la instancia del servlet llamando al método destroy() .
- El contenedor descargará el código de bytes del servlet de la memoria y destruirá el objeto «ServletContext» .
Conclusión
Los Java Servlets no tienen un método main() . Es el trabajo de Servlet Container instanciar el servlet o crear un nuevo hilo para manejar los objetos de solicitud y respuesta. Para procesar varias requests en un solo servlet, el contenedor crea varios subprocesos. También puede monitorear y reaccionar ante estos eventos en el ciclo de vida de un servlet definiendo objetos de escucha. Los métodos en los objetos de escucha se invocan cuando ocurren eventos del ciclo de vida.
Publicación traducida automáticamente
Artículo escrito por yaminitalisetty y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA