Tutoriales Crear tu Primera Aplicación Web Real con Tomcat 4 y MySQL Autor: Traductor: Juan Antonio Palos (Ozito) OnJava (OnJava) Puedes encontrar la versión original de este tutorial en Inglés en: http://www.onjava.com/ ¿Qué Tecnologías Utilizar? Configurar la Base de Datos o Crear la Tabla Libros en la Base de Datos Las Clases Java de la Aplicación o libreria.ContextListener Propósito de la clase ContextListener Métodos de la clase ContextListener Código Fuente Completo de la clase ContextListener o libreria.LibrosBD Propósito de la clase LibrosBD Métodos de la Clase LibrosBD Código Fuente Completo de la clase LibrosBD o libreria.Libro Propósito de la clase Libros Métodos de la clase Libros Código Fuente Completo de la clase Libro Las Páginas JSP o La página Index.jsp Propósito de la Página Index.jsp Aspecto de la Página Mostrar la Tabla Bucle por Todas las Filas de la Tabla Mostrar un Libro en un Fila de la Tabla Código Completo de la Página Index.jsp Insertar un Registro en la Base de Datos o Form_Insertar.jsp Propósito de la Página Form_Insertar.jsp Aspecto de la Página Form_Insertar.jsp Dibujar el Formulario Código Completo de la Página Form_Insertar.jsp o Insertar.jsp Propósito de la Página Insertar.jsp Aspecto de la Página Insertar.jsp Mostrar la Tabla Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Código Completo de la Página Insertar.jsp Borrar un Registro de la Base de Datos o Form_Borrar.jsp Propósito de la Página Form_Borrar.jsp Aspecto de la Página Form_Borrar.jsp Recuperar los Datos del libro a Borrar Mostrar la Tabla Código Completo de la Página Form_Borrar.jsp o Borrar.jsp Propósito de la Página Borrar.jsp Crear el Aspecto de la Página Borrar.jsp Recuperar los Datos del libro a Borrar Mostar la Tabla Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Código Completo de la Página Borrar.jsp Modificar un Registro de la Base de Datos o Form_Modificar.jsp Propósito de la Página Form_Modificar.jsp Crear el Aspecto de la Página Form_Modificar.jsp Recuperar los Datos del libro a Modificar Mostrar el Formulario Código Completo de la Página Form_Modificar.jsp o Modificar.jsp Propósito de la Página Modificar.jsp Aspecto de la Página Modificar.jsp Mostrar la Tabla Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Código Completo de la Página Modificar.jsp Ficheros de Configuración o Libreria/WEB-INF/web.xml Propósito del Fichero web.xml Código Fuente Completo del Fichero web.xml o Libreria.xml Propósito del Fichero Libreria.xml Definición de Logger Definición del DataSource Parámetros de la Base de Datos Parámetros del Repositorio de Conexiones Código Fuente Completo del fichero Libreria.xml Desplegar y Ejecutar la Aplicación o Desplegar la Aplicación o Ejecutar la Aplicación Tutoriales Crear tu Primera Aplicación Web Real con Tomcat 4 y MySQL Autor: OnJava (OnJava) Traductor: Juan Antonio Palos (Ozito) ¿Qué Tecnologías Utilizar? ¿Qué Tecnologías Utilizar? Hemos decidido utilizar las tecnologías del contenedor Servlet/JSP Tomcat 4 para implementar una aplicación Web. Esto todavía tiene muchas opciones, y elegir entre las distintas tecnologías disponibles no es fácil. Para este curso, hemos decidido dejarlo lo más simple posible y utilizar Java Server Pages (JSPs) en combinación con clases Java. Deberíamos evitar la utilización de JSPs para implementar lógica compleja; dichas aplicaciones pueden ser divertidas de escribir, pero puede ser frustrante su depuración y casi imposible de entender y mantener. Una solución realmente buena es usar JSPs para manejar la presentación de la página web (porque para esto son buenas las JSPs), y Java para implementar la lógica compleja, como el acceso a bases de datos. De esta forma, el software será fácil de escribir y de depurar, y posteriormente el código será sencillo de entender y de mantener. La aplicación Web puede servirse sobre en un servidor Web dedicado o sobre un ordenador personal con Windows, Linux, o Mac OS X. Requiere un Java runtime environment (JDK 1.2 o superior ), y una versión reciente del Contenedor Servlet/JSP Tomcat (versión 4 o superior). Todos estos paquetes están disponibles en Internet de forma gratuita. La aplicación Web también requiere una base de datos. Servirá casi cualquier base de datos relacional, si acepta SQL y tiene un driver JDBC. MySQL tiene buena reputación y se ajusta a nuestro presupuesto perfectamente. Podemos obtener la última versión de MySQL y su driver Connector/J JDBC Driver desde MySQL.com. Para dar acceso a Tomcat (y sus aplicaciones) a nuestra base de datos, debemos copiar el fichero del driver JDBC de la base de datos al directorio common/lib de Tomcat. Finalmente, debemos configurar los roles admin y manager de Tomcat, y los nombres de usuarios y las passwords. Editamos el fichero tomcat-users.xml en el directorio conf de Tomcat, para que se parezca a esto: <?xml version='1.0'?> <tomcat-users> <role rolename="admin"/> <role rolename="manager"/> <user username="tomcatusername" password="tomcatpassword" roles="admin,manager"/> </tomcat-users> Configurar la Base de Datos o Crear la Tabla Libros en la Base de Datos Configurar la Base de Datos Crear la Tabla Libros en la Base de Datos Configurar la base de datos depende del software de base de datos que estemos utilizando. Necesitarás corregir estas instrucciones si no utilizas MySQL. Libreria emplea una sola tabla llamada Libros en una base de datos llamada biblioteca. La tabla Libros tiene siete campos: id, la clave primaria, un campo numérico que se incrementa automáticamente. isbn, un campo de 13 caracteres que contiene el código ISBN único para cada libro. editorial, un campo de 24 caracteres que contiene el nombre de la editorial que ha publicado el libro. autor, un campo de 32 caracteres que contiene el nombre del autor del libro. categoria, un campo de 32 caracteres que contiene la categoría a la que pertenece el libro. titulo, un campo de 50 caracteres que contiene el título del libro. ubicacion, un campo de 5 caracteres en el ubicación actual del libro en nuestro sistema de estanterías. Configuremos la base de datos MySQL. Primero arrancamos la Base de Datos utilizado la línea de comandos mysql con permisos de root. Cuando se nos pida, introducimos la password. Creamos la base de datos biblioteca y le concedemos permisos a mysqlusername en esa base de datos con la password mysqlpassword. Los comandos son: # mysql -u root -p mysql> create database biblioteca; mysql> grant all privileges on biblioteca.* to mysqlusername@localhost \ identified by 'mysqlpassword' with grant option; mysql> flush privileges; Luego, creamos la tabla Libros en la base de datos biblioteca: mysql> create table Libros ( \ id tinyint(4) primary key auto_increment, \ isbn varchar(13) NOT NULL, \ editorial varchar(24) NOT NULL, \ autor varchar(32) NOT NULL, \ categoria varchar(32) NOT NULL, \ titulo varchar(50) NOT NULL, \ ubicacion varchar(5) NOT NULL \ ); Enviamos los cambios con el comando commit;. Para verificar la configuración de la tabla, ejecutamos el comando describe Libros;. Deberíamos ver algo como esto: Ahora podemos insertar una fila de datos para probar la base de datos: mysql> insert into libros(isbn, editorial, autor, categoria, titulo, \ -> ubicacion) values ("84-415-0092-4", "Anaya Multimedia",\ -> "Varios", "Informática", "La Biblia de Java", "AB-14"); mysql> select * from Libros; Esto debería producir la siguiente salida: Observa que a la id del libro se le ha asignado automáticamente un valor de 1. La base de datos ya está lista para su utilización. Las Clases Java de la Aplicación o o o libreria.ContextListener Propósito de la clase ContextListener Métodos de la clase ContextListener Código Fuente Completo de la clase ContextListener libreria.LibrosBD Propósito de la clase LibrosBD Métodos de la Clase LibrosBD Código Fuente Completo de la clase LibrosBD libreria.Libro Propósito de la clase Libros Métodos de la clase Libros Código Fuente Completo de la clase Libro Las Clases Java de la Aplicación La aplicación Web utilizada para demostrar las tecnologías usadas en este tutorial es una simple aplicación de control de una librería (solo control y ubicación de los libros, no hay facturación, por ejemplo), llamada Libreria . No es el propósito de este tutorial crear una aplicación completa, es sólo un ejemplo. Libreria tiene tres clases Java: libreria.ContextListener es un oyente del contexto servlet al que Tomcat llamará cuando inicie y detenga la aplicación Libreria. Esta clase crea un objeto de la clase LibrosBD y lo almacena como un atributo de contexto con el nombre BaseDatos libreria.LibrosBD es una clase que representa la base de datos de libros. Su constructor establece una conexión a la base de datos (utilizando el objeto LibrosBD que se obtiene del atributo de contexto BaseDatos), y la sesión se puede compartir entre varias sesiones web. La clase proporciona varios métodos de acceso a la base de datos (para insertar, borrar, modificar u obtener registros de la base de datos). libreria.Libro es una clase Java que representa un libro. Las páginas JSP de la aplicación utilizan esta clase como un Bean contenedor de datos para mostrarlos. libreria.ContextListener libreria.ContextListener es un oyente del contexto servlet al que se llamará cuando arranque y cuando se pare la aplicación Libreria. Esto se configura en el descriptor de despliegue de la aplicación web.xml. Cuando se arranca la aplicación Libreria se crea un ejemplar de la clase LibrosBD y se almacena como un atributo de contexto; cuando se cierra la aplicación, el objeto LibrosBD se recupera del atributo de contexto y se cierra la conexión con la base de datos. Entre tanto, las JSP recuperan el objeto LibrosBD del atributo de contexto siempre que necesitan acceder a la base de datos. Propósito de la clase ContextListener El propósito de la clase Java libreria.ContextListener es crear un ejemplar de libreria.LibrosBD y almacenarlo como un atributo del contexto servlet identificado como: "BaseDatos". Esto permitirá a las páginas JSP recuperar el ejemplar de libreria.LibrosBD y acceder a la tabla Libros. libreria.ContextListener está configurado como un oyente de contexto servlet en el fichero web.xml. Métodos de la clase ContextListener contextInitialized Se llama a contextInitialized siempre que la aplicación web arranca. Primero se recupera el contexto servlet desde el evento de contexto servlet: ServletContext servletContext = servletContextEvent.getServletContext (); Luego se crea un ejemplar de LibrosBD y se graba en el contexto servlet identificado como: "BaseDatos". Si este proceso lanza una excepción se guarda un log: try { LibrosBD LibrosBD = new LibrosBD (); servletContext.setAttribute ("BaseDatos", LibrosBD); } catch (Exception e) { servletContext.log ("No se pudo crear el atributo BaseDatos: " + e.getMessage()); } contextDestroyed Se llama a contextDestroyed cuando se cierra la aplicación web. Primero se recupera el contexto servlet desde el evento ServletContexto: ServletContext servletContext = servletContextEvent.getServletContext (); Luego se recupera el objeto LibrosBD desde el contexto y se cierra la base de datos: LibrosBD LibrosBD = (LibrosBD) servletContext.getAttribute ("BaseDatos"); LibrosBD.close (); Luego se elimina el atributo del contexto servlet: servletContext.removeAttribute ("BaseDatos"); Código Fuente Completo de la clase ContextListener // // // ContextListener.java package libreria; import javax.servlet.*; public final class ContextListener implements ServletContextListener { public void contextInitialized (ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext (); try { LibrosBD LibrosBD = new LibrosBD (); servletContext.setAttribute ("BaseDatos", LibrosBD); } catch (Exception e) { servletContext.log ("No se pudo crear el atributo BaseDatos: " + e.getMessage ()); } } public void contextDestroyed (ServletContextEvent servletContextEvent) { ServletContext servletContext = servletContextEvent.getServletContext (); LibrosBD LibrosBD = (LibrosBD) servletContext.getAttribute ("BaseDatos"); LibrosBD.close (); servletContext.removeAttribute ("BaseDatos"); } } libreria.LibrosBD libreria.LibrosBD es una clase que representa la base de datos de libros. Su constructor establece una conexión a la base de datos, y la sesión se puede compartir entre varias sesiones web. La clase proporciona varios métodos de acceso a la base de datos. Propósito de la clase LibrosBD El propósito de la clase libreria.LibrosBD es establecer una conexión a la base de datos pública y proporcionar métodos para acceder de forma segura y actualizar la tabla Libros contenida en la base de datos sin conflictos con otros usuarios que estén accediendo a los mismos datos. Sólo hay una conexión a la base de datos que es compartida por todos los usuarios de la aplicación Web Libreria. Esto es adecuado mientras el número de usuarios concurrentes no sea excesivo. Vamos a mantenerlo lo más simple posible, sólo debemos añadir soporte para varias conexiones si es realmente necesario. Observa, sin embargo, que si vamos a realizar esas complejidades, es en esta clase Java donde debemos hacerlas. Métodos de la Clase LibrosBD Constructor de LibrosBD: Establece una conexión a la base de datos pública. Hasta hace poco, si queríamos establecer una conexión a una base de datos desde un Servlet bajo Tomcat teníamos que codificar el driver JDBC, la URL de la base de datos, y el nombre de usuario y su password dentro del Servlet de esta forma: Class.forName ("org.gjt.mm.mysql.Driver").newInstance (); connection = DriverManager.getConnection ("jdbc:mysql://localhost/MiBase", "mysqlusername", "mysqlpassword"); No es buena idea codificar dicha información en el código fuente de la aplicación. Tomcat 4 resuelve este problema permitiendo al Servlet acceder a Tomcat y recuperar una conexión desde el DataSource que se define en el fichero Libreria.xml, como veremos más adelante. Primero se recupera el javax.naming.InitialContext para que se pueda realizar una búsqueda JNDI: InitialContext initialContext = new InitialContext (); Después se recupera el contexto de la aplicación Libreria: Context envContext = (Context) initialContext.lookup ("java:comp/env"); Luego se recupera el propio DataSource: DataSource dataSource = (DataSource) envContext.lookup ("jdbc/biblioteca"); Y por último se recupera la conexión desde el DataSource: this.connection = dataSource.getConnection (); Todos los parámetros del DataSource tenemos que definirlos en el fichero Libreria.xml (que veremos más adelante), aunque también se pueden modificar usando las facilidades de administración de Tomcat, con la dirección http://localhost:8080/admin . getConnection Se utilizan los métodos getConnection y releaseConnection para asegurarse de que la conexión a la base de datos se puede compartir de forma segura, el recurso de la conexión se controla utilizando los métodos sincronizados getConnection y releaseConnection. Primero getConnection espera hasta que se libera la conexión: while (this.connectionFree == false) { try { wait (); } catch (InterruptedException e) { } } Luego marca el indicador de conexión libre como no libre, así bloquea la conexión hasta que se llame a releaseConnection: this.connectionFree = false; Luego se lo notifica a cualquier otro thread de LibrosBD que esté esperando una conexión: notify (); Finalmente devuelve la conexión: return this.connection; releaseConnection Primero espera hasta que la conexión esté ocupada: while (this.connectionFree == true) { try { wait (); } catch (InterruptedException e) { } } Luego selecciona el indicador de conexión libre a libre, así desbloquea la conexión hasta que se llame a getConnection: this.connectionFree = true; Finalmente se lo notifica a cualquier otro thread de LibrosBD que esté esperando una conexión: notify (); Todas las demás rutinas que acceden a la base de datos emplean getConnection y releaseConnection, para que sólo pueda acceder a la base de datos un thread a la vez. getLibro El método getLibro toma un parámetro id y devuelve el Libro para ese id; si no se puede encontrar ese id se devuelve un Libro null. getLibro primero obtiene una conexión libre this.getConnection (); Luego crea una sentencia select, e inserta el id en la posición adecuada: PreparedStatement preparedStatement = this.connection.prepareStatement ("SELECT * FROM Libros WHERE id = ?"); preparedStatement.setString (1, id); Luego ejecuta la sentencia: ResultSet resultSet = preparedStatement.executeQuery (); Si la sentencia select devuelve datos, se ensambla un objeto Libro con los datos, se cierra la consulta sql; se libera la conexión se devuelve el objeto Libro: if (resultSet.next ()) { Libro libro = new Libro ( resultSet.getString (1), resultSet.getString (2), resultSet.getString (3), resultSet.getString (4), resultSet.getString (5), resultSet.getString (6), resultSet.getString (7) ); preparedStatement.close (); this.releaseConnection (); return libro; } Si la sentencia select no devuelve datos, se cierra la sentencia, se libera la conexión, y se devuelve un objeto Libro null: else { preparedStatement.close (); this.releaseConnection (); return null; } insertarLibro, borrarLibro, modificarLibro, y obtenerLibros Todos estos métodos utilizan una técnica similar a la del método getLibro close close simplemente cierra la conexión: this.connection.close (); Código Fuente Completo de la clase LibrosBD // // // LibrosBD.java package libreria; import java.sql.*; import java.util.*; import javax.sql.*; import javax.naming.*; public class LibrosBD { Connection connection; private boolean connectionFree = true; private ArrayList libros; public LibrosBD () throws Exception { try { InitialContext initialContext = new InitialContext (); Context envContext = (Context) initialContext.lookup ("java:comp/env"); DataSource dataSource = (DataSource) envContext.lookup ("jdbc/biblioteca"); this.connection = dataSource.getConnection (); } catch (Exception e) { throw new Exception ("No se pudo abrir la base de datos biblioteca: " + e.getMessage ()); } } protected synchronized Connection getConnection () { while (this.connectionFree == false) { try { wait (); } catch (InterruptedException e) { } } this.connectionFree = false; notify (); return this.connection; } protected synchronized void releaseConnection () { while (this.connectionFree == true) { try { wait (); } catch (InterruptedException e) { } } this.connectionFree = true; notify (); } public Libro getLibro (String id) { try { this.getConnection (); PreparedStatement preparedStatement = this.connection.prepareStatement ("SELECT id, isbn, editorial, autor, categoria, titulo, ubicacion FROM libros" + " WHERE id = ?"); preparedStatement.setString (1, id); ResultSet resultSet = preparedStatement.executeQuery (); if (resultSet.next ()) { Libro libro = new Libro ( resultSet.getString (1), resultSet.getString (2), resultSet.getString (3), resultSet.getString (4), resultSet.getString (5), resultSet.getString (6), resultSet.getString (7) ); preparedStatement.close (); this.releaseConnection (); return libro; } else { preparedStatement.close (); this.releaseConnection (); return null; } } catch (SQLException e) { this.releaseConnection (); return null; } } public int insertarLibro (Libro libro) { int rowsAffected = 0; try { this.getConnection (); PreparedStatement preparedStatement = this.connection.prepareStatement ("INSERT INTO libros (isbn, editorial, autor, categoria, titulo, " + " ubicacion) VALUES (?, ?, ?, ?, ?, ?)"); preparedStatement.setString (1, libro.getIsbn ()); preparedStatement.setString (2, libro.getEditorial ()); preparedStatement.setString (3, libro.getAutor ()); preparedStatement.setString (4, libro.getCategoria ()); preparedStatement.setString (5, libro.getTitulo ()); preparedStatement.setString (6, libro.getUbicacion ()); rowsAffected = preparedStatement.executeUpdate (); preparedStatement.close (); this.releaseConnection (); } catch (SQLException e) { this.releaseConnection (); return 0; } return rowsAffected; } public int borrarLibro (String id){ int rowsAffected = 0; try { this.getConnection (); PreparedStatement preparedStatement = this.connection.prepareStatement ("DELETE FROM libros WHERE id = ?"); preparedStatement.setString (1, id); rowsAffected = preparedStatement.executeUpdate (); preparedStatement.close (); this.releaseConnection (); } catch (SQLException e) { this.releaseConnection (); return 0; } return rowsAffected; } public int modificarLibro (Libro libro) { int rowsAffected = 0; try { this.getConnection (); PreparedStatement preparedStatement = this.connection.prepareStatement ("UPDATE libros SET isbn=?, editorial=?," + " autor=?, categoria=?, titulo=?, ubicacion=? WHERE id =?"); preparedStatement.setString (1, libro.getIsbn ()); preparedStatement.setString (2, libro.getEditorial ()); preparedStatement.setString (3, libro.getAutor ()); preparedStatement.setString (4, libro.getCategoria ()); preparedStatement.setString (5, libro.getTitulo ()); preparedStatement.setString (6, libro.getUbicacion ()); preparedStatement.setString (7, libro.getId ()); rowsAffected = preparedStatement.executeUpdate (); preparedStatement.close (); this.releaseConnection (); } catch (SQLException e) { this.releaseConnection (); return 0; } return rowsAffected; } public Collection getLibros () { libros = new ArrayList (); try { this.getConnection (); PreparedStatement preparedStatement = this.connection.prepareStatement ("SELECT id, isbn, editorial, autor, categoria, titulo, ubicacion FROM libros"); ResultSet resultSet = preparedStatement.executeQuery (); while (resultSet.next ()) { Libro libro = new Libro ( resultSet.getString (1), resultSet.getString (2), resultSet.getString (3), resultSet.getString (4), resultSet.getString (5), resultSet.getString (6), resultSet.getString (7) ); libros.add (libro); } preparedStatement.close (); } catch (SQLException e) { return null; } this.releaseConnection (); return libros; } public void close () { try { this.connection.close (); } catch (SQLException e) { System.out.println (e.getMessage ()); } } } libreria.Libro libreria.Libro es una clase Java que representa un libro. Las clases que recolectan datos todavía son una buena idea cuando se programan JSPs, por eso esta clase es una buena idea para la aplicación Libreria. El constructor de libreria.Libro almacena los campos del libro en el objeto. Esta clase también incluye los habituales métodos get para recuperar los datos del libro: Libro(String id, String isbn, String editorial, String autor, String categoria, String titulo, String ubicacion) getId() getIsbn() getEditorial() getAutor() getCategoria() getTitulo() getUbicacion() Propósito de la clase Libros El propósito de esta clase es recolectar los datos relativos a un libro de nuestra base de datos. Métodos de la clase Libros Constructor de la clase Libro El constructor almacena los campos suministrados del libro: this.id = id; this.isbn = isbn; this.editorial = editorial; this.autor = autor; this.categoria = categoria; this.titulo = titulo; this.ubicacion = ubicacion; getId, getIsbn, getEditorial, getAutor, getCategoria, getTitulo y getUbicacion Estos métodos devuelven los distintos campos que componente un libro. Código Fuente Completo de la clase Libro // // // Libro.java package libreria; public class Libro private String private String private String private String private String private String private String { id = null; isbn = null; editorial = null; autor = null; categoria = null; titulo = null; ubicacion = null; public Libro (String id, String isbn, String editorial, String autor, String categoria, String titulo, String ubicacion) this.id = id; this.isbn = isbn; this.editorial = editorial; this.autor = autor; this.categoria = categoria; this.titulo = titulo; this.ubicacion = ubicacion; } public String getId () { return this.id; } public String getIsbn () { return this.isbn; } public String getEditorial () { return this.editorial; } public String getAutor () { return this.autor; } public String getCategoria () { return this.categoria; } { public String getTitulo () { return this.titulo; } public String getUbicacion () { return this.ubicacion; } } Las Páginas JSP o La página Index.jsp Propósito de la Página Index.jsp Aspecto de la Página Mostrar la Tabla Bucle por Todas las Filas de la Tabla Mostrar un Libro en un Fila de la Tabla Código Completo de la Página Index.jsp Las Páginas JSP La aplicación Libreria tiene siete páginas JSP. Cada una representa una página Web que realiza una operación independiente sobre la base de datos. El estado de la base de datos en cada página es independiente de su estado en la página anterior. Si la base de datos cambia debido a una solicitud de otro usuario, la página Web lo detectará y reaccionará de la forma apropiada. Por ejemplo, si estamos modificando un libro y otro usuario borra ese libro antes de que confirmemos la solicitud de modificación, la JSP nos notificará el fallo al intentar modificar un libro que ahora no existe. La página Index.jsp Es la página principal de la aplicación web Libreria, y es la primera página que se muestra a un usuario cuando entra en la aplicación Web. Muestra una tabla con todos los libros que hay en la tabla Libros de la base de datos. Cada fila de la tabla muestra un libro individual, y enlaces para borrar o modificar es libro. La parte inferior de la página tiene un enlace para poder añadir nuevos libros. El enlace Añadir un Nuevo Libro pasa el control a la página Form_Insertar.jsp. El enlace Borrar pasa el control a la página Form_Borrar.jsp con el id del libro a borrar. El enlace Modificar pasa el control a la página Form_Modificar.jsp con el id del libro a modificar. Propósito de la Página Index.jsp El propósito de Index.jsp es producir una página Web con una tabla que muestre el contenido de la tabla Libros de la base de datos, con enlaces para añadir nuevos libros a la base de datos [Form_Insertar.jsp]; borrar libros específicos de la base de datos [Form_Borrar.jsp]; y modificar libros específicos en la base de datos [Form_Modificar.jsp]. La siguiente figura muestra un ejemplo de la página principal de la aplicación Libreria: Aspecto de la Página Este código HTML dibuja el aspecto de la página con un enlace a Form_Insertar.jsp en la parte inferior de la página <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Página Principal de mi Librería</title> </head> <body bgcolor="#ffffee"> <h1><center>Página Principal de mi Librería</center></h1> --- Aquí va el código que muestra la tabla con los datos <hr> <center> <destacar><a href="Form_Insertar.jsp">Añadir un Nuevo Libro</a></destacar> </center> </body> </html> Mostrar la Tabla Este código HTML muestra la tabla y sus cabeceras: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>Autor</th> <th>Titulo</th> <th>Ubicacion</th> <th>Accion</th> <th>ID</th> </tr> -- Aquí va el código que muestra los datos </table> Bucle por Todas las Filas de la Tabla Este código Java recupera el ejemplar libreria.LibrosBD almacenado en el atributo BaseDatos de la aplicación Web por libreria.ContextListener: LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Luego se recupera un objeto Collection con el contenido de la base de datos: Collection libros = librosBD.getLibros(); Si el objeto Collection no es nulo, y contiene algún libro [es decir, su tamaño es mayor que cero], se procesa el objeto Collection recuperando uno por uno todos sus libros: if (libros != null) { if (libros.size () > 0) { for (Iterator iterator = libros.iterator(); iterator.hasNext(); ) { ... aquí va el código que muestra los datos de una fila... } } } Mostrar un Libro en un Fila de la Tabla Este código HTML mezclado con código Java muestra un libro en una fila de la tabla. El código Java simplemente recupera campos individuales desde el libro: libro.getAutor() devuelve el nombre del autor del libro; libro.getTitulo () devuelve el título del libro; libro.getUbicacion () devuelve la ubicación del libro en nuestras estanterías; y libro.getId () devuelve el id. En la primera columna de la tabla va el nombre del autor; en la segunda columna va el título; en la tercera columna va la ubicación, en la cuarta columna un enlace a Form_Borrar.jsp, la palabra "o" y un enlace a Form_Modificar.jsp; y en la columna final va el id: <tr> <td> <%= libro.getAutor () %> </td> <td> <%= libro.getTitulo () %> </td> <td> <%= libro.getUbicacion () %> </td> <td align="center"> <destacar><a href="Form_Borrar.jsp?id=<%= libro.getId () %>"> Borrar</a></destacar> o <destacar><a href="Form_Modificar.jsp?id=<%= libro.getId () %>"> Modificar</a></destacar> </td> <td align="center"> <%= libro.getId () %> </td> </tr> Cuando se selecciona el enlace "Borrar" se le pasa el parámetro id a la página Form_Borrar.jsp, y cuando se selecciona el enlace "Modificar" se le pasa el mismo parámetro a la página Form_Modificar.jsp. Código Completo de la Página Index.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Página Principal de mi Librería</title> </head> <body bgcolor="#ffffee"> <h1><center>Página Principal de mi Librería</center></h1> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>Autor</th> <th>Titulo</th> <th>Ubicacion</th> <th>Accion</th> <th>ID</th> </tr> <% LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Collection libros = librosBD.getLibros(); if (libros != null) { if (libros.size () > 0) { for (Iterator iterator = libros.iterator(); iterator.hasNext(); ) { Libro libro = (Libro) iterator.next (); %> <tr> <td> <%= libro.getAutor () %> </td> <td> <%= libro.getTitulo () %> </td> <td> <%= libro.getUbicacion () %> </td> <td align="center"> <destacar><a href="Form_Borrar.jsp?id=<%= libro.getId () %>"> Borrar</a></destacar> o <destacar><a href="Form_Modificar.jsp?id=<%= libro.getId () %>"> Modificar</a></destacar> </td> <td align="center"> <%= libro.getId () %> </td> </tr> <% } } } %> </table> <br> <hr> <center> <destacar><a href="Form_Insertar.jsp">Añadir un Nuevo Libro</a></destacar> </center> </body> </html> Las Páginas JSP o La página Index.jsp Propósito de la Página Index.jsp Aspecto de la Página Mostrar la Tabla Bucle por Todas las Filas de la Tabla Mostrar un Libro en un Fila de la Tabla Código Completo de la Página Index.jsp Las Páginas JSP La aplicación Libreria tiene siete páginas JSP. Cada una representa una página Web que realiza una operación independiente sobre la base de datos. El estado de la base de datos en cada página es independiente de su estado en la página anterior. Si la base de datos cambia debido a una solicitud de otro usuario, la página Web lo detectará y reaccionará de la forma apropiada. Por ejemplo, si estamos modificando un libro y otro usuario borra ese libro antes de que confirmemos la solicitud de modificación, la JSP nos notificará el fallo al intentar modificar un libro que ahora no existe. La página Index.jsp Es la página principal de la aplicación web Libreria, y es la primera página que se muestra a un usuario cuando entra en la aplicación Web. Muestra una tabla con todos los libros que hay en la tabla Libros de la base de datos. Cada fila de la tabla muestra un libro individual, y enlaces para borrar o modificar es libro. La parte inferior de la página tiene un enlace para poder añadir nuevos libros. El enlace Añadir un Nuevo Libro pasa el control a la página Form_Insertar.jsp. El enlace Borrar pasa el control a la página Form_Borrar.jsp con el id del libro a borrar. El enlace Modificar pasa el control a la página Form_Modificar.jsp con el id del libro a modificar. Propósito de la Página Index.jsp El propósito de Index.jsp es producir una página Web con una tabla que muestre el contenido de la tabla Libros de la base de datos, con enlaces para añadir nuevos libros a la base de datos [Form_Insertar.jsp]; borrar libros específicos de la base de datos [Form_Borrar.jsp]; y modificar libros específicos en la base de datos [Form_Modificar.jsp]. La siguiente figura muestra un ejemplo de la página principal de la aplicación Libreria: Aspecto de la Página Este código HTML dibuja el aspecto de la página con un enlace a Form_Insertar.jsp en la parte inferior de la página <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Página Principal de mi Librería</title> </head> <body bgcolor="#ffffee"> <h1><center>Página Principal de mi Librería</center></h1> --- Aquí va el código que muestra la tabla con los datos <hr> <center> <destacar><a href="Form_Insertar.jsp">Añadir un Nuevo Libro</a></destacar> </center> </body> </html> Mostrar la Tabla Este código HTML muestra la tabla y sus cabeceras: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>Autor</th> <th>Titulo</th> <th>Ubicacion</th> <th>Accion</th> <th>ID</th> </tr> -- Aquí va el código que muestra los datos </table> Bucle por Todas las Filas de la Tabla Este código Java recupera el ejemplar libreria.LibrosBD almacenado en el atributo BaseDatos de la aplicación Web por libreria.ContextListener: LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Luego se recupera un objeto Collection con el contenido de la base de datos: Collection libros = librosBD.getLibros(); Si el objeto Collection no es nulo, y contiene algún libro [es decir, su tamaño es mayor que cero], se procesa el objeto Collection recuperando uno por uno todos sus libros: if (libros != null) { if (libros.size () > 0) { for (Iterator iterator = libros.iterator(); iterator.hasNext(); ) { ... aquí va el código que muestra los datos de una fila... } } } Mostrar un Libro en un Fila de la Tabla Este código HTML mezclado con código Java muestra un libro en una fila de la tabla. El código Java simplemente recupera campos individuales desde el libro: libro.getAutor() devuelve el nombre del autor del libro; libro.getTitulo () devuelve el título del libro; libro.getUbicacion () devuelve la ubicación del libro en nuestras estanterías; y libro.getId () devuelve el id. En la primera columna de la tabla va el nombre del autor; en la segunda columna va el título; en la tercera columna va la ubicación, en la cuarta columna un enlace a Form_Borrar.jsp, la palabra "o" y un enlace a Form_Modificar.jsp; y en la columna final va el id: <tr> <td> <%= libro.getAutor () %> </td> <td> <%= libro.getTitulo () %> </td> <td> <%= libro.getUbicacion () %> </td> <td align="center"> <destacar><a href="Form_Borrar.jsp?id=<%= libro.getId () %>"> Borrar</a></destacar> o <destacar><a href="Form_Modificar.jsp?id=<%= libro.getId () %>"> Modificar</a></destacar> </td> <td align="center"> <%= libro.getId () %> </td> </tr> Cuando se selecciona el enlace "Borrar" se le pasa el parámetro id a la página Form_Borrar.jsp, y cuando se selecciona el enlace "Modificar" se le pasa el mismo parámetro a la página Form_Modificar.jsp. Código Completo de la Página Index.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Página Principal de mi Librería</title> </head> <body bgcolor="#ffffee"> <h1><center>Página Principal de mi Librería</center></h1> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>Autor</th> <th>Titulo</th> <th>Ubicacion</th> <th>Accion</th> <th>ID</th> </tr> <% LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Collection libros = librosBD.getLibros(); if (libros != null) { if (libros.size () > 0) { for (Iterator iterator = libros.iterator(); iterator.hasNext(); ) { Libro libro = (Libro) iterator.next (); %> <tr> <td> <%= libro.getAutor () %> </td> <td> <%= libro.getTitulo () %> </td> <td> <%= libro.getUbicacion () %> </td> <td align="center"> <destacar><a href="Form_Borrar.jsp?id=<%= libro.getId () %>"> Borrar</a></destacar> o <destacar><a href="Form_Modificar.jsp?id=<%= libro.getId () %>"> Modificar</a></destacar> </td> <td align="center"> <%= libro.getId () %> </td> </tr> <% } } } %> </table> <br> <hr> <center> <destacar><a href="Form_Insertar.jsp">Añadir un Nuevo Libro</a></destacar> </center> </body> </html> Insertar un Registro en la Base de Datos o Form_Insertar.jsp Propósito de la Página Form_Insertar.jsp Aspecto de la Página Form_Insertar.jsp Dibujar el Formulario Código Completo de la Página Form_Insertar.jsp o Insertar.jsp Propósito de la Página Insertar.jsp Aspecto de la Página Insertar.jsp Mostrar la Tabla Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Código Completo de la Página Insertar.jsp Insertar un Registro en la Base de Datos Form_Insertar.jsp Form_Insertar.jsp muestra un formulario en el que introduciremos los campos del nuevo libro. En la parte inferior de la página hay en enlace para abortar la solicitud. Propósito de la Página Form_Insertar.jsp El propósito de esta página es producir una página Web con un formulario que el usuario rellena con los datos de un libro. El usuario podría entonces enviar los datos del formulario para su procesamiento transfiriendo el control a la página o abortar el proceso seleccionando un enlace de vuelta a la página Index.jsp. En la siguiente figura podemos ver un ejemplo de la página Form_Insertar.jsp: Aspecto de la Página Form_Insertar.jsp Este código HTML crea el aspecto de la página con un enlace a la página Index.jsp, etiquetado como "Volver a la Página Inicial [el libro no se añadirá]" en la parte inferior de la página: <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería: Insertar un nuevo libro</title> </head> <body bgcolor="#ffffee"> <h1><center>Librería: Insertar un nuevo libro</center></h1> -- Aquí va el código que muestra el formulario -<hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial [el libro no se añadirá]</a></destacar> </center> </body> </html> Dibujar el Formulario Este código HTML mezclado con código Java crea un formulario cuya acción es "postear" los datos del nuevo libro que hay en los campos de entrada a la página : <form method="post" action="Insertar.jsp"> Luego se muestra una tabla; en la columna izquierda de la tabla se muestran los nombres de los campos; la columna derecha contiene los campos de entrada: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><input name="isbn" type="text"></td> </tr> <tr> <th>Editorial:</th> <td><input name="editorial" type="text"></td> </tr> <tr> <th>Autor:</th> <td><input name="autor" type="text"></td> </tr> <tr> <th>Categoría:</th> <td><input name="categoria" type="text"></td> </tr> <tr> <th>Título:</th> <td><input name="titulo" type="text"></td> </tr> <tr> <th>Ubicación:</th> <td><input name="ubicacion" type="text"></td> </tr> </table> Luego se define un campo oculto que simula la pulsación del botón submit cuando se pulsa la tecla return: <input name="pagemode" type="hidden" value="submit"> Luego se muestra el botón de envío del formulario etiquetado "Añadir el nuevo libro": <input type="submit" value="Añadir el nuevo libro"> Cuando se pulsa el botón de envío, se pasan los parámetros isbn, editorial, autor, categoria, titulo y ubicacion a la página Código Completo de la Página Form_Insertar.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería: Insertar un nuevo libro</title> </head> <body bgcolor="#ffffee"> <h1><center>Librería: Insertar un nuevo libro</center></h1> <form method="post" action="Insertar.jsp"> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><input name="isbn" type="text"></td> </tr> <tr> <th>Editorial:</th> <td><input name="editorial" type="text"></td> </tr> <tr> <th>Autor:</th> <td><input name="autor" type="text"></td> </tr> <tr> <th>Categoría:</th> <td><input name="categoria" type="text"></td> </tr> <tr> <th>Título:</th> <td><input name="titulo" type="text"></td> </tr> <tr> <th>Ubicación:</th> <td><input name="ubicacion" type="text"></td> </tr> </table> <br> <center> <input name="pagemode" type="hidden" value="submit"> <input type="submit" value="Añadir el nuevo libro"> </center> <hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial [el libro no se añadirá]</a></destacar> </center> </body> </html> Insertar.jsp Esta página muestra los campos que recibe del nuevo libro. Luego intenta añadir el nuevo libro a la base de datos y muestra el éxito o el fracaso en el intento. En la parte inferior de la página hay un enlace a la página Index.jsp. Propósito de la Página Insertar.jsp El propósito de esta página es producir una página Web con un tabla que muestre los parámetros del libro que se le han pasado desde la página Form_Insertar.jsp; realmente realiza la actualización de la base de datos; muestra si la base de datos se actualizó correctamente o no, y espera hasta que el usuario seleccione el enlace de vuelta a Index.jsp. La siguiente figura muestra un ejemplo de la página Insertar.jsp: Aspecto de la Página Insertar.jsp Este código HTML genera el aspecto de la página con un enlace a Index.jsp en la parte inferior de la página: <html> <head> <title>Librería -- Insertando un nuevo Libro</title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Insertando un nuevo Libro</center></h1> -- aquí va el código para mostrar la tabla --- aquí va el código para actualizar la base de datos y mostrar el éxito o el fracaso de la operación -<hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial</a></destacar> </center> </body> </html> Mostrar la Tabla Este código HTML mezclado con código Java muestra la tabla; en la columna izquierda se muestran los nombres de los campos; la columna derecha contiene los datos del nuevo libro recuperados desde los parámetros: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><%= request.getParameter ("isbn") %></td> </tr> <tr> <th>Editorial:</th> <td><%= request.getParameter ("editorial") %></td> </tr> <tr> <th>Autor:</th> <td><%= request.getParameter ("autor") %></td> </tr> <tr> <th>Categoría:</th> <td><%= request.getParameter ("categoria") %></td> </tr> <tr> <th>Título:</th> <td><%= request.getParameter ("titulo") %></td> </tr> <tr> <th>Ubicación:</th> <td><%= request.getParameter ("ubicacion") %></td> </tr> </table> Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Este código Java mezclado con código HTML recupera el ejemplar de libreria.LibrosBD almacenado en el atributo BaseDatos de la aplicación por libreria.ContextListener: LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Esto construye un objeto Libro con los parámetros pasados desde Form_Insertar.jsp: Libro libro = new Libro ( null, request.getParameter ("isbn"), request.getParameter ("editorial"), request.getParameter ("autor"), request.getParameter ("categoria"), request.getParameter ("titulo"), request.getParameter ("ubicacion") ); Luego se añade el libro a la base de datos: int rowsAffected = librosBD.insertarLibro (libro); Si sólo se ve afectada una fila por la actualización de la base de datos se muestra el mensaje "Se ha Añadido a la Base de Datos" en color verde, si no es así, se muestra el mensaje "No se Pudo Añadir el Registro" en color rojo: if (rowsAffected == 1) { %> <center> <h2><font color="#00cc00">Se ha añadido a la Base de Datos</font></h2> </center> <% } else { %> <center> <h2><font color="#cc0000">No se ha podido Añadir el registro</font></h2> </center> <% } %> Código Completo de la Página Insertar.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería -- Insertando un nuevo Libro</title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Insertando un nuevo Libro</center></h1> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><%= request.getParameter ("isbn") %></td> </tr> <tr> <th>Editorial:</th> <td><%= request.getParameter ("editorial") %></td> </tr> <tr> <th>Autor:</th> <td><%= request.getParameter ("autor") %></td> </tr> <tr> <th>Categoría:</th> <td><%= request.getParameter ("categoria") %></td> </tr> <tr> <th>Título:</th> <td><%= request.getParameter ("titulo") %></td> </tr> <tr> <th>Ubicación:</th> <td><%= request.getParameter ("ubicacion") %></td> </tr> </table> <% LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Libro libro = new Libro ( null, request.getParameter ("isbn"), request.getParameter ("editorial"), request.getParameter ("autor"), request.getParameter ("categoria"), request.getParameter ("titulo"), request.getParameter ("ubicacion") ); int rowsAffected = librosBD.insertarLibro(libro); if (rowsAffected == 1) { %> <center> <h2><font color="#00cc00">Se ha añadido a la Base de Datos</font></h2> </center> <% } else { %> <center> <h2><font color="#cc0000">No se ha podido Añadir el registro</font></h2> </center> <% } %> <hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial</a></destacar> </center> </body> </html> Borrar un Registro de la Base de Datos o Form_Borrar.jsp Propósito de la Página Form_Borrar.jsp Aspecto de la Página Form_Borrar.jsp Recuperar los Datos del libro a Borrar Mostrar la Tabla Código Completo de la Página Form_Borrar.jsp o Borrar.jsp Propósito de la Página Borrar.jsp Crear el Aspecto de la Página Borrar.jsp Recuperar los Datos del libro a Borrar Mostar la Tabla Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Código Completo de la Página Borrar.jsp Borrar un Registro de la Base de Datos Form_Borrar.jsp Esta página lee el libro correspondiente al ID que ha recibido. Luego muestra los campos del libro en una tabla para que podamos asegurarnos de que se va a borrar el libro correcto. En la parte inferior de la página hay dos enlaces: uno para continuar con la solicitud de borrado del libro y otro para abortar la solicitud. Propósito de la Página Form_Borrar.jsp El propósito de esta página es producir una página web con una tabla que muestre el libro que se va a borrar. El usuario podría continuar el proceso de borrado seleccionado un enlace a la página Borrar.jsp o abortar el proceso seleccionando un enlace de vuelta a Index.jsp. La siguiente imagen muestra un ejemplo de la página Form_Borrar.jsp: Aspecto de la Página Form_Borrar.jsp Este código HTML crea el aspecto de la página con un enlace a Borrar.jsp etiquetado como "Borrar el Libro nnn" y un enlace a Index.jsp etiquetado como "Volver a la Página Inicial [el libro no se borrará]", en la parte inferior de la página: <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería -- Borrando el Libro <%= request.getParameter ("id") %></title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Borrando el Libro <%= request.getParameter ("id") %></center></h1> -- aquí va el código para recuperar los datos del libro a borrar -<br> <center> <destacar><a href="Borrar.jsp?id=<%= libro.getId () %>">Borrar el libro <%= request.getParameter ("id") %></a></destacar> </center> <% } else { %> <center> <h2><font color="#cc0000">No se pudo encontrar el libro <%= request.getParameter ("id") %></font></h2> </center> <% } %> <hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial [el libro no se borrará]</a></destacar> </center> </body> </html> Cuando se pulsa sobre el enlace "Borrar el Libro nnn" se le pasa el parámetro id al página Borrar.jsp. Recuperar los Datos del libro a Borrar Este código Java recupera el ejemplar de libreria.LibrosBD almacenado en el atributo BaseDatos de la aplicación web por libreria.ContextListener: LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Luego obtiene de la base de datos el libro cuyo id se ha pasado como parámetro a esta página desde Index.jsp: Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id")); if (libro != null){ -- aquí va el código para mostrar la tabla -} else { %> <center> <h2><font color="#cc0000">No se pudo encontrar el libro <%= request.getParameter ("id") %></font></h2> </center> <% } Mostrar la Tabla Este código HTML mezclado con código Java muestra la tabla; en la columna izquierda se muestran los nombres de los campos; la columna derecha contiene los datos del libro recuperados desde la base de datos: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><input name="isbn" type="text" value="<%= libro.getIsbn () %>"></td> </tr> <tr> <th>Editorial:</th> <td><input name="editorial" type="text" value="<%= libro.getEditorial() %>"></td> </tr> <tr> <th>Autor:</th> <td><input name="autor" type="text" value="<%= libro.getAutor () %>"></td> </tr> <tr> <th>Categoría:</th> <td><input name="categoria" type="text" value="<%= libro.getCategoria () %>"></td> </tr> <tr> <th>Título:</th> <td><input name="titulo" type="text" value="<%= libro.getTitulo () %>"></td> </tr> <tr> <th>Ubicación:</th> <td><input name="ubicacion" type="text" value="<%= libro.getUbicacion () %>"></td> </tr> </table> Código Completo de la Página Form_Borrar.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería -- Borrando el Libro <%= request.getParameter ("id") %></title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Borrando el Libro <%= request.getParameter ("id") %></center></h1> <% LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id")); if (libro != null){ %> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><input name="isbn" type="text" value="<%= libro.getIsbn () %>"></td> </tr> <tr> <th>Editorial:</th> <td><input name="editorial" type="text" value="<%= libro.getEditorial() %>"></td> </tr> <tr> <th>Autor:</th> <td><input name="autor" type="text" value="<%= libro.getAutor () %>"></td> </tr> <tr> <th>Categoría:</th> <td><input name="categoria" type="text" value="<%= libro.getCategoria () %>"></td> </tr> <tr> <th>Título:</th> <td><input name="titulo" type="text" value="<%= libro.getTitulo () %>"></td> </tr> <tr> <th>Ubicación:</th> <td><input name="ubicacion" type="text" value="<%= libro.getUbicacion () %>"></td> </tr> </table> <br> <center> <destacar><a href="Borrar.jsp?id=<%= libro.getId () %>">Borrar el libro <%= request.getParameter ("id") %></a></destacar> </center> <% } else { %> <center> <h2><font color="#cc0000">No se pudo encontrar el libro <%= request.getParameter ("id") %></font></h2> </center> <% } %> <hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial [el libro no se borrará]</a></destacar> </center> </body> </html> Borrar.jsp Esta página lee el libro cuyo id se le ha pasado. Luego muestra los datos del libro en una tabla, intenta borrar el libro de la base de datos, y muestra el éxito o el fracaso del intento. Propósito de la Página Borrar.jsp El propósito de esta página es producir una página web con una tabla que muestra el libro cuyo parámetro id se ha pasado a esta página desde Form_Borrar.jsp; realmente realiza la actualización en la base de datos; muestra si la base de datos se ha actualizado con éxito o no; y espera hasta que el usuario seleccione el enlace de vuelta a la página Index.jsp. En la siguiente figura puedes ver un ejemplo de la página Borrar.jsp: Crear el Aspecto de la Página Borrar.jsp Este código HTML genera el aspecto de la página con un enlace a Index.jsp en la parte inferior de la página: <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería -- Borrando un Libro</title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Borrando el Libro <%= request.getParameter ("id") %></center></h1> -- aquí se recuperan los datos del libro a borrar --- aquí se muestra la tabla de datos --- aquí va el código que actualiza la base de datos y se muestra el éxito o el fracaso de la operación -<hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial</a></destacar> </center> </body> </html> Recuperar los Datos del libro a Borrar Este código Java recupera el ejemplar de libreria.LibrosBD almacenado en el atributo BaseDatos de la aplicación web por libreria.ContextListener: LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Luego obtiene de la base de datos el libro cuyo id se ha pasado como parámetro a esta página desde Form_Borrar.jsp: Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id")); Mostar la Tabla Este código HTML mezclado con código Java muestra la tabla; en la columna izquierda se muestran los nombres de los campos; la columna derecha contiene los datos del libro a borrar recuperados de la base de datos: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><%= libro.getIsbn() %></td> </tr> <tr> <th>Editorial:</th> <td><%= libro.getEditorial() %></td> </tr> <tr> <th>Autor:</th> <td><%= libro.getAutor() %></td> </tr> <tr> <th>Categoría:</th> <td><%= libro.getCategoria() %></td> </tr> <tr> <th>Título:</th> <td><%= libro.getTitulo() %></td> </tr> <tr> <th>Ubicación:</th> <td><%= libro.getUbicacion() %></td> </tr> </table> Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Este código Java mezclado con código HTML borra el libro cuyo parámetro id se le ha pasado como parámetro: int rowsAffected = librosBD.borrarLibro (request.getParameter ("id")); Si sólo se ve afectada una fila en la actualización de la base de datos se muestra en verde el mensaje "Se ha borrado el libro nnn"; si no es así, se muestra en rojo el mensaje "No se pudo borrar el libro nnn": if (rowsAffected == 1) { %> <center> <h2><font color="#00cc00">Se ha Borrado el Libro <%= request.getParameter ("id") %></font></h2> </center> <% } else { %> <center> <h2><font color="#cc0000">No se pudo borrar el libro <%= request.getParameter ("id") %></font></h2> </center> <% } Código Completo de la Página Borrar.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería -- Borrando un Libro</title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Borrando el Libro <%= request.getParameter ("id") %></center></h1> <% LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id")); if (libro != null){ %> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><%= libro.getIsbn() %></td> </tr> <tr> <th>Editorial:</th> <td><%= libro.getEditorial() %></td> </tr> <tr> <th>Autor:</th> <td><%= libro.getAutor() %></td> </tr> <tr> <th>Categoría:</th> <td><%= libro.getCategoria() %></td> </tr> <tr> <th>Título:</th> <td><%= libro.getTitulo() %></td> </tr> <tr> <th>Ubicación:</th> <td><%= libro.getUbicacion() %></td> </tr> </table> <% int rowsAffected = librosBD.borrarLibro (request.getParameter ("id")); if (rowsAffected == 1) { %> <center> <h2><font color="#00cc00">Se ha borrado el libro <%= request.getParameter ("id") %></font></h2> </center> <% } else { %> <center> <h2><font color="#cc0000">No se pudo borrar el libro <%= request.getParameter ("id") %></font></h2> </center> <% } } else { %> <center> <h2><font color="#cc0000">No se encontró el libro <%= request.getParameter ("id") %></font></h2> </center> <% } %> <hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial</a></destacar> </center> </body> </html> Modificar un Registro de la Base de Datos o Form_Modificar.jsp Propósito de la Página Form_Modificar.jsp Crear el Aspecto de la Página Form_Modificar.jsp Recuperar los Datos del libro a Modificar Mostrar el Formulario Código Completo de la Página Form_Modificar.jsp o Modificar.jsp Propósito de la Página Modificar.jsp Aspecto de la Página Modificar.jsp Mostrar la Tabla Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Código Completo de la Página Modificar.jsp Modificar un Registro de la Base de Datos Form_Modificar.jsp Form_Modificar.jsp muestra un formulario HTML con los valores actuales del libro. También tiene un botón para enviar el formulario y un enlace para abortar la solicitud. Propósito de la Página Form_Modificar.jsp El propósito de esta página es producir una página web que muestre los datos del libro a modificar. El usuario podría o modificar los datos del formulario y enviar el formulario para su procesamiento transfiriendo el control a la página Modificar.jsp o abortar el proceso seleccionando un enlace de vuelta a la página Index.jsp. La siguiente imagen nos muestra un ejemplo de la página Form_Modificar.jsp: Crear el Aspecto de la Página Form_Modificar.jsp Este código HTML crea el aspecto de la página con un enlace en la parte inferior hacia la página Index.jsp etiquetado como "Volver a la Página Inicial [el libro no se modificará]". <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería -- Modificando el Libro <%= request.getParameter ("id") %></title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Modificando el Libro <%= request.getParameter ("id") %></center></h1> -- aquí va el código que recupera el libro a modificar --- aquí va el código para mostrar el formulario -<hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial [el libro no se modificará]</a></destacar> </center> </body> </html> Recuperar los Datos del libro a Modificar Este código Java recupera el ejemplar de libreria.LibrosBD almacenado en el atributo BaseDatos de la aplicación web por libreria.ContextListener: LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Luego obtiene de la base de datos el libro cuyo id se ha pasado como parámetro a esta página desde Index.jsp: Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id")); Mostrar el Formulario Este código HTML mezclado con código Java crea un formulario cuya acción es "postear" los datos modificados del libro que hay en los campos de entrada a la página Modificar.jsp: <form method="post" action="Modificar.jsp"> Uno de estos campos es un campo oculto que contiene el id del libro a modificar -- esto nos asegura que el parámetro id pasado desde la página Index.jsp se pasa a la página Modificar.jsp. <input name="id" type="hidden" value="<%= libro.getId () %>"> Luego se muestra una tabla; en la columna izquierda de la tabla se muestran los nombres de los campos; la columna derecha contiene los campos de entrada pre-rellenos con los datos existentes: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><input name="isbn" type="text" value="<%= libro.getIsbn () %>"></td> </tr> <tr> <th>Editorial:</th> <td><input name="editorial" type="text" value="<%= libro.getEditorial() %>"></td> </tr> <tr> <th>Autor:</th> <td><input name="autor" type="text" value="<%= libro.getAutor () %>"></td> </tr> <tr> <th>Categoría:</th> <td><input name="categoria" type="text" value="<%= libro.getCategoria () %>"></td> </tr> <tr> <th>Título:</th> <td><input name="titulo" type="text" value="<%= libro.getTitulo () %>"></td> </tr> <tr> <th>Ubicación:</th> <td><input name="ubicacion" type="text" value="<%= libro.getUbicacion () %>"></td> </tr> </table> Luego se define un campo oculto que simula la pulsación del botón submit cuando se pulsa la tecla return: <input name="pagemode" type="hidden" value="submit"> Luego se muestra el botón de envío del formulario etiquetado "Modificar el Libro nnn": <input align="center" type="submit" value="Modificar el Libro <%= request.getParameter ("id")%>"> Cuando se pulsa el botón de envío, se pasan los parámetros isbn, editorial, autor, categoria, titulo y ubicacion a la página Modificar.jsp Código Completo de la Página Form_Modificar.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería -- Modificando el Libro <%= request.getParameter ("id") %></title> </head> <body bgcolor="#ffffee"> <h1><center>Librería -- Modificando el Libro <%= request.getParameter ("id") %></center></h1> <% LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id")); if (libro != null){ %> <form method="post" action="Modificar.jsp"> <input name="id" type="hidden" value="<%= libro.getId () %>"> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><input name="isbn" type="text" value="<%= libro.getIsbn () %>"></td> </tr> <tr> <th>Editorial:</th> <td><input name="editorial" type="text" value="<%= libro.getEditorial() %>"></td> </tr> <tr> <th>Autor:</th> <td><input name="autor" type="text" value="<%= libro.getAutor () %>"></td> </tr> <tr> <th>Categoría:</th> <td><input name="categoria" type="text" value="<%= libro.getCategoria () %>"></td> </tr> <tr> <th>Título:</th> <td><input name="titulo" type="text" value="<%= libro.getTitulo () %>"></td> </tr> <tr> <th>Ubicación:</th> <td><input name="ubicacion" type="text" value="<%= libro.getUbicacion () %>"></td> </tr> </table> <br> <center> <input name="pagemode" type="hidden" value="submit"> <input align="center" type="submit" value="Modificar el Libro <%= request.getParameter ("id") %>"> </center> <% } else { %> <center> <h2><font color="#cc0000">No se pudo encontrar el libro <%= request.getParameter ("id") %></font></h2> </center> <% } %> <hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial [el libro no se modificará]</a></destacar> </center> </body> </html> Modificar.jsp Modificar.jsp muestra en una tabla los campos modificados del libro recibido. Luego intenta modificar la base de datos y muestra el éxito o el fracaso del intento. Propósito de la Página Modificar.jsp El propósito de esta página es producir una página web con una tabla que muestre los parámetros del libro pasados desde la página Form_Modificar.jsp; realmente realiza la actualización de la base de datos; muestra si la base de datos se ha actualizado con éxito o no; y espera hasta que el usuario pulse el enlace de vuelta a la página Index.jsp. Aquí tenemos un ejemplo de la página Modificar.jsp: Aspecto de la Página Modificar.jsp Este código HTML genera el aspecto de la página con un enlace a Index.jsp en la parte inferior de la página: <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería: Modificando el Libro <%= request.getParameter ("id") %></title> </head> <body bgcolor="#ffffee"> <h1><center>Librería: Modificando el Libro <%= request.getParameter ("id") %></center></h1> -- aquí va el código que muestra la tabla --- aquí va el código que actualiza la base de datos y muestra el éxito o el fracaso de la operación -<center> <destacar><a href="Index.jsp">Volver a la Página Inicial</a></destacar> </center> </body> </html> Mostrar la Tabla Este código HTML mezclado con código Java muestra la tabla; en la columna izquierda se muestran los nombres de los campos; la columna derecha contiene los datos del libro recuperados de los parámetros: <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><%= request.getParameter ("isbn") %></td> </tr> <tr> <th>Editorial:</th> <td><%= request.getParameter ("editorial") %></td> </tr> <tr> <th>Autor:</th> <td><%= request.getParameter ("autor") %></td> </tr> <tr> <th>Categoría:</th> <td><%= request.getParameter ("categoria") %></td> </tr> <tr> <th>Título:</th> <td><%= request.getParameter ("titulo") %></td> </tr> <tr> <th>Ubicación:</th> <td><%= request.getParameter ("ubicacion") %></td> </tr> </table> Actualizar la Base de Datos y Mostrar el Éxito o el Fracaso Este código Java mezclado con código HTML recupera el ejemplar de libreria.LibrosBD almacenado en el atributo BaseDatos de la aplicación por libreria.ContextListener: LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Esto construye un objeto Libro desde los parámetros pasados desde Form_Modificar.jsp: Libro libro = new Libro request.getParameter request.getParameter request.getParameter request.getParameter request.getParameter request.getParameter request.getParameter ); ( ("id"), ("isbn"), ("editorial"), ("autor"), ("categoria"), ("titulo"), ("ubicacion") Luego se modifica el libro en la base de datos: int rowsAffected = librosBD.modificarLibro (libro); Si sólo se ve afectada una fila por la actualización de la base de datos se muestra el mensaje "Se ha modificado el Libro nnn" en color verde, si no es así, se muestra el mensaje "No se pudo modificar el libro nnn" en color rojo: if (rowsAffected == 1) { %> <center> <h2><font color="#00cc00">Se ha modificado el Libro <%= request.getParameter ("id") %></font></h2> </center> <% } else { %> <center> <h2><font color="#cc0000">No se Pudo modificar el Libro <%= request.getParameter ("id") %></font></h2> </center> <% } Código Completo de la Página Modificar.jsp <%@ page language="java" import="java.util.*, libreria.*" %> <html> <head> <title>Librería: Modificando el Libro <%= request.getParameter ("id") %></title> </head> <body bgcolor="#ffffee"> <h1><center>Librería: Modificando el Libro <%= request.getParameter ("id") %></center></h1> <table align="center" cellpadding="2" cellspacing="2" border="1" width="80%" bgcolor="#dddddd"> <tr> <th>ISBN:</th> <td><%= request.getParameter ("isbn") %></td> </tr> <tr> <th>Editorial:</th> <td><%= request.getParameter ("editorial") %></td> </tr> <tr> <th>Autor:</th> <td><%= request.getParameter ("autor") %></td> </tr> <tr> <th>Categoría:</th> <td><%= request.getParameter ("categoria") %></td> </tr> <tr> <th>Título:</th> <td><%= request.getParameter ("titulo") %></td> </tr> <tr> <th>Ubicación:</th> <td><%= request.getParameter ("ubicacion") %></td> </tr> </table> <% LibrosBD librosBD = (LibrosBD) application.getAttribute ("BaseDatos"); Libro libro = new Libro ( request.getParameter ("id"), request.getParameter ("isbn"), request.getParameter ("editorial"), request.getParameter ("autor"), request.getParameter ("categoria"), request.getParameter ("titulo"), request.getParameter ("ubicacion") ); int rowsAffected = librosBD.modificarLibro(libro); if (rowsAffected == 1) { %> <center> <h2><font color="#00cc00">Se ha modificado el Libro <%= request.getParameter ("id") %></font></h2> </center> <% } else { %> <center> <h2><font color="#cc0000">No se pudo modificar el Libro <%= request.getParameter ("id") %></font></h2> </center> <% } %> <hr> <center> <destacar><a href="Index.jsp">Volver a la Página Inicial</a></destacar> </center> </body> </html> Ficheros de Configuración o Libreria/WEB-INF/web.xml Propósito del Fichero web.xml Código Fuente Completo del Fichero web.xml o Libreria.xml Propósito del Fichero Libreria.xml Definición de Logger Definición del DataSource Parámetros de la Base de Datos Parámetros del Repositorio de Conexiones Código Fuente Completo del fichero Libreria.xml Ficheros de Configuración Ya estamos listos para crear los ficheros de configuración de nuestra aplicación Librería : Libreria/WEB-INF/web.xml Libreria/WEB-INF/web.xml es el descriptor de despliegue para la aplicación Web. Contiene dos parámetros clave. El parámetro listener identifica la clase Java del oyente libreria.ContextListener, al que se llamará durante la arrancada y parada de la aplicación. <listener> <listener-class>listener.ContextListener</listener-class> </listener> El parámetro welcome-file-list controla el punto de entrada a la aplicación. El siguiente código selecciona la página Index.jsp como único punto de entrada a la aplicación Librería: <welcome-file-list> <welcome-file>Index.jsp</welcome-file> </welcome-file-list> Propósito del Fichero web.xml Es el descriptor de despliegue de la aplicación y está contenido en el directorio WEB-INF. Define varios parámetros que son usados cuando se despliega la aplicación en el contenedor de Servlets/JSP Tomcat. display-name Configura el nombre de la aplicación web que se mostrará en los listados de Tomcat. La siguiente línea selecciona este parámetro de la aplicación Libreria como "Aplicación Web de Libreria": <display-name>Aplicación Web de Libreria</display-name> description Configura la descripción de la aplicación Web. La siguiente línea selecciona la descripción de la aplicación Libreria como "Esta aplicación mantiene una base de datos de libros.": <description>Esta aplicación mantiene una base de datos de libros.</description> listener Configura la aplicación web para que se ejecute un oyente de contexto servlet cuando se arranque o se pare la propia aplicación Web. Las siguiente líneas seleccionan que el oyente de contexto servlet de la aplicación Librería sea libreria.ContextListener <listener> <listener-class>libreria.ContextListener</listener-class> </listener> welcome-file-list Configura el punto de entrada a la aplicación web. Las preferencias por defecto para este parámetro se seleccionan en el fichero conf/web.xml de Tomcat. Usando nuestro editor de texto, podemos echar una mirada a la parte final de nuestro fichero conf/web.xml. Deberíamos ver algo como esto: <!-<!-<!-<!-<!-<!-<!-<!-<!-<!-<!-- ==================== Default Welcome File List ===================== When a request URI refers to a directory, the default servlet looks for a "welcome file" within that directory and, if present, to the corresponding resource URI for display. If no welcome file is present, the default servlet either serves a directory listing, or returns a 404 status, depending on how it is configured. If you define welcome files in your own application's web.xml deployment descriptor, that list *replaces* the list configured here, so be sure that you include any of the default values that you wish to include. --> --> --> --> --> --> --> --> --> --> --> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>Home.jsp</welcome-file> </welcome-file-list> Es posible realizar cambios globales en nuestra configuración de Tomcat modificando el fichero conf/web.xml, pero no recomiendo hacerlo. Es mucho mejor seleccionar las preferencias en el parámetro welcome-file-list de la propia aplicación. Las siguiente líneas seleccionan el punto de entrada de la aplicación Librería como Index.jsp <welcome-file-list> <welcome-file>Index.jsp</welcome-file> </welcome-file-list> Código Fuente Completo del Fichero web.xml <?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>Aplicación Web de Libreria</display-name> <description>Esta aplicación mantiene una base de datos de libros.</description> <listener> <listener-class>libreria.ContextListener</listener-class> </listener> <welcome-file-list> <welcome-file>Index.jsp</welcome-file> </welcome-file-list> </web-app> Libreria.xml Propósito del Fichero Libreria.xml El fichero Libreria.xml contiene los detalles del "contexto" de la aplicación Libreria, es decir, los parámetros que Tomcat usará cuando ejecute la aplicación, entre ellos la definición del DataSource a utilizar, o el tipo de "Log" que va a tener esta aplicación, por ejemplo. Este código define el path de contexto, el documento base, el nivel de depuración, el marcador de recargable, y el marcador de contexto cruzado: <Context path="/Libreria" docBase="Libreria" debug="1" reloadable="true" crossContext="true"> ... Aquí va la definición del Logger ... ... Aquí va la definición del DataSource ... </Context> Lo más importante a observar en este trozo de código son los atributos path y docBase, pero veamos una breve descripción de cada uno de ellos. path indica el path que utilizaremos para acceder a nuestra aplicación una vez instalada en Tomcat y formará parte de la URI para acceder a la aplicación desde nuestro navegador, por ejemplo http://localhost:8080/Libreria en nuestro caso. docBase también conocido como Raíz del Documento se utiliza para indicar el directorio donde van a residir los ficheros de la aplicación cuyo contexto estamos configurando. Nota: Si nuestra aplicación se encuentra empaquetada en un fichero WAR, en el atributo docBase deberemos poner el path completo del fichero .war. debug indica el nivel de log de esta aplicación, cuando mayor sea el número que pongamos aquí, mayor será el nivel de detalle que veremos en los ficheros de log. reloadable especifica si queremos que Tomcat monitorice cada cierto tiempo las clases de esta aplicación para ver si han cambiado, pero debemos tener en cuenta que esta operación consume muchos recursos y que puede ser muy útil para entornos de prueba pero puede ser una mala idea para entornos de producción. crossContext indica si queremos que las llamadas a ServletContext.getContext() dentro de esta aplicación sobre otras aplicaciones Web que se ejecuten en el mismo host virtual devuelvan siempre un request dispatcher válido. En entornos de alta seguridad se puede seleccionar a false para hacer que getContext() siempre devuelva null. Hay muchos otros atributos del elemento context, podrás encontrar más información sobre ellos en el fichero Context.html que viene en la documentación de Tomcat, en el directorio C:\Archivos de programa\Apache Group\Tomcat 4.1\webapps\tomcat-docs\config\ Definición de Logger Este código define un objeto Logger como una clase org.apache.catalina.logger.FileLogger. En el directorio logs de Tomcat se creará un fichero log llamado localhost_Libreria_log.YYYY-MMDD.txt donde YYYY-MM-DD es la fecha del log: <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_Libfreria_log." suffix=".txt" timestamp="true"/> Definición del DataSource Este código define un Resource llamado jdbc/biblioteca como una clase javax.sql.DataSource: <Resource name="jdbc/biblioteca" auth="Container" type="javax.sql.DataSource"/> Este código define el ResourceParams llamado jdbc/biblioteca como una clase org.apache.commons.dbcp.BasicDataSourceFactory: <ResourceParams name="jdbc/biblioteca"> <parameter> <name>factory</name> <value>org.apache.commons.dbcp.BasicDataSourceFactory</value> </parameter> ... aquí van los parámetros de la base de datos ... ... aquí van los parámetros del Repositorio de Conexiones ... </ResourceParams> Parámetros de la Base de Datos url La URL de la base de datos url = jdbc:mysql://localhost:1306/biblioteca?autoReconnect=true. Por defecto, MySQL cierra las conexión inactivas después de 8 horas. Si esto sucede, usando autoReconnect=true se hará que Tomcat se reconecte automáticamente. Otras bases de datos podrían funcionar de forma diferente: <parameter> <name>url</name> <value>jdbc:mysql://localhost:1306/biblioteca?autoReconnect=true</value> </parameter> driverClassName El nombre de la clase del driver JDBC, driverClassName = org.gjt.mm.mysql.Driver que es el nombre de la clase para el driver MySQL Connector/J JDBC . <parameter> <name>driverClassName</name> <value>org.gjt.mm.mysql.Driver</value> </parameter> Nota: Recuerda que debes situar el fichero JAR mysql-connector-java-2.0.14-bin.jar en el directorio ..\common\lib de Tomcat. username El nombre de usuario para acceder a la base de datos MySQL username = mysqlusername. <parameter> <name>username</name> <value>mysqlusername</value> </parameter> password La password MySQL para acceder a la base de datos, password = mysqlpassword. <parameter> <name>password</name> <value>mysqlpassword</value> </parameter> Parámetros del Repositorio de Conexiones maxActive El número máximo de conexiones en el repositorio, maxActive = 100. Seleccionamos maxActive = 0 para que no haya limite. Debemos asegurarnos de configurar max_connections lo suficientemente grande para manejar todas las conexiones a nuestra base de datos. <parameter> <name>maxActive</name> <value>100</value> </parameter> maxIdle El número máximo de conexiones inactivas a retener en el repositorio, maxIdle = 30. Seleccionamos maxIdle = 0 para que no haya límite. <parameter> <name>maxIdle</name> <value>30</value> </parameter> maxWait El tiempo máximo a esperar para obtener una conexión disponible [en milisegundos], maxWait = 10000. Seleccionamos maxWait = -1 para esperar indefinidamente. Si hay un timeout, se lanza una Exception. <parameter> <name>maxWait</name> <value>10000</value> </parameter> removeAbandoned Si removeAbandoned = true entonces cuando haya pocas conexiones disponibles en el repositorio de conexiones se recuperará y reciclará cualquier conexión abandonada que se encuentre. El valor por defecto es removeAbandoned = false. <parameter> <name>removeAbandoned</name> <value>true</value> </parameter> removeAbandonedTimeout El número de segundos que una conexión tiene que estar inactiva hasta que sea considerada abandonada por el repositorio de conexiones. removeAbandonedTimeout = 300 es el tiempo por defecto. <parameter> <name>removeAbandonedTimeout</name> <value>300</value> </parameter> logAbandoned Si logAbandoned = true el repositorio de conexiones guardará un seguimiento de pila del código que abandonó un recurso de conexión. <parameter> <name>logAbandoned</name> <value>true</value> </parameter> Código Fuente Completo del fichero Libreria.xml <Context path="/Libreria" docBase="Libreria" debug="1" reloadable="true" crossContext="true"> <Logger className="org.apache.catalina.logger.FileLogger" prefix="localhost_Libreria_log." suffix=".txt" timestamp="true"/> <Resource name="jdbc/biblioteca" auth="Container" type="javax.sql.DataSource"/> <ResourceParams name="jdbc/biblioteca"> <parameter> <name>factory</name> <value>org.apache.commons.dbcp.BasicDataSourceFactory</value> </parameter> <parameter> <name>url</name> <value>jdbc:mysql://localhost:1306/biblioteca?autoReconnect=true</value> </parameter> <parameter> <name>driverClassName</name> <value>org.gjt.mm.mysql.Driver</value> </parameter> <parameter> <name>username</name> <value>mysqlusername</value> </parameter> <parameter> <name>password</name> <value>mysqlpassword</value> </parameter> <parameter> <name>maxActive</name> <value>100</value> </parameter> <parameter> <name>maxIdle</name> <value>30</value> </parameter> <parameter> <name>maxWait</name> <value>10000</value> </parameter> <parameter> <name>removeAbandoned</name> <value>true</value> </parameter> <parameter> <name>removeAbandonedTimeout</name> <value>300</value> </parameter> <parameter> <name>logAbandoned</name> <value>true</value> </parameter> </ResourceParams> </Context> Desplegar y Ejecutar la Aplicación o Desplegar la Aplicación o Ejecutar la Aplicación Desplegar y Ejecutar la Aplicación Desplegar la Aplicación Descarga el fichero Libreria.zip que debe tener el siguiente contenido: Descomprime el fichero Librería.zip en el directorio \webapps de tu instalación de Tomcat. Aségurate de que en el directorio \webapps además del directorio \Libreria tienes el fichero Libreria.xml. Este debería ser el aspecto del despliegue de tu aplicación: C:\tomcat 4.1\ | -> webapps\ | |- Libreria.xml -> Libreria\ | |- Borrar.jsp |- Form_Borrar.jsp |- Form_Insertar.jsp ||||-> Form_Modificar.jsp Index.jsp Insertar.jsp Modificar.jsp WEB-INF\ | |- web.xml -> classes\ | -> libreria\ | |- ContextListener.class |- Libro.class |- LibosBD.class Modifica el fichero Libreria.xml para adecuar la URL de la base de datos a la de tu máquina, además del nombre de usuario y la password que utilizas para acceder a MySQL. Ejecutar la Aplicación Antes de ejecutar la aplicación debes asegurarte de que has seguido los pasos indicados en la sección Crear la Tabla Libros en la Base de Datos. Ahora solo queda arrancar Tomcat de la forma habitual, dirigir tu navegador favorito a la dirección http://localhost:8080/Libreria/Index.jsp, y deberías ver la pantalla inicial de la aplicación: Ahora ya puedes empezar a insertar, borrar y modificar registros.