Una aplicación web es una aplicación a la que accedemos mediante protocolo HTTP utilizando un navegador web. Hemos visto el protocolo HTTP, pero no cómo utilizarlo para implementar una aplicación.
Aplicaciones en el lado del servidorEn 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 clienteSe 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).
J2EE es una especificación que abarca un conjunto de tecnologías basadas en lenguaje Java que podremos utilizar para implementar aplicaciones web. Entre estas tecnologías destacamos:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ClaseServletHTML extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter(); out.println ("<!DOCTYPE HTML PUBLIC \""+ "-//W3C//DTD HTML 4.0 " + "Transitional//EN\">");
out.println ("<HTML>"); out.println ("<BODY>"); out.println ("<h1>Titulo</h1>"); out.println ("<p>Hola " + request.getParameter("nombre") + "</p>"); out.println ("</BODY>"); out.println ("</HTML>"); } }
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<BODY>
<h1>Titulo</h1>
<p>Hola <% out.print(request.getParameter("nombre")); %></p>
</BODY>
</HTML>
En este caso cuando el cliente solicite el JSP el servidor ejecutará el código Java que contiene y devolverá al cliente el documento generado.
Podemos hacer las mismas cosas con servlets y JSPs, pero cada una de estas dos tecnologías será más adecuada para una determinada tarea. Si bien los servlets son convenientes en los casos que haya que hacer mucho procesamiento de información (mucho código Java), los JSPs serán preferibles cuando predomina la parte de presentación. Ambas tecnologías pueden ser combinadas de forma que el servlet realice la parte de procesamiento de datos, y el JSP se encargue de presentar los resultados producidos.
Las aplicaciones J2EE se arquitecturan en las siguientes capas:
Figura 1. Capas de J2EE
Los servidores de aplicaciones J2EE son servidores que implementan la especificación de J2EE dando soporte a este tipo de aplicaciones. De esta forma, si realizamos una aplicación según el estándar de J2EE, podremos desplegarla en cualquier servidor de aplicaciones J2EE para de esta forma ponerla en funcionamiento.
El despliegue de una aplicación consiste en la asignación de elementos físicos a los componentes lógicos de nuestra aplicación, es decir, a la instalación de la aplicación en el directorio de aplicaciones del servidor de aplicaciones, de forma que este servidor empiece a servirla a los clientes que se conecten.
Podemos encontrar un gran número de servidores de aplicaciones J2EE, en los que podremos desplegar las aplicaciones que realicemos, siempre que cumplan el estándar J2EE. Entre ellos destacamos:
Vamos a centrarnos en el servidor de aplicaciones Tomcat, del que hemos de destacar que NO es un servidor de aplicaciones J2EE. Esto es así porque no cumple toda la especificación de J2EE, sólo una parte. Por esta razón se habla de Tomcat como contenedor de Servlets y JSPs, ya que soporta aplicaciones web con estos componentes, pero no soporta otros componentes como los EJBs. Las aplicaciones de Tomcat siguen el estándar de J2EE, pero no lo implementan al completo, por lo que nos centraremos en el estudio de las características que podemos utilizar en este servidor.
Una aplicación web J2EE que utilice servlets o páginas JSP debe tener una estructura de ficheros y directorios determinada:
WEB-INF
, que contiene la información Web relevante
para la aplicación. Esta información se divide en:
web.xml
)
que contiene información genérica sobre la aplicación. Lo veremos con
más detalle más adelanteclasses
: en él irán todas
las clases Java utilizadas en la aplicación (ficheros .class
),
es decir, clases externas a la API de Java que se utilicen en las páginas
JSP, servlets, etc. Las clases deberán mantener la estructura de paquetes,
es decir, si queremos colocar la clase paquete1.subpaquete1.MiClase
dentro de classes
, se quedará almacenada en el directorio
classes/paquete1/subpaquete1/MiClase
.lib
: aquí colocaremos las clases Java
que estén empaquetadas en ficheros JAR (es decir, colocaremos los ficheros
JAR de nuestra aplicación Web, y las librerías ajenas a la API de JDK
o de servlets y JSP que se necesiten)WEB-INF
servirá
sólo para la configuración interna de la aplicación en
el servidor, y nunca podremos acceder a este directorio directamente desde
la web. El resto de elementos de la aplicación (imágenes, etc), podemos estructurarlos
como nos convenga, creando la estructura de directorios que queramos a partir
del directorio raíz de nuestra aplicación. Todos estos directorios
si que serán accesibles desde la web.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.
Ejemplo: Aplicación web sencilla
Rutas relativas al contextoCada 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.
Supongamos que tenemos alguna imagen o recurso al que queremos acceder desde
otro, en nuestra aplicación Web. Por ejemplo, supongamos que colgando
del directorio raíz de la aplicación tenemos la imagen miImagen.jpg
dentro de la carpeta imagenes
(es decir, imagenes/miImagen.jpg
).
Podemos acceder a esta imagen de varias formas, aunque a veces podemos tener problemas con alguna, porque luego el contenedor Web tome la ruta relativa al lugar desde donde queremos cargar la imagen (o recurso, en general). Este problema lo podemos tener accediendo a elementos desde servlets, sobre todo.
Una solución para evitar esto es acceder a todos los elementos de la aplicación
a partir de la ruta del contexto. Por ejemplo, si nuestro contexto tiene la
ruta /aplic
asociada, para acceder a la imagen desde una página
HTML, pondríamos:
<img src="/aplic/imagenes/miImagen.jpg">
Como hemos dicho anteriormente, el directorio WEB-INF
de una aplicación
web con servlets y/o páginas JSP, debe haber un fichero descriptor de despliegue
(llamado web.xml
) que contenga la información relativa a
la aplicación.
Es un fichero XML, que comienza con una cabecera XML que indica la versión
y la codificación de caracteres, y un DOCTYPE
que indica el tipo
de documento, y la especificación de servlets que se sigue. La etiqueta raíz
del documento XML es web-app
. Así, un ejemplo de fichero
podría ser:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Mi Aplicacion Web</display-name>
<description> Esta es una aplicacion web sencilla a modo de ejemplo
</description>
</web-app>
En este caso se utiliza la especificación 2.3 de servlets o anteriores (para
utilizar versiones posteriores habría que cambiar la especificación en la línea
de DOCTYPE
). Algunos servidores permiten omitir la cabecera xml
y el DOCTYPE
, pero sí es una buena costumbre el ponerlas.
Dentro de la etiqueta raíz <web-app>
podemos colocar otros
elementos que ayuden a establecer la configuración de nuestra aplicación web.
Dichos elementos deben seguir un orden: podemos omitir los que no se necesiten,
pero los que pongamos deben tener una colocación adecuada en el documento. Veremos
a continuación algunos de ellos, en el orden en que deben aparecer si aparecen
(existen otras etiquetas que no veremos aquí, y que debéis consultar el orden
en que ponerlas). En algunos elementos profundizaremos un poco más, por tratarse
de elementos genéricos de una aplicación web (variables globales, etc). En otros
(servlets, filtros, etc), simplemente se indicará qué elementos se tratan, pero
su configuración se explicará en temas más específicos.
1.5.2.1.1. Información general de la aplicación
Primero tenemos etiquetas con información general:
<display-name>
: nombre con que deben utilizar las aplicaciones gráficas para referenciar a la aplicación<description>
: texto descriptivo de la aplicación1.5.2.1.1.1. Variables globales
Podemos tener varias etiquetas:
<context-param>
: para declarar las variables globales a toda la aplicación web, y sus valores. Dentro tiene dos subetiquetas:
<param-name>
: nombre de la variable o parámetro<param-value>
: valor de la variable o parámetroUn ejemplo:
<context-param> <param-name>param1</param-name> <param-value>valor1</param-value> </context-param>Estos parámetros pueden leerse desde servlets con el método
getInitParameter
del objetoServletContext
.1.5.2.1.2. Filtros
Para el tratamiento de filtros se tienen las etiquetas:
<filter>
: para asociar un nombre identificativo con la clase que implementa el filtro<filter-mapping>
: para asociar un nombre identificativo de filtro con una URL o patrón de URLSe pueden tener varias de estas etiquetas, cada una para un filtro.
1.5.2.1.3. Oyentes
Se tiene la etiqueta:
<listener>
: para definir una clase oyente que responde ante eventos en sesiones y contextos (al iniciar, al cerrar, al modificar).
1.5.2.1.4 Servlets
Para definir los servlets en nuestro fichero de configuración, se tienen las etiquetas:
<servlet>
: asocia un nombre identificativo con una clase Java que implementa un servlet<servlet-mapping>
: asocia un nombre identificativo de servlet con una URL o patrón de URL.Se pueden tener varias de estas etiquetas, cada una para un servlet.
1.5.2.1.5 Configuración de sesión
Se tiene la etiqueta:
<session-config>
: para indicar parámetros de configuración de las sesiones.Por ejemplo, podemos indicar el tiempo (en minutos) que le damos a una sesión de usuario antes de que el servidor la finalice:
<session-config> <session-timeout>30</session-timeout> </session-config>1.5.2.1.6 Páginas de inicio
Se tiene la etiqueta:
<welcome-file-list>
: para indicar qué páginas debe buscar Tomcat como páginas de inicio en el caso de que en la URL se indique el directorio, pero no la página, como por ejemplo:http://localhost:8080/unadireccion/dir/Para ello, esta etiqueta tiene una o varias subetiquetas
<welcome-file>
para indicar cada una de las posibles páginasPor ejemplo, podemos indicar que las páginas por defecto sean
index.html
oindex.jsp
con:<welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list>Las páginas se buscan en el orden en que se especifican en esta etiqueta.
1.5.2.1.7 Librerías de tags
Se tiene la etiqueta:
taglib
: para cargar una librería de tags para utilizar en páginas JSP. Podemos tener una o varias de estas etiquetas.1.5.2.1.8 Seguridad
Para gestionar la seguridad en las aplicaciones Web se tienen las etiquetas:
security-constraint
: permite especificar qué URLs de la aplicación deben protegerselogin-config
: indica cómo debe autorizar el servidor a los usuarios que quieran acceder a las URLs protegidas (indicadas consecurity-constraint
)security-role
: da una lista de roles en los que se encuadrarán los usuarios que intenten acceder a recursos protegidos.Existen otras etiquetas internas, relacionadas con la seguridad, que no se encuentran detalladas aquí.
Una forma alternativa 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.
Por ejemplo, si tenemos en el directorio C:/web/ejemplo
los siguientes
ficheros:
C:/web/ejemplo/ index.html WEB-INF/ web.xml classes/ ClaseServlet.class
Para crear el WAR nos colocamos en dicho directorio C:/web/ejemplo
y escribimos:
jar cMvf ejemplo.war *
Las opciones c
, v
y f
son para crear
el WAR como un JAR comprimido normal. La opción M
(mayúscula) es
para que no se añada el fichero MANIFEST
.
También es IMPORTANTE destacar que no debe haber subdirectorios desde la raíz de la aplicación, es decir, la estructura del fichero WAR debe ser:
index.html WEB-INF/ web.xml classes/ ClaseServlet.class
sin ningún subdirectorio previo (ni ejemplo/
ni web/ejemplo/
ni nada por el estilo).
Una vez hemos construido la aplicación deberemos desplegarla en el servidor de aplicaciones para que dicha aplicación esté disponible al acceder al servidor desde la web. Este proceso es conocido como despliegue o deployment. Cada servidor de aplicaciones tiene sus propios métodos para desplegar las aplicaciones. Por ejemplo, casi siempre tenemos disponible una interfaz web a través de la cual podemos subir y desplegar una aplicación en el servidor.
Vamos a ver las posibles formas en las que el servidor web Tomcat nos permite desplegar las aplicaciones, pero antes veremos dónde se almacenan las aplicaciones desplegadas en Tomcat.
Tomcat tiene un directorio webapps
(${tomcat.home}/webapps
)
donde están todas las aplicaciones web instaladas en el servidor. Cada
aplicación web está contenida dentro de un subdirectorio de webapps
,
y este subdirectorio contendrá toda la estructura de directorios y ficheros
correspondiente a la aplicación web. Por ejemplo, podremos tener:
${tomcat.home}/webapps/aplic/
${tomcat.home}/webapps/aplic/index.htm
${tomcat.home}/webapps/aplic/WEB-INF/
${tomcat.home}/webapps/aplic/WEB-INF/web.xml
${tomcat.home}/webapps/aplic/WEB-INF/classes/
${tomcat.home}/webapps/aplic/WEB-INF/lib/
De esta forma tendremos un contexto (aplicación web) aplic
instalado en Tomcat. Por defecto Tomcat asigna como ruta de cada contexto el
mismo nombre del directorio del mismo, por lo que para acceder a esta aplicación
aplic
anterior deberemos introducir la siguiente URL:
http://localhost:8080/aplic/index.htm
Considerando que tenemos Tomcat instalado en nuestra máquina local y
atendiendo en el puerto 8080
(es el puerto por defecto de Tomcat).
También podremos configurar Tomcat para asignar a cada contexto la ruta
que queramos. Al instalar Tomcat encontramos una aplicación instalada
por defecto en un directorio ROOT
(${tomcat.home}/webapps/ROOT
).
Esta aplicación tiene asignada la ruta /
, por lo que cuando
accedamos a la URL:
http://localhost:8080/
Será esta la aplicación a la que se estará accediendo, que nos muestra la página de bienvenida de Tomcat y enlaces a documentación y a la aplicación de gestión del servidor.
Si copiamos recursos a este directorio ROOT
, podremos acceder
a ellos a partir de esta URL raíz del servidor. Por ejemplo, si copiamos
la siguiente página HTML:
${tomcat.home}/webapps/ROOT/pagina.htm
Podremos acceder a ella utilizando la siguiente URL:
http://localhost:8080/pagina.htm
También podremos configurar Tomcat para que sea cualquier otra de las aplicaciones instaladas la que tenga asignada esta ruta raíz, simplemente cambiando la ruta asignada a cada contexto.
Una vez hemos visto como se almacenan las aplicaciones desplegadas en Tomcat,
vamos a ver como desplegarlas. Una forma sencilla de hacerlo es simplemente
crear el directorio de la aplicación en webapps
y copiar
ahí todo su contenido. Esto a veces nos fuerza a reiniciar el servidor
para que la nueva aplicación sea reconocida correctamente por Tomcat.
Por esta razón, existen otras formas de despliegue de forma dinámica,
sin necesidad de reiniciar Tomcat, a través de una aplicación
instalada en Tomcat llamada manager. Tendremos disponible una interfaz
HTML del manager, con la que podremos desplegar aplicaciones desde
un navegador.
Esta forma de despliegue es la más sencilla. Simplemente copiamos el
contenido de nuestra aplicación, que habremos generado en el directorio
build
de nuestro directorio de desarrollo, al directorio webapps
de Tomcat.
También podremos copiar directamente el fichero WAR con la aplicación
al directorio webapps
de Tomcat. En este caso, cuando reiniciemos
Tomcat, éste desempaquetará el fichero WAR creando la estructura
de directorios de la aplicación bajo webapps
. Esto es el
comportamiento por defecto, pero podremos configurar Tomcat para que no desempaquete
los WAR, sino que acceda a la aplicación usando directamente el fichero
WAR.
Este método tiene el inconveniente de que deberemos reiniciar el servidor para que Tomcat reconozca las nuevas aplicaciones que hayamos instalado. En las última versiones de Tomcat se suelen reconocer correctamente las aplicaciones que se instalan en tiempo de ejecución, sin necesidad de reiniciar el servidor, pero en algunos casos será necesario reiniciarlo para asegurarnos de que ha actualizado correctamente la información sobre las aplicaciones instaladas.
Para evitar tener que reiniciar el servidor, tenemos una aplicación
instalada en Tomcat llamada manager
, que nos permitirá desplegar
y gestionar las aplicaciones web instaladas en el servidor en tiempo de ejecución.
Con el manager podremos subir y desplegar una aplicación, ver
la lista de aplicaciones desplegadas, y detener, recargar, reanudar o desinstalar
estas aplicaciones.
El manager de Tomcat cuenta con una interfaz HTML desde la cual podremos desplegar aplicaciones y gestionar las aplicaciones instaladas. Para acceder a esta interfaz HTML del manager introduciremos la siguiente URL en cualquier navegador:
http://localhost:8080/manager/html
Para poder acceder al manager necesitaremos contar con un usuario con rol manager
registrado en Tomcat. Si no tenemos ningún usuario con estos permisos
deberemos crear uno. Para ello editaremos el fichero ${tomcat.home}/conf/tomcat-users.xml
e introduciremos las siguientes líneas:
<role rolename="manager"/> <user username="admin" password="j2ee" roles="manager"/>
Con esto ya podremos acceder al manager con nuestro usuario. En este caso el
usuario tendrá el nombre admin
y el password j2ee
.
Una vez accedamos al manager veremos una página como la que se muestra a continuación:
Aquí podemos ver las aplicaciones instaladas en el servidor y podemos
gestionarlas. Podemos detener (Stop) las aplicaciones para que dejen
de estar disponibles, pero sin borrarlas del servidor, y posteriormente reanudar
su ejecución con Start. También podemos recargar las
aplicaciones con Reload. Esto será útil cuando hayamos
modificado la aplicación y queramos que Tomcat reconozca estos cambios,
por ejemplo si hemos cambiado la configuración de la aplicación
(web.xml
) o hemos añadido o modificado clases Java. Por
último, con Remove podremos desinstalar la aplicación
del servidor. Al hacer esto se eliminarán todos los ficheros de la aplicación
y ya no podrá reanudarse.
En la parte inferior de esta página encontramos los siguientes formularios:
Desde aquí podremos desplegar aplicaciones web en el servidor. Con el formulario superior podremos desplegar una aplicación que ya se encuentre en un directorio de la máquina en la que está el servidor.
Con el formulario inferior será muy sencillo desplegar una aplicación web. Simplemente necesitamos tener el fichero WAR de la aplicación en nuestra máquina. Pulsamos sobre Examinar... para buscar y seleccionar este fichero WAR, y una vez seleccionado pulsaremos sobre Install para que suba y despliegue la aplicación al servidor web.
Hemos visto la estructura y componentes que debe tener una aplicación web, y como desplegarla en el servidor Tomcat para ponerla en marcha. Cuando tenemos una aplicación web sencilla podemos construir la estructura y los elementos de la aplicación manualmente. Sin embargo, conforme vaya haciéndose más compleja la aplicación será conveniente realizar un proceso de desarrollo más organizado. Vamos a ver a continuación como organizar nuestro directorio de desarrollo de forma que se nos facilite el proceso de construcción de nuestra aplicación.
Cuando iniciamos Tomcat, automáticamente carga en el CLASSPATH
del servidor lo necesario para trabajar con servlets y páginas JSP, y también
carga las clases que haya en los directorios WEB-INF/classes
y
WEB-INF/lib
de las aplicaciones, para que sepan dónde encontrarlas.
Sin embargo, para poder construir una aplicación (implementar y compilar los servlets y otras clases que la componen), necesitaremos también tener estos datos configurados, pues de lo contrario no conseguiremos compilar. Veremos ahora qué pasos hay que seguir para esto.
Primero debemos crear un directorio de trabajo donde colocar nuestras aplicaciones Web. Es recomendable que dicho directorio quede fuera del directorio de instalación del servidor.
Para que la aplicación esté disponible tendremos que instalarla dentro del servidor de aplicaciones, por lo que tendremos que copiar la aplicación de nuestro directorio de desarrollo al directorio del servidor web, es decir, una vez construida la aplicación tendremos que desplegarla para poder utilizarla.
A la hora de construir la aplicación podemos distinguir los recursos que la componen en dos tipos, según si necesitan ser compilados por nosotros de forma previa al despliegue o no:
.class
)
en el directorio WEB-INF/classes
de la misma.web.xml
) y librerías
JAR incluidas en WEB-INF/lib
. Además, en este grupo también
se incluye el contenido dinámico en forma de páginas JSP. Estas
páginas no deberán ser compiladas por nosotros, sino que serán
compiladas automáticamente por el servidor de aplicaciones la primera
vez que se ejecute la aplicación, pero eso será transparente
para nosotros por lo que no deberemos preocuparnos por ello.A continuación vamos a proponer una posible estructura de nuestro directorio de trabajo que nos facilite el desarrollo de aplicaciones web.
Durante el desarrollo crearemos los distintos componentes de nuestra aplicación en los siguientes directorios:
src |
Código fuente (servlets y otras clases) que necesita ser compilado |
web |
Elementos que no necesitan ser compilados (recursos estáticos,
JSPs, WEB-INF/web.xml , librerías). En este directorio
tendremos la estructura completa de nuestra aplicación, a excepción
del contenido del directorio WEB-INF/classes . |
De esta forma separamos las clases Java de nuestra aplicación, que deben ser compiladas antes de desplegar la aplicación, del resto de elementos de la aplicación.
Una vez desarrollados todos los componentes de la aplicación, la construiremos en los siguientes directorios:
bin |
Clases de la aplicación compiladas. Se utiliza como directorio
temporal donde compilamos el código fuente de src . Estas
clases compiladas deberán ser incorporadas posteriormente al directorio
WEB-INF/classes de nuestra aplicación web. |
build |
Aplicación completa tal como se instalará en el servidor.
Tendrá la estructura del directorio web y además
las clases compiladas de bin . |
dist |
Aplicación empaquetada (fichero WAR). Contenido del directorio
build empaquetado en un fichero WAR. |
Para poder compilar las clases Java con nuestros servlets tenemos que añadir
al CLASSPATH
el lugar donde se encuentran las APIs de servlets
y JSP. Cada servidor proporciona mediante unos ficheros JAR estas librerías,
que deberemos añadir. En el caso de Tomcat, tenemos los ficheros servlet.jar
(para servlets), jsp.jar
, jspengine.jar
y jasper.jar
(para JSP). Todos estos ficheros se encuentran
localizados en el directorio common/lib
. Normalmente sólo
necesitamos añadir el fichero servlet.jar
, puesto que las páginas
JSP las compila automáticamente el servidor si no lo están, y él ya encuentra
solo los JAR.
También deberemos añadir los directorios y ficheros JAR de otras clases que
necesitemos y no formen parte de la API de Java (incluyendo librerías del directorio
WEB-INF/classes
o WEB-INF/lib
de la aplicación).
Deberemos escribir todo el código fuente de las clases Java de nuestra
aplicación en el subdirectorio src
del directorio de desarrollo,
y generar el resto de recursos en el subdirectorio web
(siempre
será necesario tener al menos el descriptor de despliegue /WEB-INF/web.xml
para que la aplicación funcione).
Una vez hemos desarrollado los componentes de nuestra aplicación, deberemos construir la aplicación. Para ello deberemos realizar los siguientes pasos:
1. Compilar las clases de la aplicación. Generaremos las clases compiladas (ficheros
.class
) en el subdirectoriobin
de nuestro directorio de desarrollo.2. Juntar todos los elementos de la aplicación. En el subdirectorio
build
generaremos la aplicación web completa, juntando la estructura creada en el directorioweb
a las clases compiladas debin
. Para ello copiaremos a este directoriobuild
todo el contenido deweb
, y el contenido debin
lo copiaremos abuild/WEB-INF/classes
.3. De forma opcional podemos empaquetar la aplicación en un fichero WAR. Para ello empaquetaremos todo el contenido del directorio
build
, donde tenemos nuestra aplicación web completa, en un fichero WAR que guardaremos en el subdirectoriodist
de nuestro directorio de trabajo.
Con esto tendremos la aplicación lista para ser desplegada en nuestro servidor de aplicaciones, tal como vimos en el punto anterior.
Eclipse es una herramienta que permite integrar diferentes tipos de aplicaciones. La aplicación principal es el JDT (Java Development Tooling), un IDE para crear programas en Java. Otras aplicaciones, que no vienen con la distribución estándar de Eclipse, se añaden al mismo en forma de plugins, y son reconocidos automáticamente por la plataforma.
Además, Eclipse tiene su propio mecanismo de gestión de recursos. Los recursos son ficheros en el disco duro, que se encuentran alojados en un espacio de trabajo (workspace), un directorio especial en el sistema. Así, si una aplicación de Eclipse modifica un recurso, dicho cambio es notificado al resto de aplicaciones de Eclipse, para que lo tengan en cuenta.
Para instalar Eclipse se requiere:
Para la instalación, se siguen los pasos:
eclipse vm ruta_jdk_jre
Para arrancar Eclipse se tiene el ejecutable eclipse.exe o eclipse.sh en ECLIPSE_HOME. La pantalla inicial de Eclipse aparecerá tras unos segundos:
Figura 1. Pantalla inicial de Eclipse
Veremos las opciones principales con detalle más adelante. De los menús, entre otros, pueden resultar interesantes:
Podemos cambiar la configuración visual del entorno Eclipse según el tipo de aplicaciones que vayamos a desarrollar. Como vamos a trabajar con aplicaciones en Java cambiaremos a la perspectiva Java. Para ello seleccionaremos la opción del menú Window > Open Perspective > Java tal como se muestra a continuación:
Lo primero que debemos hacer para empezar a desarrollar una nueva aplicación es crear un proyecto Java en Eclipse. Para ello seleccionamos la opción del menú File > New > Project ...
Dentro de la ventana de nuevo proyecto, seleccionamos Java Project y pulsamos Next.
En la siguiente pantalla deberemos dar un nombre al proyecto para identificarlo dentro de Eclipse. Este nombre es interno de Eclipse, y no tiene porque corresponderse con el nombre de nuestra aplicación web en Tomcat. Por defecto creará el directorio para este proyecto dentro del espacio de trabajo de Eclipse. Si queremos crearlo en otro directorio desmarcaremos la casilla Use default.
Cuando hayamos introducido esta información pulsamos sobre Next.
En la siguiente pantalla configuraremos la estructura de nuestro directorio de desarrollo y las librerías externas utilizadas.
Lo primero que vamos a hacer es configurar el directorio de fuentes, para que
los guarde en src
. Pulsaremos sobre Add folder... para
añadir este directorio.
Aparecerá la siguiente ventana. Como todavía no existe el directorio
src
, deberemos crearlo pulsando sobre Create New Folder...
En la siguiente ventana introduciremos el nombre del directorio a crear (src
),
y pulsamos sobre OK para que lo cree.
De esta forma volverá a la pantalla anterior donde tendremos ya el directorio
src
creado. Seleccionamos este directorio y pulsamos sobre OK
para añadirlo como directorio de fuentes.
Nos preguntará si queremos eliminar el directorio raíz del proyecto
como directorio de fuentes y utilizar sólo src
para tal
fin, y generar las clases compiladas en el directorio bin
. Pulsaremos
sobre Yes.
De esta forma veremos en la pantalla de configuración del proyecto el
directorio src
como único directorio de fuentes de la aplicación,
y bin
como directorio de salida. Ahora vamos a cambiar a la pestaña
Libraries para configurar las librerías externas que vamos a
necesitar tener en el classpath para nuestro proyecto.
En esta pestaña añadiremos librerías JAR al classpath pulsando sobre Add External JARs ...
Deberemos seleccionar los ficheros JAR que queremos añadir al classpath.
Los ficheros de Tomcat que necesitaremos añadir para compilar nuestras
aplicaciones se encuentran en el directorio ${tomcat.home}/common/lib
.
Podemos añadir todos los ficheros JAR de este directorio al classpath,
pero para las aplicaciones que vamos a desarrollar bastará con incluir
el fichero servlet.jar
únicamente.
Una vez tengamos esta librería incluida se mostrará en la lista como se puede ver a continuación. Ahora ya podemos pulsar sobre Finish para que se cree el proyecto con los datos que hemos introducido.
Una vez creado el proyecto, podremos crear directorios y ficheros dentro de
nuestro directorio de desarrollo. De esta forma, podremos crear la estructura
de nuestra aplicación web y los recursos que no necesitan ser compilados
dentro del directorio web
.
Pulsando con el botón derecho sobre nuestro proyecto en el explorador de paquetes se abrirá un menú contextual con el que podremos crear un nuevo directorio. Para ello pulsaremos sobre la opción New > Folder.
Aparecerá la siguiente pantalla donde deberemos introducir el nombre
del directorio que vamos a crear. Por ejemplo podemos crear de esta forma el
directorio web
donde introduciremos toda la estructura y recursos
de nuestra aplicación web, a excepción de los recursos que necesitan
ser compilados (clases Java).
A su vez, podremos crear subdirectorios dentro de web
para de
esta forma crear el directorio WEB-INF
, y dentro de éste
los directorios classes
y lib
. De la misma forma podremos
crear cualquier otro directorio que queramos tener en nuestra aplicación
web.
Una vez tengamos la estructura de directorios necesaria, podemos crear ficheros
genéricos de texto. De esta forma podremos crear el descriptor de despliegue
(web.xml
) y cualquier fichero JSP o HTML que queramos añadir
a la aplicación. Para crear un fichero genérico de texto pulsaremos
sobre la opción New > File del menú contextual como
se muestra a continuación:
En la siguiente ventana introduciremos el nombre del fichero a crear. Por ejemplo,
para crear el descriptor de despliegue utilizaremos el nombre web.xml
,
lo crearemos dentro del directorio WEB-INF
.
Una vez creado el fichero, podremos abrirlo en el editor de texto de Eclipse para escribir su contenido. Introduciremos en este editor el contenido del descriptor de despliegue y grabaremos el fichero pulsando sobre el icono Guardar.
De la misma forma podemos crear cualquier otro fichero de texto para nuestra aplicación que no necesite ser compilado, como páginas HTML y JSP.
Además de los recursos estáticos de la aplicación y páginas JSP, que no necesitan ser compilados, una aplicación web también puede tener clases Java (Servlets y otras clases auxiliares). Para crear una nueva clase en nuestra aplicación pulsaremos sobre New > Class.
Se mostrará la siguiente pantalla donde introduciremos los datos de
la nueva clase a crear. Deberemos introducir el paquete y el nombre de la clase.
Además, en el caso de que se trate de un Servlet, deberemos poner como
superclase la clase HttpServlet
. Para seleccionar está superclase
podemos pulsar sobre el botón Browse ... junto al campo Superclass.
Se mostrará la siguiente ventana para explorar las clases. Introduciendo
en el campo de texto superior una parte del nombre de la clase que buscamos,
por ejemplo 'HttpServlet', nos mostrará la lista de todas las
clases que coincidan con ese nombre. Seleccionaremos de la lista la clase que
buscamos (HttpServlet
) y pulsamos OK.
Entonces aparecerá el nombre completo de la clase seleccionada en el campo Superclass de la ventana anterior. Ya podremos pulsar sobre Finish para crear la clase.
Eclipse creará automáticamente el esqueleto de esta clase y podremos modificarlo en el editor. Este editor nos ofrecerá facilidades como autocompletar los nombres de los métodos, y revisar la sintaxis del código conforme lo escribimos.
En el caso de que estemos implementando un Servlet, deberemos sobrescribir
el método doGet
de esta clase. Para sobrescribir métodos
de clases de las que heredamos abriremos el menú contextual sobre el
área de edición de código, y seleccionamos la opción
Source > Override/Implement Methods ...
Entonces podremos seleccionar el método doGet
que es el
que nos interesa en este caso y pulsar OK.
Esto nos creará el esqueleto de este método, dentro del cual tendremos que añadir el código necesario. Podemos copiar el código que hemos visto para el servlet de ejemplo anterior.
Nos mostrará subrayados con rojo los errores en el código. Posiblemente
haya errores del tipo "PrintWriter cannot be resolved" debidos
a no haber importado el paquete necesario donde se encuentra esta clase. Para
solucionarlos podemos abrir un menú contextual pulsando con el botón
derecho sobre el elemento que da este error, y seleccionar la opción
Source > Add Import. De esta forma Eclipse añadirá
automáticamente el import
para este elemento a nuestra clase,
sin tener nosotros que buscar el paquete en el que se encontraba.
Otra opción interesante de este menú contextual del editor de código es la opción Source > Format, que dará formato automáticamente al código añadiendo las sangrías necesarias para cada línea de código, permitiéndonos de esta forma "limpiar" el código de forma rápida.
Ant es una herramienta basada en Java, similar a la herramienta make, pero más adecuada para el desarrollo de aplicaciones Java. Make tiene el inconveniente de ser dependiente del shell que utilicemos, ya que ejecuta comandos de éste, lo cual complicaría la portabilidad de nuestras aplicaciones a distintas plataformas. Uno de los objetivos que se han buscado desde el principio con las tecnologías Java es la independencia de la plataforma, por lo que será conveniente contar con un sistema de construcción de aplicaciones que cumpla este objetivo para que la portabilidad no se vea dañada.
Ant utiliza ficheros de configuración basados en XML, donde definiremos las tareas a realizar. Para realizar estas tareas se utilizarán clases Java, en lugar de comandos del shell, lo cual lo hará independiente de la plataforma. Podremos realizar un gran número de diferentes tareas con esta herramienta, de las que veremos las principales, y además es extensible, permitiéndonos añadir nuestras propias tareas que podremos implementar utilizando clases Java.
El fichero de configuración, llamado build.xml
, es bastante
más complejo que un Makefile
, pero podremos parametrizarlo,
permitiéndonos reutilizar una misma plantilla genérica para distintas
aplicaciones. Además, este fichero build.xml
al utilizar
una gramática de más alto nivel no tendrá el inconveniente
de los tabuladores que encontramos en los Makefile
(si en lugar
de tabuladores usamos espacios no funcionan correctamente).
La herramienta ant se encuentra integrada dentro del entorno Eclipse, de forma que podremos utilizar ficheros de ant para automatizar las tareas de compilación y despliegue de nuestras aplicaciones web desde dentro del mismo entorno.
NOTA: En algunas ocasiones la versión de ant dentro de Eclipse puede
fallar si no tiene configurado el fichero ${java.home}/lib/tools.jar
en su classpath. Conviene asegurarnos yendo a Window > Preferences
e y a la sección Ant > Runtime. Deberemos tener este fichero
incluido en el classpath de ant tal como se muestra a continuación:
Vamos a ver paso a paso como utilizar ant desde Eclipse.
1. Creamos un fichero build.xml
en el directorio raíz de
nuestro proyecto y escribimos su contenido. Veremos el fichero recién
creado en el explorador de paquetes como un fichero de tipo ant.
Como contenido de este fichero podemos utilizar la siguiente plantilla que nos servirá para aplicaciones con la estructura de directorios que hemos definido en puntos anteriores.
<project name="Prueba" default="prepare" basedir=".">
<!-- Propiedades -->
<property name="catalina.home"
value="c:\\Archivos de programa\\Apache Group\\Tomcat 4.1"/>
<property name="app.name" value="aplic"/>
<property name="app.home" value="${catalina.home}/webapps/${app.name}"/>
<property name="war.name" value="${app.name}.war"/>
<property name="bin.home" value="${basedir}/bin"/>
<property name="build.home" value="${basedir}/build"/>
<property name="dist.home" value="${basedir}/dist"/>
<property name="src.home" value="${basedir}/src"/>
<property name="web.home" value="${basedir}/web"/>
<property name="compile.debug" value="true"/>
<property name="compile.deprecation" value="false"/>
<property name="compile.optimize" value="true"/>
<!-- Classpath -->
<path id="compile.classpath">
<pathelement location="${catalina.home}/common/classes"/>
<fileset dir="${catalina.home}/common/endorsed">
<include name="*.jar"/>
</fileset>
<fileset dir="${catalina.home}/common/lib">
<include name="*.jar"/>
</fileset>
<pathelement location="${catalina.home}/shared/classes"/>
<fileset dir="${catalina.home}/shared/lib">
<include name="*.jar"/>
</fileset>
<fileset dir="${web.home}/WEB-INF/lib">
<include name="*.jar"/>
</fileset>
</path>
<!-- Objetivos -->
<target name="all" depends="clean,dist"
description="Compila todo"/>
<target name="clean"
description="Borra directorios build y dist">
<delete dir="${build.home}"/>
<delete dir="${dist.home}"/>
</target>
<target name="compile" description="Compila los fuentes Java">
<javac srcdir="${src.home}"
destdir="${bin.home}" debug="${compile.debug}" deprecation="${compile.deprecation}" optimize="${compile.optimize}">
<classpath refid="compile.classpath"/>
</javac>
</target>
<target name="prepare" depends="compile">
<mkdir dir="${build.home}"/>
<mkdir dir="${build.home}/WEB-INF"/>
<mkdir dir="${build.home}/WEB-INF/classes"/>
<mkdir dir="${build.home}/WEB-INF/lib"/>
<copy todir="${build.home}">
<fileset dir="${web.home}"/>
</copy>
<copy todir="${build.home}/WEB-INF/classes">
<fileset dir="${bin.home}"/>
</copy>
</target>
<target name="dist" depends="prepare"
description="Crea el fichero WAR de la aplicacion">
<mkdir dir="${dist.home}"/>
<jar jarfile="${dist.home}/${war.name}"
basedir="${build.home}"/>
</target>
<target name="deploy" depends="prepare" description="Despliega copiando al webapps">
<mkdir dir="${app.home}"/>
<copy todir="${app.home}">
<fileset dir="${build.home}"/>
</copy>
</target>
</project>
Al comienzo de este fichero se muestran en negrita las propiedades que deberemos editar para adaptar esta plantilla a nuestra aplicaciones. Deberemos cambiar el nombre de la aplicación, y el directorio donde tenemos instalado Tomcat.
2. Para utilizar este fichero de ant desde Eclipse deberemos mostrar la vista de ant. Para ello iremos a Window > Show View > Ant como se muestra a continuación:
3. Veremos la ventana de ant a la derecha de la ventana de Eclipse. Ahora deberemos añadir nuestro fichero de ant a esta ventana pulsando sobre el botón señalado en la siguiente imagen:
Seleccionamos el fichero build.xml
que hemos creado en el directorio
raíz de nuestro proyecto. Si en la siguiente ventana no vemos este fichero,
se puede deber a tener seleccionado otro proyecto, o a haber creado el fichero
en otro directorio.
4. Una vez hecho esto, si el fichero es correcto deberemos ver en la ventana de ant los objetivos definidos en él.
Haciendo doble click sobre cualquiera de los objetivos lo ejecutaremos, realizándose de esta forma las tareas correspondientes. Los objetivos definidos en la plantilla de ejemplo son:
clean
: Elimina las clases compiladas para volver
a compilar el sistema desde cero la próxima vez.
compile
: Compila las clases de nuestra aplicación,
cuyos fuentes están ubicados en el directorio src
, produciendo
las clases compiladas en el directorio bin
.
prepare
: Construye en el directorio build
la aplicación completa, juntando el contenido que no necesita ser compilado
de web
con las clases compiladas de bin
. Una vez hecho
esto en build
tendremos la aplicación lista para ser desplegada.
dist
: Genera un fichero WAR con nuestra aplicación
en el directorio dist
. Podremos utilizar este fichero para desplegar
la aplicación en nuestro servidor.
all
: Elimina las clases compiladas anteriormente
y vuelve a construir el sistema entero, realizando todas las tareas anteriores.
deploy
: Despliega la aplicación automáticamente
copiando el contenido del directorio build
al directorio webapps
de Tomcat. Posiblemente Tomcat deba ser reiniciado para que reconozca las aplicaciones
desplegadas de esta forma.
De esta forma podemos automatizar todo el proceso de construcción y despliegue de aplicaciones web que vimos anteriormente, de forma que simplemente pulsando sobre un objetivo realice todas las acciones necesarias de forma automática.