Según la definición de Sun, Java Enterprise Edition (Java EE) es el estándar de la industria para desarrollar applicaciones Java portables, rebustas, escalables y seguras en el lado del servidor (server-side). Basado en Java SE, proporciona APIs para servicios web, modelo de componetes, gestión y comunicación.
Veremos en esta sesión una introducción al concepto de aplicaciones web y su estructura. Después veremos una introducción al manejo de servidores web (viendo como ejemplo el servidor web Tomcat), y pasaremos dar algunos detalles introductorios sobre algunas de las herramientas principales para el desarrollo de aplicaciones Java EE, como son los servlets y las páginas JSP, viendo cómo se integra todo en algunos ejemplos sencillos de aplicación que podremos probar.
Toda aplicación web (sea o no Java EE) se basa para su funcionamiento en un protocolo cliente-servidor: por un lado, el usuario abre un navegador (cliente), que le mostrará una serie de interfaces para la aplicación web a probar (formularios, enlaces, etc). Interactuando con estos formularios enviará una serie de órdenes a un servidor remoto, que las ejecutará, y mostrará al usuario las páginas con los resultados obtenidos (resultados de una búsqueda, alta en un sistema de registro, etc).
En todo este proceso intervienen varios factores: el cliente envía una serie de peticiones al servidor, y éste le emite, para cada una su correspondiente respuesta. En la petición del cliente puede haber una serie de cabeceras de petición, incluidas por el propio navegador, con información sobre la petición (tipo de navegador, idiomas aceptados, etc). Por otro lado, en la respuesta del servidor también pueden incluirse cabeceras de respuesta, con información sobre el contenido que se envía al navegador (tamaño del contenido, idioma, fecha de la última modificación, etc). Además, el servidor envía un código de estado, indicando si la petición previa del cliente se ha podido responder bien o ha habido errores (por ejemplo, un código 404 indicará que el servidor no ha podido encontrar la página solicitada por el cliente).
Todos estos elementos (cabeceras de petición, cuerpo de la petición, código de estado de la respuesta, cabeceras de respuesta y texto de la respuesta) se envían entre cliente y servidor utilizando el protocolo HTTP, que establece la forma en la que deben separarse estos elementos para enviarse, y la estructura que debe tener cada bloque.
La petición que realiza un cliente HTTP (por ejemplo, un navegador web) tiene la siguiente estructura:
Comando URI Protocolo Cabeceras de petición Datos adicionales
donde el Comando podrá ser cualquiera de los comandos soportados por el protocolo HTTP:
La URI será la URL del documento solicitado, y el protocolo indica la versión de HTTP que se va a emplear en la comunicación.
Las cabeceras dan información al servidor sobre el cliente (por ejemplo, tipo de navegador, tipo de datos que acepta: zips, htmls, xmls, etc).
Finalmente, los datos adicionales se utilizan por ciertos métodos (como POST) para enviar parámetros adicionales de la petición.
Un ejemplo completo de petición GET sería:
GET /dir/cargaPagina.php?id=21&nombre=Pepe HTTP/1.1 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible;MSIE5.0;Windows 98)
Esta misma petición, con un comando POST sería:
POST /dir/cargaPagina.php HTTP/1.1 Accept-Encoding: gzip, deflate User-Agent: Mozilla/4.0 (compatible;MSIE5.0;Windows 98) id=21&nombre=Pepe
La respuesta que envía el servidor al cliente, tras su petición, tiene una estructura como:
Protocolo Codigo Mensaje Cabeceras de respuesta Datos
Donde protocolo es el protocolo empleado por el servidor (normalmente el mismo indicado por el cliente).
El código es un código de respuesta, que indica si se ha podido servir bien el documento o ha habido errores. Por ejemplo, un código 200 indica que se ha servido bien. Un código 404 (muy común al navegar por internet) indica que no se ha encontrado el documento. Un código 500 indica un error en el servidor.
El mensaje va asociado al código, y explica brevemente el significado del mismo.
Las cabeceras de respuesta son similares a las de petición, pero dan en este caso al cliente (el navegador) información sobre la petición realizada y la respuesta servida (tamaño de la respuesta, idioma, etc).
En el caso de aplicaciones Java EE, en el lado del servidor, necesitamos uno que dé soporte a la arquitectura Java EE. Típicamente los servidores de aplicaciones Java EE son servidores potentes, que abarcan todo el potencial de funcionalidades que ofrece la plataforma Java EE. Sin embargo estos servidores son pesados (ocupan mucho espacio en disco y memoria), y requieren de máquinas relativamente potentes y dedicadas para su correcto funcionamiento.
En el caso de no necesitar toda la plataforma, sino su núcleo básico (esto es, manejo de servlets, páginas JSP, struts, JSF y alguna que otra característica), podemos "conformarnos" con un servidor web con soporte para Java EE. Estos servidores lógicamente no disponen de todas las funcionalidades de un gran servidor de aplicaciones, pero nos permiten cargar aplicaciones web más ligeras, consumiendo menos recursos y siendo más fácilmente mantenibles.
El servidor web estándar que se suele emplear para estos primeros pasos, o estas aplicaciones ligeras con Java EE es Tomcat. Es un servidor Java EE desarrollado por el proyecto Jakarta (los mismos desarrolladores que el servidor Apache), y proporciona diferentes funcionalidades para desarrollar aplicaciones Java EE basadas en servlets, páginas JSP, struts, y otras librerías que son un estándar en el desarrollo de aplicaciones Java EE.
La página donde encontrar las últimas versiones y documentación sobre su funcionamiento y configuración es:
Para poder instalar Tomcat (versión 5.5.x) tenemos que tener instalada previamente la versión 1.5.x de JDK. Una vez hecho esto, deberemos tener una variable de entorno JAVA_HOME que apunte al directorio donde se ha instalado JDK (algunas versiones de Tomcat ya la establecen automáticamente).
Una vez tengamos JDK instalado, ya podemos instalar Tomcat:
Tomcat necesita además otra variable de entorno, llamada CATALINA_HOME, que apunte al directorio donde está instalado Tomcat. Si no se autoestablece deberemos asignarla nosotros.
Una vez tenemos instalado Tomcat, la ejecución del mismo difiere según la distribución que nos hayamos descargado.
Para la versión ejecutable Windows, en el botón de Inicio, en Programas, tendremos creada una carpeta Apache Tomcat 5.5, y dentro de ella una opción Monitor Tomcat. Al ejecutarla, nos aparecerá un icono en la barra inferior, junto al reloj, mediante el que podremos parar y arrancar el servidor, con el botón derecho. También tenemos una opción en ese menú que es Configure Tomcat, que nos servirá para configurar alguna de las opciones de Tomcat que veremos más adelante.
Para la versión ZIP (Linux o Windows) dentro del subdirectorio bin donde hayamos instalado Tomcat tenemos, entre otros, dos ejecutables (ficheros .sh ):
Una vez tengamos el servidor arrancado podemos probarlo con la dirección raíz:
http://localhost:8080/
Que debería mostrar una página como:
La distribución de Tomcat está dividida en los siguientes directorios:
La configuración de Tomcat está almacenada en cuatro ficheros que se encuentran en el directorio conf. Tres de ellos están en formato XML y el cuarto es un fichero de políticas de seguridad en el formato estándar de Java:
Hemos visto que una aplicación web es una aplicación a la que accedemos mediante protocolo HTTP utilizando un navegador web.
Aplicaciones en el lado del servidor
En el lado del servidor, tenemos que conseguir que nuestro servidor HTTP sea capaz de ejecutar programas de aplicación que recojan los parámetros de peticiones del cliente, los procesen y devuelvan al servidor un documento que éste pasará a su vez al cliente.
Así, para el cliente el servidor no habrá hecho nada distinto a lo estipulado en el protocolo HTTP, pero el servidor podrá valerse de herramientas externas para procesar y servir la petición solicitada, pudiendo así no limitarse a servir páginas estáticas, sino utilizar otras aplicaciones (servlets, JSP, PHP, etc) para servir documentos con contenido dinámico.
Los programas de aplicación son típicamente programas que realizan consultas a bases de datos, procesan la información resultante y devuelven la salida al servidor, entre otras tareas.
Vamos a centrarnos en las aplicaciones web J2EE, en las que los componentes dinámicos que recibirán las peticiones HTTP en el servidor serán los servlets y JSPs. Estos componentes podrán analizar esta petición y utilizar otros componentes Java para realizar las acciones necesarias (beans, EJBs, etc).
Aplicaciones en el lado del cliente
Se tienen muchas tecnologías relacionadas con extensiones del lado del cliente (entendiendo cliente como un navegador que interpreta código HTML). El código HTML es un código estático que sólo permite formatear la apariencia de una página y definir enlaces a otras páginas o URLs. Esto no es suficiente si queremos que el navegador realice funciones más complicadas: validar entradas de formularios, mostrar la evolución del precio de unas acciones, etc.
Para ampliar las funcionalidades del navegador (respetando el protocolo HTTP), se utilizan tecnologías como JavaScript, Applets, Flash, etc. Estas se basan en hacer que el navegador ejecute código que le pasa el servidor, bien embebido en documentos HTML (como es el caso de JavaScript), o bien mediante ficheros compilados multiplataforma (como es el caso de los Applets Java o los ficheros Flash).
Una aplicación web J2EE que utilice servlets o páginas JSP debe tener una estructura de ficheros y directorios determinada:
Colgando del directorio inicial de la aplicación, se tiene un directorio WEB-INF, que contiene la información Web relevante para la aplicación. Esta información se divide en:
Notar que se separan los ficheros .class de los ficheros JAR, colocando los primeros en el directorio classes y los segundos en lib.
Esta estructura estará contenida dentro de algún directorio, que será el directorio correspondiente a la aplicación Web, y que podremos, si lo hacemos convenientemente, copiar en el servidor que nos convenga. Es decir, cualquier servidor Web J2EE soporta esta estructura en una aplicación Web, sólo tendremos que copiarla en el directorio adecuado de cada servidor.
Cada aplicación web J2EE es un contexto, una unidad que comprende un conjunto de recursos, clases Java y su configuración. Cuando hablemos de contexto, nos estaremos refiriendo a la aplicación web en conjunto. Por ello utilizaremos indistintamente los términos aplicación web y contexto.
Rutas relativas al contexto
Cada contexto (aplicación web) instalado en el servidor tendrá asociado una ruta para acceder a él desde la web. Por ejemplo, podemos asociar nuestro contexto la ruta /aplic, de forma que accediendo a la siguiente URL:
http://localhost:8080/aplic/index.htm
Estaremos leyendo el recurso /index.htm de nuestro contexto.
Ficheros WAR
Una forma de distribuir aplicaciones Web es empaquetar toda la aplicación (a partir de su directorio inicial) dentro de un fichero WAR (de forma parecida a como se hace con un TAR o un JAR), y distribuir dicho fichero. Podemos crear un fichero WAR de la misma forma que creamos un JAR, utilizando la herramienta JAR.
Estos ficheros WAR son un estándar de J2EE, por lo que podremos utilizarlos en los diferentes servidores de aplicaciones J2EE existentes.