porVandana Pursnani
Traducido por Germán Rojo Eguren
Los primeros sitios web no eran sino colecciones de páginas web enlazadas entre ellas por el Lenguaje HTML. Hoy en día, los sitios web incluyen multimedia, aplicaciones de comercio electrónico, y otro tipo de sofisticadas aplicaciones basadas en Web como voz IP y banca online. Además de los avances en contenido, se han producido avances en las tecnologías de servidores web, como el desarrollo de servidores de aplicaciones, y tecnologías de creación dinámica de contenido, como las páginas JSP y las páginas ASP.
Este artículo describe la tecnología de Java Servlets. En primer lugar, se provee información de trasfondo sobre los servidores web, contenedores web y servidores de aplicaciones. Después, este artículo aborda la implementación de la API de Servlets en las aplicaciones web. Finalmente, el artículo también aborda las ventajas de los servlets y una breve comparación con los scripts CGI.
Cuando visitas un restaurante, el camarero coge tu pedido y se lo pasa al personal de la cocina. Cuando el pedido se ha completado, el camarero te trae la comida. Las actividades que se desarrollan en la cocina, son invisibles para tí. La cocina, al igual que la web, opera según un modelo cliente/servidor. Al escribir la dirección de un sitio web o una URL en un navegador, o cliente, se inicia una petición al servidor que alberga el sitio. Cualquier acción que realice el servidor es transparente para los visitantes del sitio. En una arquitectura cliente/servidor típica de 2-capas, el contenido del sitio web (la capa de presentación del sitio web) como las páginas HTML, los servlets, las JSP, las ASP, software de correo, los scripts CGI, etc... se almacenan en el servidor web. Los sistemas de 2-capas más viejos, como los de la figura 1, estaban hechos de un servidor web o contenedor, y el navegador.
Figura 1: Arquitectura 2-capas (Cliente/Servidor)
El servidor de aplicaciones es una extensión del modelo cliente/servidor
2-capas a una aproximación de N-capas. El servidor de aplicaciones tiene
un servidor o contenedor web integrado y un contenedor de apliaciones. Un ejemplo
es el modelo de aplicaciones J2EE (Edición Empresarial de Java 2) [12]. Este modelo es el implementado en servidores de aplicación
como el WebSphere de IBM, el BEA WebLogic, etc... La Figura
2 demuestra la aproximación de N-capas.
Figura 2: Arquitectura de N-capas
La aproximación de N-capas es ideal para la generación de contenido dinámico. Los Servlets de Java, que heredan las características de Java y más, han asumido un papel prominente en los servidores de aplicaciones.
Los Servlets son componentes del servidor. Estos componentes pueden ser ejecutados en cualquier plataforma o en cualquier servidor debido a la tecnología Java que se usa para implementarlos. Los Servlets incrementan la funcionalidad de una aplicación web. Se cargan de forma dinámica por el entorno de ejecución Java del servidor cuando se necesitan. Cuando se recibe una petición del cliente, el contenedor/servidor web inicia el servlet requerido. El Servlet procesa la petición del cliente y envía la respuesta de vuelta al contenedor/servidor, que es enrutada al cliente [1].
Figura 3: Modelo de respuesta a peticiones HTTP
La interacción cliente/servidor basada en Web usa el protocolo HTTP. EL protocolo HTTP es un protocolo sin estados basado en un modelo de petición y respuesta con un número pequeño y finito de métodos de petición como GET, POST, HEAD, OPTIONS, PUT, TRACE, DELETE, CONNECT, etc.. La respuesta contiene el estado de la respuesta y meta-información describiendo dicha respuesta. La mayor parte de las aplicaciones web basadas en servlets se construyen en el marco de trabajo del modelo petición/respuesta HTTP (Figura 3).
Una vez que el contenedor/servidor básico se ha bajado y configurado, el siguiente paso es entender la programación de servlets. El API Servlet tiene dos paquetes, el javax.servlet [7], que tiene clases y paquetes independientes de protocolos, y el javax.servlet.http [7], que es más específico para el protocolo HTTP.
Antes de meternos en el ciclo de vida de los servlets, necesitamos comprender las clases básicas y los interfaces usados en la implementación del servlet.
Todo servlet debe directa o indirectamente implementar este interfaz. Como cualquier otro interfaz de Java, este es también una colección de declaraciones vacías de métodos. Los siguientes métodos están declarados en el interfaz Servlet.[8]
public abstract void init (ServletConfig config) throws ServletException.
El método init se usa para inicializar los parámetros proporcionados por el objeto ServletConfig. Se invoca sólo una vez, a menos que el servlet sea reiniciado si se destruye y se vuelve a cargar. El método init es el lugar en el que inicializar los parámetros de configuración como la conexión con una base de datos, la inicialización de archivos y otros valores de entorno. Ninguno método del servlet puede ser invocado a no ser que el servlet esté inicializado mediante el uso del método init().
public abstract ServletConfig getServletConfig ()
Este método proporciona el objeto ServletConfig para la inicialización de los parámetros del servlet. Se pueden crear parámetros adicionales especificándolos en el archivo servlet.properties. Una vez que hayan sido especificados en este archivo, se puede acceder a ellos usando el objeto ServletConfig.
public abstract void service (ServletRequest req, ServletResponse
res) throws ServletException, IOException.
El método service es el punto esencial del modelo petición respuesta del protocolo HTTP. Recibe una petición del cliente en forma de objeto ServletRequest. Los parámetros del cliente son pasados junto al objeto de petición (aunque existen otras formas de enviar parámetros desde el cliente al servlet, por ejemplo, usando cookies o por medio de una reescritura del URL). La respuesta resultante se envia al cliente usando el objeto ServletResponse.
public abstract String getServletInfo()
Este método se usa para la extracción de metadatos del servlet,
como por ejemplo el autor, la versión del servlet, y otra información
concerniente al copyright. El método tendrá que ser redefinido
dentro del servlet para que devuelva esta información.
public abstract void destroy ()
El método destroy se invoca para liberar todos los recursos solicitados como la base de datos, y otros recursos del servidor. También se encarga de la sincronización de cualquier hilo pendiente. Este método se llama una sola vez, automáticamente, como el método init.
La clase GenericServlet proporciona una implementación básica del interfaz Servlet. Para escribir un servlet especificamente para el protocolo HTTP, se usa la clase HTTPServlet, que extiende a Generic Servlet (Figura 4).
Figura 4: Clases Relevantes de Servlets e Interfaces.
Como se ha tratado previamente, el ciclo de vida de los eventos para un servlet (Figura 5) se especifica en el interfaz javax.servlet.Servlet. Todos los servlets siguen el modelo del ciclo de vida. El contenedor web tiene la responsabilidad de crear una instancia del servlet y de invocar al método init (1). Si un cliente ha enviado una petición al contenedor web, entonces, esa petición se pasa al método servicio del servlet (2), y se envia una respuesta de vuelta al contendor web (3). Finalmente, cuando el servlet haya finalizado su propósito, el contenedor web invoca al método destroy (4).
Figura 5: Ciclo de Vida del Servlet
Además de los métodos que heredan de la clase GenericServlet, la clase HTTPServlet tiene métodos adicionales para cada uno de los métodos de respuesta HTTP tratados antes.
doDelete (HttpServletRequest, HttpServletResponse) doGet (HttpServletRequest, HttpServletResponse)doOptions (HttpServletRequest, HttpServletResponse)doPost (HttpServletRequest, HttpServletResponse)doPut (HttpServletRequest, HttpServletResponsedoTrace (HttpServletRequest, HttpServletResponse)Por ejemplo, la clase Servlet tiene que redefinir doGet o doPost
(o ambos métodos, dependiendo de si los datos serán enviados por
un GET o por métodos de petición POST HTTP). Estos métodos
toman dos parámetros: un objeto HttpServletRequest y un
objeto HttpServletResponse. Estos dos objetos dan acceso total
a toda la información sobre la petición del cliente, y ayudan
a controlar la salida enviada al cliente como respuesta a dicha petición.
Los métodos doGet y doPost son invocados por
el método service. El método service puede usarse
directamente al redefinirlo.
Para demostrar el ciclo de vida de un servlet, echémosle un vistazo a un sencillo programa servlet. Este programa importa el paquete básico para crear un servlet, javax.servlet. Este programa implementará el interfaz servlet. Define el método init, que toma como parámetro un objeto ServletConfig para establecer las propiedades del servlet. Tiene un método principal service que toma como parámetros los objetos de petición y respuesta. Todo el procedimiento del servlet gira en torno a estos objetos. La petición del cliente va adjunta en el objeto de petición, y la respuesta del servlet se envía en el objeto de respuesta. Este servlet sólo proporciona una respuesta sencilla de escritura de una frase como salida html.
import java.io.*;
import javax.servlet.*;
public SimpleServlet implements Servlet
{
private ServletConfig config;
public void init (ServletConfig config) throws ServletException
{
this.config = config;
// El objeto de configuración proporciona parámetros de inicialización al servlet
}
public void destroy() { // se pueden realizar tareas de finalización aquí }
public void service (ServletRequest req, ServletResponse res) throws ServletException, IOException
{
res.setContentType( "text/html" ); // setting MIME type
PrintWriter out = res.getWriter();
// flujo de salida para la escritura de información en el cliente
out.println (<html>" );
out.println( "<head>" ); //Se genera el código del cliente
out.println( "<title>FIRST SERVLET</title>" );
out.println( "</head>" );
out.println( "<body>" );
out.println( "<h1>This is my First Servlet</h1>" );
out.println( "</body>" );
out.println( "</html>" );
out.close();
}
} // Fin de la clase
Una vez que el servlet haya sido compilado, es necesario instalarlo en el contenedor web en su adecuada localización o en un directorio por defecto de servlets. Esto es algo que cambia con cada servidor; para los servidores web de iPlanet [4], los servlets pueden estar en el directorio c:\netscape\server4\docs\servlets. Otra opción para el servidor web iPlanet es que se configure la ruta de los servlets en la pestaña de servlets (directorio de servlets) de la consola del servidor web iPlanet, de forma que pueda localizar el programa servlet durante la ejecución. Una vez que el programa esté en su directorio por defecto, el cliente puede invoarlo cuando especifica la dirección de la web o la URL en su navegador.
Los servlets añaden comportamiento dinámico a los servidores. La API de programación de los servlets hace muy fácil la escritura de servicios complejos para aplicaciones basadas en web, sin tener que centrarse en los detalles de bajo nivel de los protocolos HTTP, formatos de petición, y cabeceras. Puesto que los servlets tienen un marco de trabajo similar al Java, son independientes de la plataforma tanto en el cliente como en el servidor. Además, los servlets pueden ser enlazados con diferentes bases de datos, como Oracle, Servidores SQL, etc... y también con varios servidores web.
Los Servlets de java son extensiones directas del servidor web. Simplemente, son objetos Java que se cargan de forma dinámica por el Entorno de Ejecución del Java (JRE) cuando se necesitan. Cuando un proceso se inicia en un servidor, necesita la asignación de varios recursos. El cambio entre procesos implica también mucha sobrecarga debido al cambio de contexto al tener que grabar toda la información de un proceso para volver más tarde a él. A un proceso se le puede llamar hilo pesado debido a que inicia un proceso completo, con una enorme cantidad de sobrecarga en términos de tiempo, memoria, etc... Por el contrario, por cada petición a un servlet, se crea un hilo ligero para manejarla. Un hilo ligero es un proceso hijo, que es controlado por el proceso padre (en este caso, el servidor). En tal escenario, el cambio de contexto se hace muy fácil, y los hilos pueden pasar fácilmente de activos a inactivos, o a espera. Esto mejora sustancialmente el rendimiento de los servlets sobre los scripts CGI.
Para afinar el rendimiento, con los servlets es posible "cachear" la información común (como las consultas a bases de datos) en la memoria, para evitar los costosos e innecesarios accesos a la base de datos. No existe ninguna forma sencilla de implementar esto en un CGI. Los Servlets también tienen un manejo muy potente de las excepciones.
Sin embargo, existen determinados casos en los que la creación de servlets no sería un requerimiento. Podría ser una buena inversión sólo si el sitio web recibe muchas visitas; para sitios web menos visitados, se pueden realizar las mismas tareas con scripts CGI.
Este artículo ha intentado explorar la tecnología de los servlets Java. Los avances en los servidores web, y en la tecnología de servidores de aplicaciones han simplificado la programación del lado del servidor. Componentes como los servlets de Java, las páginas JSP, CORBA y el XML, están haciendo de la arquitectura J2EE (Java 2 Enterprise Edition - Edición Empresarial de Java 2) un campo señalado de estudio.
Vandana Pursnani (pursnani@acm.org) tiene un M.S. en administración de ordenadores. Actualmente, trabaja para SiteGain Inc. en cual ejerce un nivel alto en la ingeniería de software, y está completando sus estudios en ciencias de la computación para el Instituto de Tecnología de New Jersey. Sus áreas de interés incluyen la visualización de la información de una red y de un sitio web, patrones de uso de sitios web, el efecto del uso de la información en aplicaciones de comercio electrónico, y tecnología J2EE.