Está en la página 1de 60

Crear tu Primera Aplicacin Web Real con Tomcat 4 y

MySQL

Qu Tecnologas Utilizar?

Qu Tecnologas Utilizar?
Hemos decidido utilizar las tecnologas del contenedor Servlet/JSP Tomcat 4 para implementar
una aplicacin Web. Esto todava tiene muchas opciones, y elegir entre las distintas tecnologas
disponibles no es fcil. Para este curso, hemos decidido dejarlo lo ms simple posible y utilizar
Java Server Pages (JSPs) en combinacin con clases Java.
Deberamos evitar la utilizacin de JSPs para implementar lgica compleja; dichas aplicaciones
pueden ser divertidas de escribir, pero puede ser frustrante su depuracin y casi imposible de
entender y mantener. Una solucin realmente buena es usar JSPs para manejar la presentacin
de la pgina web (porque para esto son buenas las JSPs), y Java para implementar la lgica
compleja, como el acceso a bases de datos. De esta forma, el software ser fcil de escribir y de
depurar, y posteriormente el cdigo ser sencillo de entender y de mantener.
La aplicacin 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 versin reciente del Contenedor Servlet/JSP Tomcat (versin 4 o superior).
Todos estos paquetes estn disponibles en Internet de forma gratuita.
La aplicacin Web tambin requiere una base de datos. Servir casi cualquier base de datos
relacional, si acepta SQL y tiene un driver JDBC. MySQL tiene buena reputacin y se ajusta a
nuestro presupuesto perfectamente. Podemos obtener la ltima versin de MySQL y su
driverConnector/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
Crear la Tabla Libros en la Base de Datos

Configurar la base de datos depende del software de base de datos que estemos utilizando.
Necesitars 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 numrico que se incrementa automticamente.

isbn, un campo de 13 caracteres que contiene el cdigo 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 categora a la que pertenece el


libro.

titulo, un campo de 50 caracteres que contiene el ttulo del libro.

ubicacion, un campo de 5 caracteres en el ubicacin actual del libro en nuestro sistema


de estanteras.
Configuremos la base de datos MySQL. Primero arrancamos la Base de Datos utilizado la lnea 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 configuracin de la tabla, ejecutamos el comando describe
Deberamos 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", "Informtica", "La Biblia de Java", "AB-14");
mysql> select * from Libros;
Esto debera producir la siguiente salida:

Libros;.

Observa que a la id del libro se le ha asignado automticamente un valor de 1.


La base de datos ya est lista para su utilizacin.
Las Clases Java de la Aplicacin
La aplicacin Web utilizada para demostrar las tecnologas usadas en este tutorial es una simple
aplicacin de control de una librera (solo control y ubicacin de los libros, no hay facturacin,
por ejemplo), llamada Libreria . No es el propsito de este tutorial crear una aplicacin
completa, es slo un ejemplo.
Libreria tiene tres clases Java:

libreria.ContextListener es un oyente del contexto servlet al que Tomcat llamar


cuando inicie y detenga la aplicacin Libreria. Esta clase crea un objeto de la
claseLibrosBD 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 conexin a la base de datos (utilizando el objeto LibrosBD que se
obtiene del atributo de contexto BaseDatos), y la sesin se puede compartir entre varias
sesiones web. La clase proporciona varios mtodos 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 pginas JSP de la aplicacin
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 aplicacin Libreria. Esto se configura en el descriptor de
despliegue de la aplicacin web.xml. Cuando se arranca la aplicacin Libreria se crea un
ejemplar de la clase LibrosBD y se almacena como un atributo de contexto; cuando se cierra la
aplicacin, el objeto LibrosBD se recupera del atributo de contexto y se cierra la conexin 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.
Propsito de la clase ContextListener
El
propsito
de
la
clase
Java libreria.ContextListener es
crear
un
ejemplar
delibreria.LibrosBD y almacenarlo como un atributo del contexto servlet identificado
como:"BaseDatos".
Esto
permitir
a
las
pginas
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.
Mtodos de la clase ContextListener

contextInitialized
Se llama a contextInitialized siempre que la aplicacin 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 excepcin 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 aplicacin 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");
Cdigo 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 conexin a la base de datos, y la sesin se puede compartir entre varias sesiones
web. La clase proporciona varios mtodos de acceso a la base de datos.
Propsito de la clase LibrosBD
El propsito de la clase libreria.LibrosBD es establecer una conexin a la base de datos
pblica y proporcionar mtodos para acceder de forma segura y actualizar la
tabla Libroscontenida en la base de datos sin conflictos con otros usuarios que estn
accediendo a los mismos datos.
Slo hay una conexin a la base de datos que es compartida por todos los usuarios de la
aplicacin Web Libreria. Esto es adecuado mientras el nmero de usuarios concurrentes no sea
excesivo. Vamos a mantenerlo lo ms simple posible, slo debemos aadir 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.

Mtodos de la Clase LibrosBD

Constructor de LibrosBD:
Establece una conexin a la base de datos pblica.
Hasta hace poco, si queramos establecer una conexin a una base de datos desde un
Servlet bajo Tomcat tenamos 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 informacin en el cdigo fuente de la aplicacin. Tomcat 4
resuelve este problema permitiendo al Servlet acceder a Tomcat y recuperar una conexin
desde el DataSource que se define en el fichero Libreria.xml, como veremos ms
adelante.
Primero se recupera el javax.naming.InitialContext para que se pueda realizar una
bsqueda JNDI:
InitialContext initialContext = new InitialContext ();
Despus se recupera el contexto de la aplicacin 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 conexin desde el DataSource:
this.connection = dataSource.getConnection ();
Todos
los
parmetros
del DataSource tenemos
que
definirlos
en
el
ficheroLibreria.xml (que veremos ms adelante), aunque tambin se pueden modificar
usando
las
facilidades
de
administracin
de
Tomcat,
con
la
direccinhttp://localhost:8080/admin .
getConnection
Se utilizan los mtodos getConnection y releaseConnection para asegurarse de que la
conexin a la base de datos se puede compartir de forma segura, el recurso de la conexin
se controla utilizando los mtodos sincronizados getConnection yreleaseConnection.
Primero getConnection espera hasta que se libera la conexin:
while (this.connectionFree == false) {
try {
wait ();
}
catch (InterruptedException e) {
}
}
Luego marca el indicador de conexin libre como no libre, as bloquea la conexin hasta que
se llame a releaseConnection:
this.connectionFree = false;
Luego se lo notifica a cualquier otro thread de LibrosBD que est esperando una conexin:
notify ();
Finalmente devuelve la conexin:
return this.connection;
releaseConnection
Primero espera hasta que la conexin est ocupada:
while (this.connectionFree == true) {
try {
wait ();
}
catch (InterruptedException e) {
}
}
Luego selecciona el indicador de conexin libre a libre, as desbloquea la conexin hasta
que se llame a getConnection:
this.connectionFree = true;
Finalmente se lo notifica a cualquier otro thread de LibrosBD que est esperando una
conexin:
notify ();
Todas
las
dems
rutinas
que
acceden
a
la
base
de
datos
emplean getConnection yreleaseConnection, para que slo pueda acceder a la base de
datos un thread a la vez.
getLibro

//
//
//

El mtodo getLibro toma un parmetro id y devuelve el Libro para ese id; si no se puede
encontrar ese id se devuelve un Libro null.
getLibro primero obtiene una conexin libre
this.getConnection ();
Luego crea una sentencia select, e inserta el id en la posicin 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 conexin 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 conexin, y se
devuelve un objeto Libro null:
else {
preparedStatement.close ();
this.releaseConnection ();
return null;
}
insertarLibro, borrarLibro, modificarLibro, y obtenerLibros
Todos estos mtodos utilizan una tcnica similar a la del mtodo getLibro
close
close simplemente cierra la conexin:
this.connection.close ();
Cdigo Fuente Completo de la clase LibrosBD

LibrosBD.java

package libreria;
import
import
import
import

java.sql.*;
java.util.*;
javax.sql.*;
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
todava son una buena idea cuando se programan JSPs, por eso esta clase es una buena idea
para la aplicacin Libreria.
El constructor de libreria.Libro almacena los campos del libro en el objeto. Esta clase
tambin incluye los habituales mtodos 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()
Propsito de la clase Libros

El propsito de esta clase es recolectar los datos relativos a un libro de nuestra base de datos.
Mtodos 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 ygetUbicacion
Estos mtodos devuelven los distintos campos que componente un libro.
Cdigo 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 Pginas JSP
La aplicacin Libreria tiene siete pginas JSP. Cada una representa una pgina Web que realiza
una operacin independiente sobre la base de datos. El estado de la base de datos en cada
pgina es independiente de su estado en la pgina anterior. Si la base de datos cambia debido a
una solicitud de otro usuario, la pgina 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 modificacin, la JSP nos notificar el fallo al intentar modificar un
libro que ahora no existe.
La pgina Index.jsp

Es la pgina principal de la aplicacin web Libreria, y es la primera pgina que se muestra a un


usuario cuando entra en la aplicacin 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 pgina tiene un enlace para poder aadir
nuevos libros.

El enlace Aadir un Nuevo Libro pasa el control a la pgina Form_Insertar.jsp.

El enlace Borrar pasa el control a la pgina Form_Borrar.jsp con el id del libro a borrar.

El enlace Modificar pasa el control a la pgina Form_Modificar.jsp con el id del libro a


modificar.
Propsito de la Pgina Index.jsp

El propsito de Index.jsp es producir una pgina Web con una tabla que muestre el contenido
de la tabla Libros de la base de datos, con enlaces para aadir nuevos libros a la base de datos
[Form_Insertar.jsp]; borrar libros especficos de la base de datos [Form_Borrar.jsp]; y
modificar libros especficos en la base de datos [Form_Modificar.jsp].
La siguiente figura muestra un ejemplo de la pgina principal de la aplicacin Libreria:

Aspecto de la Pgina

Este cdigo HTML dibuja el aspecto de la pgina con un enlace a Form_Insertar.jsp en la parte
inferior de la pgina
<%@ page language="java" import="java.util.*, libreria.*" %>
<html>
<head>
<title>Pgina Principal de mi Librera</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Pgina Principal de mi Librera</center></h1>
--- Aqu va el cdigo que muestra la tabla con los datos

<hr>
<center>
<destacar><a

href="Form_Insertar.jsp">Aadir

un

Nuevo

Libro</a></destacar>
</center>
</body>
</html>
Mostrar la Tabla

Este cdigo 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 cdigo que muestra los datos
</table>
Bucle por Todas las Filas de la Tabla

Este
cdigo
Java
recupera
el
ejemplar libreria.LibrosBD almacenado
en
el
atributoBaseDatos de la aplicacin 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 algn libro [es decir, su tamao 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 cdigo que muestra los datos de una fila...
}
}
}
Mostrar un Libro en un Fila de la Tabla

Este cdigo HTML mezclado con cdigo Java muestra un libro en una fila de la tabla. El cdigo
Java simplemente recupera campos individuales desde el libro:libro.getAutor() devuelve el
nombre del autor del libro; libro.getTitulo () devuelve el ttulo del libro;libro.getUbicacion
() devuelve la ubicacin del libro en nuestras estanteras; ylibro.getId () devuelve el id. En la
primera columna de la tabla va el nombre del autor; en la segunda columna va el ttulo; en la
tercera columna va la ubicacin, 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 parmetro id a la pgina Form_Borrar.jsp,
y cuando se selecciona el enlace "Modificar" se le pasa el mismo parmetro a la
pginaForm_Modificar.jsp.
Cdigo Completo de la Pgina Index.jsp

<%@ page language="java" import="java.util.*, libreria.*" %>


<html>
<head>
<title>Pgina Principal de mi Librera</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Pgina Principal de mi Librera</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">Aadir

un

Nuevo

Libro</a></destacar>
</center>
</body>
</html>

Crear tu Primera Aplicacin Web Real con Tomcat 4 y


MySQL

Insertar un Registro en la Base de Datos


Form_Insertar.jsp
Propsito de la Pgina Form_Insertar.jsp
Aspecto de la Pgina Form_Insertar.jsp
Dibujar el Formulario
Cdigo Completo de la Pgina Form_Insertar.jsp
Insertar.jsp
Propsito de la Pgina Insertar.jsp
Aspecto de la Pgina Insertar.jsp
Mostrar la Tabla
Actualizar la Base de Datos y Mostrar el xito o el Fracaso
Cdigo Completo de la Pgina 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 pgina hay en enlace para abortar la solicitud.
Propsito de la Pgina Form_Insertar.jsp

El propsito de esta pgina es producir una pgina Web con un formulario que el usuario rellena
con los datos de un libro. El usuario podra entonces enviar los datos del formulario para su
procesamiento transfiriendo el control a la pgina o abortar el proceso seleccionando un enlace
de vuelta a la pgina Index.jsp. En la siguiente figura podemos ver un ejemplo de la
pginaForm_Insertar.jsp:

Aspecto de la Pgina Form_Insertar.jsp

Este cdigo HTML crea el aspecto de la pgina con un enlace a la pgina Index.jsp, etiquetado
como "Volver a la Pgina Inicial [el libro no se aadir]" en la parte inferior de la pgina:
<%@ page language="java" import="java.util.*, libreria.*" %>
<html>
<head>
<title>Librera: Insertar un nuevo libro</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera: Insertar un nuevo libro</center></h1>
-- Aqu va el cdigo que muestra el formulario -<hr>
<center>
<destacar><a href="Index.jsp">Volver a la Pgina Inicial
[el libro no se aadir]</a></destacar>
</center>
</body>
</html>
Dibujar el Formulario

Este cdigo HTML mezclado con cdigo Java crea un formulario cuya accin es "postear" los
datos del nuevo libro que hay en los campos de entrada a la pgina :
<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>Categora:</th>
<td><input name="categoria" type="text"></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><input name="titulo" type="text"></td>
</tr>
<tr>
<th>Ubicacin:</th>
<td><input name="ubicacion" type="text"></td>
</tr>
</table>
Luego se define un campo oculto que simula la pulsacin del botn submit cuando se pulsa la
tecla return:
<input name="pagemode" type="hidden" value="submit">
Luego se muestra el botn de envo del formulario etiquetado "Aadir el nuevo libro":
<input type="submit" value="Aadir el nuevo libro">
Cuando se pulsa el botn de envo, se pasan los parmetros isbn, editorial, autor,
categoria, titulo y ubicacion a la pgina
Cdigo Completo de la Pgina Form_Insertar.jsp

<%@ page language="java" import="java.util.*, libreria.*" %>


<html>
<head>
<title>Librera: Insertar un nuevo libro</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera: 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>Categora:</th>
<td><input name="categoria" type="text"></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><input name="titulo" type="text"></td>
</tr>
<tr>
<th>Ubicacin:</th>

<td><input name="ubicacion" type="text"></td>


</tr>
</table>
<br>
<center>
<input name="pagemode" type="hidden" value="submit">
<input type="submit" value="Aadir el nuevo libro">
</center>
<hr>
<center>
<destacar><a href="Index.jsp">Volver a la Pgina Inicial
[el libro no se aadir]</a></destacar>
</center>
</body>
</html>
Insertar.jsp

Esta pgina muestra los campos que recibe del nuevo libro. Luego intenta aadir el nuevo libro a
la base de datos y muestra el xito o el fracaso en el intento. En la parte inferior de la pgina hay
un enlace a la pgina Index.jsp.
Propsito de la Pgina Insertar.jsp

El propsito de esta pgina es producir una pgina Web con un tabla que muestre los parmetros
del libro que se le han pasado desde la pgina Form_Insertar.jsp; realmente realiza la
actualizacin 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 pgina Insertar.jsp:

Aspecto de la Pgina Insertar.jsp

Este cdigo HTML genera el aspecto de la pgina con un enlace a Index.jsp en la parte inferior
de la pgina:
<html>
<head>
<title>Librera -- Insertando un nuevo Libro</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- Insertando un nuevo Libro</center></h1>
-- aqu va el cdigo para mostrar la tabla --- aqu va el cdigo para actualizar la base de datos y mostrar
el xito o el fracaso de la operacin -<hr>
<center>
<destacar><a

href="Index.jsp">Volver

la

Pgina

Inicial</a></destacar>
</center>
</body>
</html>
Mostrar la Tabla

Este cdigo HTML mezclado con cdigo 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 parmetros:
<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>Categora:</th>
<td><%= request.getParameter ("categoria") %></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><%= request.getParameter ("titulo") %></td>
</tr>
<tr>
<th>Ubicacin:</th>
<td><%= request.getParameter ("ubicacion") %></td>
</tr>
</table>
Actualizar la Base de Datos y Mostrar el xito o el Fracaso

Este
cdigo
Java
mezclado
con
cdigo
HTML
recupera
el
ejemplar
de libreria.LibrosBDalmacenado
en
el
atributo BaseDatos de
la
aplicacin
por libreria.ContextListener:
LibrosBD librosBD =
(LibrosBD) application.getAttribute ("BaseDatos");
Esto construye un objeto Libro con los parmetros pasados desde Form_Insertar.jsp:
Libro libro = new Libro (
null,
request.getParameter ("isbn"),

request.getParameter
request.getParameter
request.getParameter
request.getParameter
request.getParameter

("editorial"),
("autor"),
("categoria"),
("titulo"),
("ubicacion")

);
Luego se aade el libro a la base de datos:
int rowsAffected = librosBD.insertarLibro (libro);
Si slo se ve afectada una fila por la actualizacin de la base de datos se muestra el mensaje "Se
ha Aadido a la Base de Datos" en color verde, si no es as, se muestra el mensaje "No se
Pudo Aadir el Registro" en color rojo:
if (rowsAffected == 1) {
%>
<center>
<h2><font color="#00cc00">Se ha aadido a la Base de
Datos</font></h2>
</center>
<%
}
else {
%>
<center>
<h2><font color="#cc0000">No se ha podido Aadir el
registro</font></h2>
</center>
<%
}
%>
Cdigo Completo de la Pgina Insertar.jsp

<%@ page language="java" import="java.util.*, libreria.*" %>


<html>
<head>
<title>Librera -- Insertando un nuevo Libro</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- 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>Categora:</th>
<td><%= request.getParameter ("categoria") %></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><%= request.getParameter ("titulo") %></td>
</tr>
<tr>
<th>Ubicacin:</th>
<td><%= request.getParameter ("ubicacion") %></td>
</tr>
</table>
<%
LibrosBD librosBD = (LibrosBD) application.getAttribute
("BaseDatos");
Libro libro = new Libro (

null,
request.getParameter
request.getParameter
request.getParameter
request.getParameter
request.getParameter
request.getParameter

("isbn"),
("editorial"),
("autor"),
("categoria"),
("titulo"),
("ubicacion")

);
int rowsAffected = librosBD.insertarLibro(libro);
if (rowsAffected == 1) {
%>
<center>
<h2><font color="#00cc00">Se ha aadido a la Base de
Datos</font></h2>
</center>
<%
}
else {
%>
<center>
<h2><font color="#cc0000">No se ha podido Aadir el
registro</font></h2>
</center>
<%
}
%>
<hr>
<center>
<destacar><a

href="Index.jsp">Volver

la

Pgina

Inicial</a></destacar>
</center>
</body>
</html>

Crear tu Primera Aplicacin Web Real con Tomcat 4 y


MySQL

Borrar un Registro de la Base de Datos


Form_Borrar.jsp
Propsito de la Pgina Form_Borrar.jsp
Aspecto de la Pgina Form_Borrar.jsp
Recuperar los Datos del libro a Borrar
Mostrar la Tabla
Cdigo Completo de la Pgina Form_Borrar.jsp
Borrar.jsp
Propsito de la Pgina Borrar.jsp
Crear el Aspecto de la Pgina Borrar.jsp
Recuperar los Datos del libro a Borrar
Mostar la Tabla
Actualizar la Base de Datos y Mostrar el xito o el Fracaso
Cdigo Completo de la Pgina Borrar.jsp

Borrar un Registro de la Base de Datos


Form_Borrar.jsp

Esta pgina 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 pgina hay dos enlaces: uno para continuar con la solicitud de borrado del libro y
otro para abortar la solicitud.

Propsito de la Pgina Form_Borrar.jsp

El propsito de esta pgina es producir una pgina web con una tabla que muestre el libro que se
va a borrar. El usuario podra continuar el proceso de borrado seleccionado un enlace a la
pgina Borrar.jsp o abortar el proceso seleccionando un enlace de vuelta a Index.jsp. La
siguiente imagen muestra un ejemplo de la pgina Form_Borrar.jsp:

Aspecto de la Pgina Form_Borrar.jsp

Este cdigo HTML crea el aspecto de la pgina con un enlace a Borrar.jsp etiquetado
como"Borrar el Libro nnn" y un enlace a Index.jsp etiquetado como "Volver a la Pgina
Inicial [el libro no se borrar]", en la parte inferior de la pgina:
<%@ page language="java" import="java.util.*, libreria.*" %>
<html>
<head>
<title>Librera -- Borrando el Libro <%= request.getParameter ("id")
%></title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- Borrando el Libro <%= request.getParameter ("id")
%></center></h1>
-- aqu va el cdigo 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 Pgina 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 parmetro id al
pginaBorrar.jsp.
Recuperar los Datos del libro a Borrar

Este cdigo Java recupera el ejemplar de libreria.LibrosBD almacenado en el


atributoBaseDatos de la aplicacin 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 parmetro a esta pgina
desde Index.jsp:
Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id"));
if (libro != null){
-- aqu va el cdigo 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 cdigo HTML mezclado con cdigo 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>Categora:</th>

<td><input name="categoria" type="text" value="<%=


libro.getCategoria () %>"></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><input name="titulo" type="text" value="<%=
libro.getTitulo () %>"></td>
</tr>
<tr>
<th>Ubicacin:</th>
<td><input name="ubicacion" type="text" value="<%=
libro.getUbicacion () %>"></td>
</tr>
</table>
Cdigo Completo de la Pgina Form_Borrar.jsp

<%@ page language="java" import="java.util.*, libreria.*" %>


<html>
<head>
<title>Librera -- Borrando el Libro <%= request.getParameter ("id")
%></title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- 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>Categora:</th>
<td><input name="categoria" type="text" value="<%=
libro.getCategoria () %>"></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><input name="titulo" type="text" value="<%=
libro.getTitulo () %>"></td>
</tr>
<tr>
<th>Ubicacin:</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 Pgina Inicial
[el libro no se borrar]</a></destacar>
</center>
</body>
</html>
Borrar.jsp

Esta pgina 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.
Propsito de la Pgina Borrar.jsp

El propsito de esta pgina es producir una pgina web con una tabla que muestra el libro cuyo
parmetro id se ha pasado a esta pgina desde Form_Borrar.jsp; realmente realiza la
actualizacin 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 pgina Index.jsp. En la siguiente
figura puedes ver un ejemplo de la pgina Borrar.jsp:

Crear el Aspecto de la Pgina Borrar.jsp

Este cdigo HTML genera el aspecto de la pgina con un enlace a Index.jsp en la parte inferior
de la pgina:
<%@ page language="java" import="java.util.*, libreria.*" %>
<html>
<head>
<title>Librera -- Borrando un Libro</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- 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 cdigo que actualiza la base de datos y se
muestra el xito o el fracaso de la operacin -<hr>
<center>
<destacar><a
Inicial</a></destacar>
</center>
</body>
</html>
Recuperar los Datos del libro a Borrar

href="Index.jsp">Volver

la

Pgina

Este cdigo Java recupera el ejemplar de libreria.LibrosBD almacenado en el


atributoBaseDatos de la aplicacin 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 parmetro a esta pgina
desde Form_Borrar.jsp:
Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id"));
Mostar la Tabla

Este cdigo HTML mezclado con cdigo 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>Categora:</th>
<td><%= libro.getCategoria() %></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><%= libro.getTitulo() %></td>
</tr>
<tr>
<th>Ubicacin:</th>
<td><%= libro.getUbicacion() %></td>

</tr>
</table>
Actualizar la Base de Datos y Mostrar el xito o el Fracaso

Este cdigo Java mezclado con cdigo HTML borra el libro cuyo parmetro id se le ha pasado
como parmetro:
int rowsAffected = librosBD.borrarLibro (request.getParameter ("id"));
Si slo se ve afectada una fila en la actualizacin 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>
<%
}
Cdigo Completo de la Pgina Borrar.jsp

<%@ page language="java" import="java.util.*, libreria.*" %>


<html>
<head>
<title>Librera -- Borrando un Libro</title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- 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>Categora:</th>
<td><%= libro.getCategoria() %></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><%= libro.getTitulo() %></td>
</tr>
<tr>
<th>Ubicacin:</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

la

Pgina

Inicial</a></destacar>
</center>
</body>
</html>

Crear tu Primera Aplicacin Web Real con Tomcat 4 y


MySQL

Modificar un Registro de la Base de Datos


Form_Modificar.jsp
Propsito de la Pgina Form_Modificar.jsp
Crear el Aspecto de la Pgina Form_Modificar.jsp
Recuperar los Datos del libro a Modificar
Mostrar el Formulario
Cdigo Completo de la Pgina Form_Modificar.jsp
Modificar.jsp
Propsito de la Pgina Modificar.jsp
Aspecto de la Pgina Modificar.jsp
Mostrar la Tabla
Actualizar la Base de Datos y Mostrar el xito o el Fracaso
Cdigo Completo de la Pgina 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. Tambin
tiene un botn para enviar el formulario y un enlace para abortar la solicitud.

Propsito de la Pgina Form_Modificar.jsp

El propsito de esta pgina es producir una pgina web que muestre los datos del libro a
modificar. El usuario podra o modificar los datos del formulario y enviar el formulario para su
procesamiento transfiriendo el control a la pgina Modificar.jsp o abortar el proceso
seleccionando un enlace de vuelta a la pgina Index.jsp. La siguiente imagen nos muestra un
ejemplo de la pgina Form_Modificar.jsp:

Crear el Aspecto de la Pgina Form_Modificar.jsp

Este cdigo HTML crea el aspecto de la pgina con un enlace en la parte inferior hacia la
pginaIndex.jsp etiquetado como "Volver a la Pgina Inicial [el libro no se modificar]".
<%@ page language="java" import="java.util.*, libreria.*" %>
<html>
<head>
<title>Librera -- Modificando el Libro <%= request.getParameter ("id")
%></title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- Modificando el Libro <%= request.getParameter
("id") %></center></h1>
-- aqu va el cdigo que recupera el libro a modificar --- aqu va el cdigo para mostrar el formulario -<hr>
<center>
<destacar><a href="Index.jsp">Volver a la Pgina Inicial

[el libro no se modificar]</a></destacar>


</center>
</body>
</html>
Recuperar los Datos del libro a Modificar

Este cdigo Java recupera el ejemplar de libreria.LibrosBD almacenado en el


atributoBaseDatos de la aplicacin 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 parmetro a esta pgina
desde Index.jsp:
Libro libro = (Libro) librosBD.getLibro (request.getParameter ("id"));
Mostrar el Formulario

Este cdigo HTML mezclado con cdigo Java crea un formulario cuya accin es "postear" los
datos modificados del libro que hay en los campos de entrada a la pgina 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 parmetro id pasado desde la pgina Index.jsp se pasa a la
pginaModificar.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>Categora:</th>
<td><input name="categoria" type="text" value="<%=
libro.getCategoria () %>"></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><input name="titulo" type="text" value="<%=
libro.getTitulo () %>"></td>
</tr>
<tr>
<th>Ubicacin:</th>
<td><input name="ubicacion" type="text" value="<%=
libro.getUbicacion () %>"></td>
</tr>
</table>
Luego se define un campo oculto que simula la pulsacin del botn submit cuando se pulsa la
tecla return:
<input name="pagemode" type="hidden" value="submit">
Luego se muestra el botn de envo del formulario etiquetado "Modificar el Libro nnn":
<input align="center" type="submit" value="Modificar el Libro <%=
request.getParameter ("id")%>">
Cuando se pulsa el botn de envo, se pasan los parmetros isbn, editorial, autor,
categoria, titulo y ubicacion a la pgina Modificar.jsp

Cdigo Completo de la Pgina Form_Modificar.jsp

<%@ page language="java" import="java.util.*, libreria.*" %>


<html>
<head>
<title>Librera -- Modificando el Libro <%= request.getParameter ("id")
%></title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera -- 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>Categora:</th>
<td><input name="categoria" type="text" value="<%=
libro.getCategoria () %>"></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><input name="titulo" type="text" value="<%=
libro.getTitulo () %>"></td>
</tr>
<tr>
<th>Ubicacin:</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 Pgina 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.
Propsito de la Pgina Modificar.jsp

El propsito de esta pgina es producir una pgina web con una tabla que muestre los
parmetros del libro pasados desde la pgina Form_Modificar.jsp; realmente realiza la
actualizacin 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 pgina Index.jsp. Aqu tenemos un
ejemplo de la pgina Modificar.jsp:

Aspecto de la Pgina Modificar.jsp

Este cdigo HTML genera el aspecto de la pgina con un enlace a Index.jsp en la parte inferior
de la pgina:
<%@ page language="java" import="java.util.*, libreria.*" %>
<html>
<head>
<title>Librera: Modificando el Libro
%></title>

<%= request.getParameter ("id")

</head>
<body bgcolor="#ffffee">
<h1><center>Librera: Modificando el Libro
("id") %></center></h1>

<%= request.getParameter

-- aqu va el cdigo que muestra la tabla --- aqu va el cdigo que actualiza la base de datos y muestra
el xito o el fracaso de la operacin -<center>
<destacar><a

href="Index.jsp">Volver

la

Pgina

Inicial</a></destacar>
</center>
</body>
</html>
Mostrar la Tabla

Este cdigo HTML mezclado con cdigo 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 parmetros:
<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>Categora:</th>
<td><%= request.getParameter ("categoria") %></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><%= request.getParameter ("titulo") %></td>
</tr>
<tr>
<th>Ubicacin:</th>
<td><%= request.getParameter ("ubicacion") %></td>
</tr>
</table>
Actualizar la Base de Datos y Mostrar el xito o el Fracaso

Este
cdigo
Java
mezclado
con
cdigo
HTML
recupera
el
ejemplar
de libreria.LibrosBDalmacenado
en
el
atributo BaseDatos de
la
aplicacin
por libreria.ContextListener:
LibrosBD librosBD = (LibrosBD) application.getAttribute
("BaseDatos");
Esto construye un objeto Libro desde los parmetros pasados desde Form_Modificar.jsp:
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")
);
Luego se modifica el libro en la base de datos:
int rowsAffected = librosBD.modificarLibro (libro);

Si slo se ve afectada una fila por la actualizacin 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>
<%
}
Cdigo Completo de la Pgina Modificar.jsp

<%@ page language="java" import="java.util.*, libreria.*" %>


<html>
<head>
<title>Librera: Modificando el Libro <%= request.getParameter ("id")
%></title>
</head>
<body bgcolor="#ffffee">
<h1><center>Librera: 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>Categora:</th>
<td><%= request.getParameter ("categoria") %></td>
</tr>
<tr>
<th>Ttulo:</th>
<td><%= request.getParameter ("titulo") %></td>
</tr>
<tr>
<th>Ubicacin:</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

la

Pgina

Inicial</a></destacar>
</center>
</body>
</html>
Ficheros de Configuracin
Ya estamos listos para crear los ficheros de configuracin de nuestra aplicacin Librera :
Libreria/WEB-INF/web.xml

Libreria/WEB-INF/web.xml es el descriptor de despliegue para la aplicacin Web. Contiene dos


parmetros clave.
El parmetro listener identifica la clase Java del oyente libreria.ContextListener, al que se
llamar durante la arrancada y parada de la aplicacin.
<listener>
<listener-class>listener.ContextListener</listener-class>
</listener>
El parmetro welcome-file-list controla el punto de entrada a la aplicacin. El siguiente
cdigo selecciona la pgina Index.jsp como nico punto de entrada a la aplicacin Librera:
<welcome-file-list>
<welcome-file>Index.jsp</welcome-file>
</welcome-file-list>
Propsito del Fichero web.xml

Es el descriptor de despliegue de la aplicacin y est contenido en el directorio WEB-INF. Define


varios parmetros que son usados cuando se despliega la aplicacin en el contenedor de
Servlets/JSP Tomcat.
display-name
Configura el nombre de la aplicacin web que se mostrar en los listados de Tomcat. La siguiente
lnea selecciona este parmetro de la aplicacin Libreria como "Aplicacin Web de Libreria":
<display-name>Aplicacin Web de Libreria</display-name>
description
Configura la descripcin de la aplicacin Web. La siguiente lnea selecciona la descripcin de la
aplicacin Libreria como "Esta aplicacin mantiene una base de datos de libros.":
<description>Esta
aplicacin
mantiene
una
base
de
datos
de
libros.</description>
listener
Configura la aplicacin web para que se ejecute un oyente de contexto servlet cuando se
arranque o se pare la propia aplicacin Web. Las siguiente lneas seleccionan que el oyente de
contexto servlet de la aplicacin Librera sea libreria.ContextListener

<listener>
<listener-class>libreria.ContextListener</listener-class>
</listener>
welcome-file-list
Configura el punto de entrada a la aplicacin web. Las preferencias por defecto para este
parmetro 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. Deberamos 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 configuracin de Tomcat modificando el
ficheroconf/web.xml, pero no recomiendo hacerlo. Es mucho mejor seleccionar las preferencias
en el parmetro welcome-file-list de la propia aplicacin. Las siguiente lneas seleccionan el
punto de entrada de la aplicacin Librera como Index.jsp
<welcome-file-list>
<welcome-file>Index.jsp</welcome-file>
</welcome-file-list>
Cdigo 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>Aplicacin Web de Libreria</display-name>
<description>Esta
libros.</description>

aplicacin

mantiene

una

base

de

datos

de

<listener>
<listener-class>libreria.ContextListener</listener-class>
</listener>
<welcome-file-list>
<welcome-file>Index.jsp</welcome-file>
</welcome-file-list>
</web-app>
Libreria.xml

Propsito del Fichero Libreria.xml

El fichero Libreria.xml contiene los detalles del "contexto" de la aplicacin Libreria, es decir,
los parmetros que Tomcat usar cuando ejecute la aplicacin, entre ellos la definicin
delDataSource a utilizar, o el tipo de "Log" que va a tener esta aplicacin, por ejemplo.
Este cdigo define el path de contexto, el documento base, el nivel de depuracin, el marcador
de recargable, y el marcador de contexto cruzado:

<Context path="/Libreria"
crossContext="true">

docBase="Libreria"

debug="1"

reloadable="true"

... Aqu va la definicin del Logger ...


... Aqu va la definicin del DataSource ...
</Context>
Lo ms importante a observar en este trozo de cdigo son los atributos path y docBase, pero
veamos una breve descripcin de cada uno de ellos.

path indica el path que utilizaremos para acceder a nuestra aplicacin una vez instalada
en Tomcat y formar parte de la URI para acceder a la aplicacin desde nuestro navegador,
por ejemplo http://localhost:8080/Libreria en nuestro caso.

docBase tambin conocido como Raz del Documento se utiliza para indicar el
directorio donde van a residir los ficheros de la aplicacin cuyo contexto estamos
configurando. Nota: Si nuestra aplicacin se encuentra empaquetada en un ficheroWAR, en
el atributo docBase deberemos poner el path completo del fichero .war.

debug indica el nivel de log de esta aplicacin, cuando mayor sea el nmero 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 aplicacin para ver si han cambiado, pero debemos tener en cuenta que esta
operacin consume muchos recursos y que puede ser muy til para entornos de prueba
pero puede ser una mala idea para entornos de produccin.

crossContext indica
si
queremos
que
las
llamadas
a ServletContext.getContext()dentro de esta aplicacin sobre otras aplicaciones Web
que se ejecuten en el mismo host virtual devuelvan siempre un request
dispatcher vlido. En entornos de alta seguridad se puede seleccionar a false para hacer
que getContext() siempre devuelva null.
Hay muchos otros atributos del elemento context, podrs encontrar ms informacin sobre ellos
en el fichero Context.html que viene en la documentacin de Tomcat, en el
directorioC:\Archivos
de
programa\Apache
Group\Tomcat
4.1\webapps\tomcatdocs\config\
Definicin de Logger

Este cdigo define un objeto Logger como una claseorg.apache.catalina.logger.FileLogger.


En
el
directorio logs de
Tomcat
se
crear
un
fichero
log
llamado localhost_Libreria_log.YYYY-MM-DD.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"/>
Definicin del DataSource

Este
cdigo
define
un Resource llamado jdbc/biblioteca como
una
clasejavax.sql.DataSource:
<Resource
name="jdbc/biblioteca"
auth="Container"
type="javax.sql.DataSource"/>
Este
cdigo
define
el ResourceParams llamado jdbc/biblioteca como
una
claseorg.apache.commons.dbcp.BasicDataSourceFactory:
<ResourceParams name="jdbc/biblioteca">
<parameter>
<name>factory</name>
<value>org.apache.commons.dbcp.BasicDataSourceFactory</value>
</parameter>
... aqu van los parmetros de la base de datos ...
... aqu van los parmetros del Repositorio de Conexiones ...
</ResourceParams>
Parmetros 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 conexin inactivas despus de 8 horas. Si
esto sucede, usando autoReconnect=true se har que Tomcat se reconecte automticamente.
Otras bases de datos podran 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.jaren 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>
Parmetros del Repositorio de Conexiones

maxActive
El nmero mximo de conexiones en el repositorio, maxActive = 100. SeleccionamosmaxActive
= 0 para que no haya limite. Debemos asegurarnos de configurarmax_connections lo
suficientemente grande para manejar todas las conexiones a nuestra base de datos.
<parameter>
<name>maxActive</name>
<value>100</value>
</parameter>
maxIdle
El nmero mximo de conexiones inactivas a retener en el repositorio, maxIdle
Seleccionamos maxIdle = 0 para que no haya lmite.
<parameter>
<name>maxIdle</name>
<value>30</value>
</parameter>
maxWait

30.

El tiempo mximo a esperar para obtener una conexin 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 conexin abandonada que se
encuentre. El valor por defecto es removeAbandoned = false.
<parameter>
<name>removeAbandoned</name>

<value>true</value>
</parameter>
removeAbandonedTimeout
El nmero de segundos que una conexin 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
cdigo que abandon un recurso de conexin.
<parameter>
<name>logAbandoned</name>
<value>true</value>
</parameter>
Cdigo 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
type="javax.sql.DataSource"/>

name="jdbc/biblioteca"

auth="Container"

<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 Aplicacin
Desplegar la Aplicacin

Descarga el fichero

Libreria.zip que debe tener el siguiente contenido:

Descomprime el fichero

Librera.zip en el directorio \webapps de tu instalacin de Tomcat.

Asgurate de que en el directorio \webapps adems del


ficheroLibreria.xml.
Este debera ser el aspecto del despliegue de tu aplicacin:
C:\tomcat 4.1\
|
-> webapps\
|
|- Libreria.xml
-> Libreria\

directorio \Libreria tienes

el

|
|||||||->

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 mquina,


adems del nombre de usuario y la password que utilizas para acceder a MySQL.
Ejecutar la Aplicacin
Antes de ejecutar la aplicacin debes asegurarte de que has seguido los pasos indicados en la
seccin Crear la Tabla Libros en la Base de Datos.
Ahora solo queda arrancar Tomcat de la forma habitual, dirigir tu navegador favorito a la
direccin http://localhost:8080/Libreria/Index.jsp, y deberas ver la pantalla inicial de la
aplicacin:

Ahora ya puedes empezar a insertar, borrar y modificar registros.

JAVA - APLICACIN WEB, CARRITO DE COMPRAS PARTE II - CREACIN DEL MODELO


3:48 P.M. HENRY JOE WONG URQUIZA 12 COMENTARIOS

"Si usa algn cdigo del siguiente tutorial, den el icono de ME GUSTA del Facebook que se encuentra
en su mano derecha, para que se vuelva Seguidor del Blog y tambin comentenos que tal les pareci
el tutorial"

1. ENTORNO

MySQL 5.1.
NetBeans IDE 6.9.1
Apache Tomcat
JDK 1.6.0 - 21

2. INTRODUCCIN

El modelo es la representacin especfica de la informacin con la cual el sistema opera. En resumen, el


modelo se limita a lo relativo de la vista y su controlador facilitando las presentaciones visuales complejas. El
sistema tambin puede operar con ms datos no relativos a la presentacin, haciendo uso integrado de otras
lgicas de negocio y de datos afines con el sistema modelado. Ac crearemos nuestrosJavaBeans y las
clases que se encargaran de llamar a los procedimientos almacenados que hemos creado en nuestra base de
datos BDTutorial que esta en MySQL 5.1.. Para comunicar Java con Base de datos usamos lo que
comnmente se conoce como JDBC y para ejecutar consultas o inserciones a nuestra base de datos usamos
las interfaces java.sql.Statement que espera que se le pase una sentencia SQL de forma completa por
ejemplo "insert into producto values(1,'valor01')", para ejecutar sentencias preparadas se utiliza la interfaz
java.sql.PreparedStatement que en los lugares donde se deben de poner los valores para la sentecia SQL se
representan entre ? para despus poder asignar sus valores respectivos por ejemplo "insert into producto
values(?,?)" y la ultima clase para llamar a procedimientos almacenados es la
clase java.sql.CallableStatement que es la que utilizaremos para este tutorial

3. CREANDO EL PROYECTO

3.1. Proyecto en Netbeans


Primero debemos de crear un proyecto web en Netbeans y para eso abriremos el Netbeans y buscaremos el
menu File y luego New Project. Y seleccionaremos que deseamos crear un proyecto del tipo Web Application

De ah presionamos el botn Next y nos pedir que pongamos un nombre a nuestro proyecto y lo
llamaremos CarritoComprasJSP

Luego nos pedir que seleccionamos en que servidor queremos que se ejecute nuestro proyecto web. En este
caso lo ejecutaremos en el servidor de Apache Tomcat

3.2. Estructura del proyecto


Para explicar la estructura que vamos a tener del proyecto, les presento el siguiente grfico que nos indicara
como se distribuir el Modelo, el Controlador y la Vista

4. DESARROLLO

4.1. Creando el Paquete


Primero debemos de crear nuestro paquete que se llamara Modelo. En el grfico se explica como crear el
paquete

Y al paquete lo llamaremos Modelo


4.2. Creando los JavaBeans
Para crear los JavaBeans debemos de crear las clases que tendran la misma estructura de las tablas de
nuestra base de datos, eso quiere decir que si por ejemplo en alguna tabla de nuestra base de datos tenemos
una columna del tipo Varchar en Java tendriamos una variable del tipo String, si tenemos un variable del tipo
Decimal en Java seria double. Para eso hacemos clic derecho en nuestro paquete que se llama Modelo, de
ahi nos vamos a New y seleccionamos Java Class
4.2.1. Clase Producto
La clase Producto tiene la misma estructura de nuestra tabla Producto de nuestra base de datos,
a continuacin les comparto el cdigo fuente de la clase.

package Modelo;
//@author Henry Joe Wong Urquiza
public class Producto {
//Las columnas que tiene la tabla Producto
private int codigoProducto;
private String nombre;
private double precio;
//Constructor de la clase sin parametros
public Producto() {
}
//Constructor de la clase con parametros
public Producto(int codigoProducto, String nombre, double precio) {
this.codigoProducto = codigoProducto;
this.nombre = nombre;
this.precio = precio;
}
//Metodo toString de la clase que nos retorna
//el nombre del producto
@Override
public String toString() {
return nombre.toUpperCase();
}
//Metodos get y set de la clase
public int getCodigoProducto() {
return codigoProducto;
}
public void setCodigoProducto(int codigoProducto) {
this.codigoProducto = codigoProducto;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public double getPrecio() {
return precio;
}
public void setPrecio(double precio) {
this.precio = precio;
}

4.2.2. Clase Venta


La clase Venta tiene la misma estructura de nuestra tabla Venta de nuestra base de datos, a continuacin les
comparto el cdigo fuente de la clase.
package Modelo;
// @author hwong
import java.sql.Timestamp;
public class Venta {
//Las columnas que tiene la tabla Venta
private int codigoVenta;
private String cliente;
private Timestamp fecha;
//Constructor de la clase sin parametros
public Venta() {
}
//Constructor de la clase con parametros
public Venta(int codigoVenta, String cliente, Timestamp fecha) {
this.codigoVenta = codigoVenta;
this.cliente = cliente;
this.fecha = fecha;
}
//Metodos get y set de la clase
public String getCliente() {
return cliente;
}
public void setCliente(String cliente) {
this.cliente = cliente;
}
public int getCodigoVenta() {
return codigoVenta;
}
public void setCodigoVenta(int codigoVenta) {
this.codigoVenta = codigoVenta;
}

public Timestamp getFecha() {


return fecha;
}
public void setFecha(Timestamp fecha) {
this.fecha = fecha;
}
}
4.2.3. Clase DetalleVenta
La clase DetalleVenta tiene la misma estructura de nuestra tabla DetalleVenta de nuestra base de datos,
a continuacin les comparto el cdigo fuente de la clase.
package Modelo;
// @author hwong
public class DetalleVenta {
//Las columnas que tiene la tabla DetalleVenta
private int codigoVenta;
private int codigoProducto;
private double cantidad;
private double descuento;
private Producto producto;
private Venta venta;
//Constructor sin parametros
public DetalleVenta() {
}
//Constructor con parametros
public DetalleVenta(int codigoVenta, int codigoProducto, double cantidad,
double descuento) {
this.codigoVenta = codigoVenta;
this.codigoProducto = codigoProducto;
this.cantidad = cantidad;
this.descuento = descuento;
}
//Metodos Get y Set de la clase
public double getCantidad() {
return cantidad;
}
public void setCantidad(double cantidad) {

this.cantidad = cantidad;
}
public int getCodigoProducto() {
return codigoProducto;
}
public void setCodigoProducto(int codigoProducto) {
this.codigoProducto = codigoProducto;
}
public int getCodigoVenta() {
return codigoVenta;
}
public void setCodigoVenta(int codigoVenta) {
this.codigoVenta = codigoVenta;
}
public double getDescuento() {
return descuento;
}
public void setDescuento(double descuento) {
this.descuento = descuento;
}
public Producto getProducto() {
return producto;
}
public void setProducto(Producto producto) {
this.producto = producto;
}
public Venta getVenta() {
return venta;
}
public void setVenta(Venta venta) {
this.venta = venta;
}
}
4.2.4. Estructura final
Al finalizar de crear las clases deberiamos tener 3 clases tal como se muestra en el grafico siguiente

4.3. Creando las clases para comunicar con la base de datos


4.3.1. Cargando el Driver
Para poder comunicar nuestro proyecto con MySQL 5.1. primero debemos de adicionar el driver a nuestro
proyecto. Para eso hacemos clic derecho en nuestro proyecto y nos vamos a la opcin que dice Properties y
seleccionamos de ah Libraries y presionamos el botn que dice Add Library y buscamos el que dice MySQL
JDBC Driver

4.3.2. Creando la clase Conexion


Esta clase es la que centraliza la conexin con nuestra base de datos que esta en MySQL nos va dar soporte
para ciertos mtodos que vamos a usar en nuestras dems clases
package Modelo;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
//@author Henry Joe Wong Urquiza
public class Conexion {
//La url con la cual nos conectariamos a la base de datos
private static String url = "jdbc:mysql://localhost/bdtutorial";
//El usuario de la base de datos

private static String user = "root";


//La clave del usuario de la base de datos
private static String password = "clave";
//Metodo para obtener la conexion con la base de datos
public static synchronized Connection getConexion() {
Connection cn = null;
try {
//Cargamos el driver y le decimos que vamos a usar
//una conexion con mysql
Class.forName("com.mysql.jdbc.Driver");
//Obtenemos la conexion
cn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
cn = null;
} finally {
return cn;
}
}
//Metodo utilizado para cerrar el callablestatemente
public static synchronized void cerrarCall(CallableStatement cl) {
try{cl.close();}catch(Exception e){}
}
//Metodo utilizado para cerrar el resulset de datos
public static synchronized void cerrarConexion(ResultSet rs) {
try{rs.close();} catch (Exception e) {}
}
//Metodo utilizado para cerrar la conexion
public static synchronized void cerrarConexion(Connection cn) {
try{cn.close();} catch (Exception e) {}
}
//Metodo utilizado para deshacer los cambios en la base de datos
public static synchronized void deshacerCambios(Connection cn) {
try{cn.rollback();}catch (Exception e){}
}
}

4.3.3. Creando la clase ProductoBD


Que se encargara de hacer las consultas o inserciones a nuestra tabla Producto

package Modelo;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

import java.sql.Types;
import java.util.ArrayList;
// @autor Henry Joe Wong Uruqiza
// Archivo: ProductoBD.java
// Creado: 24FEBRERO2011 12:39:08 PM
public class ProductoBD {
//Metodo utilizado para insertar un Producto a nuestra Base de datos
public static synchronized boolean insertarProducto(Producto varproducto) {
Connection cn = null;
CallableStatement cl = null;
boolean rpta = false;
try {
//Nombre del procedimiento almacenado y como espera tres parametros
//le ponemos 3 interrogantes
String call = "{CALL spI_producto(?,?,?)}";
//Obtenemos la conexion
cn = Conexion.getConexion();
//Decimos que vamos a crear una transaccion
cn.setAutoCommit(false);
//Preparamos la sentecia
cl = cn.prepareCall(call);
//Como el codigo se autogenera y es del tipo OUT en el procedimiento
//almacenado le decimos que es OUT y el del tipo Integer en Java
cl.registerOutParameter(1, Types.INTEGER);
//El siguiente parametro del procedimiento almacenado es el nombre
cl.setString(2, varproducto.getNombre());
//Y por ultimo el precio
cl.setDouble(3, varproducto.getPrecio());
//Ejecutamos la sentencia y si nos devuelve el valor de 1 es porque
//registro de forma correcta los datos
rpta = cl.executeUpdate() == 1 ? true : false;
if (rpta) {
//Confirmamos la transaccion
cn.commit();
} else {
//Negamos la transaccion
Conexion.deshacerCambios(cn);
}
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (SQLException e) {
e.printStackTrace();
Conexion.deshacerCambios(cn);
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (Exception e) {

e.printStackTrace();
Conexion.deshacerCambios(cn);
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
}
return rpta;
}
//Metodo utilizado para insertar un Producto a nuestra Base de datos
public static synchronized boolean actualizarProducto(Producto varproducto) {
Connection cn = null;
CallableStatement cl = null;
boolean rpta = false;
try {
//Nombre del procedimiento almacenado y como espera tres parametros
//le ponemos 3 interrogantes
String call = "{CALL spU_producto(?,?,?)}";
//Obtenemos la conexion
cn = Conexion.getConexion();
//Decimos que vamos a crear una transaccion
cn.setAutoCommit(false);
//Preparamos la sentecia
cl = cn.prepareCall(call);
//El primer parametro del procedimiento almacenado es el codigo
cl.setInt(1, varproducto.getCodigoProducto());
//El siguiente parametro del procedimiento almacenado es el nombre
cl.setString(2, varproducto.getNombre());
//Y por ultimo el precio
cl.setDouble(3, varproducto.getPrecio());
//Ejecutamos la sentencia y si nos devuelve el valor de 1 es porque
//registro de forma correcta los datos
rpta = cl.executeUpdate() == 1 ? true : false;
if (rpta) {
//Confirmamos la transaccion
cn.commit();
} else {
//Negamos la transaccion
Conexion.deshacerCambios(cn);
}
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (SQLException e) {
e.printStackTrace();
Conexion.deshacerCambios(cn);
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (Exception e) {
e.printStackTrace();

Conexion.deshacerCambios(cn);
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
}
return rpta;
}
//Metodo utilizado para obtener todos los productos de nuestra base de datos
public static synchronized ArrayList<Producto> obtenerProducto() {
//El array que contendra todos nuestros productos
ArrayList<Producto> lista = new ArrayList<Producto>();
Connection cn = null;
CallableStatement cl = null;
ResultSet rs = null;
try {
//Nombre del procedimiento almacenado
String call = "{CALL spF_producto_all()}";
cn = Conexion.getConexion();
cl = cn.prepareCall(call);
//La sentencia lo almacenamos en un resulset
rs = cl.executeQuery();
//Consultamos si hay datos para recorrerlo
//e insertarlo en nuestro array
while (rs.next()) {
Producto p = new Producto();
//Obtenemos los valores de la consulta y creamos
//nuestro objeto producto
p.setCodigoProducto(rs.getInt("codigoProducto"));
p.setNombre(rs.getString("nombre"));
p.setPrecio(rs.getDouble("precio"));
//Lo adicionamos a nuestra lista
lista.add(p);
}
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (SQLException e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (Exception e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
}
return lista;
}
//Metodo utilizado para obtener todos los productos de nuestra base de datos

public static synchronized Producto obtenerProducto(int codigo) {


Producto p = new Producto();
Connection cn = null;
CallableStatement cl = null;
ResultSet rs = null;
try {
//Nombre del procedimiento almacenado
String call = "{CALL spF_producto_one(?)}";
cn = Conexion.getConexion();
cl = cn.prepareCall(call);
cl.setInt(1, codigo);
//La sentencia lo almacenamos en un resulset
rs = cl.executeQuery();
//Consultamos si hay datos para recorrerlo
//e insertarlo en nuestro array
while (rs.next()) {
//Obtenemos los valores de la consulta y creamos
//nuestro objeto producto
p.setCodigoProducto(rs.getInt("codigoProducto"));
p.setNombre(rs.getString("nombre"));
p.setPrecio(rs.getDouble("precio"));
}
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (SQLException e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (Exception e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
}
return p;
}
}

4.3.4. Creando la clase DetalleVentaBD


Sirve para insertar un detalle de la venta, el metodo insertarDetalle espera obtener la conexion y la
transaccion de la clase Venta. Debido a que esta ultima clase es la que inicia la transaccion con la base de
datos y es la nica encargada de confirmar o negar la transaccion
package Modelo;
// @autor Henry Joe Wong Uruqiza
import java.sql.CallableStatement;

import java.sql.Connection;
import java.sql.SQLException;
// Archivo: DetalleVentaBD.java
// Creado: 24FEBRERO2011 12:39:08 PM
public class DetalleVentaBD {
//Metodo utilizado para insertar un Detalle de Venta a nuestra Base de datos
//Obtenemos la conexion de Venta debido a que la clase Venta es la que inicia
//la transaccion
public static synchronized boolean insertarDetalleVenta(DetalleVenta
varDetalle, Connection cn) {
CallableStatement cl = null;
boolean rpta = false;
try {
//Nombre del procedimiento almacenado y como espera tres parametros
//le ponemos 3 interrogantes
String call = "{CALL spI_detalleventa(?,?,?,?)}";
//Preparamos la sentecia
cl = cn.prepareCall(call);
//Codigo de la venta
cl.setInt(1, varDetalle.getCodigoVenta());
//Codigo del producto
cl.setInt(2, varDetalle.getCodigoProducto());
//La cantidad
cl.setDouble(3, varDetalle.getCantidad());
//El descuento
cl.setDouble(4, varDetalle.getDescuento());
//Ejecutamos la sentencia y si nos devuelve el valor de 1 es porque
//registro de forma correcta los datos
rpta = cl.executeUpdate() == 1 ? true : false;
Conexion.cerrarCall(cl);
} catch (SQLException e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
} catch (Exception e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
}
return rpta;
}
}
4.3.5. Creando la clase VentaBD
package Modelo;
import java.sql.CallableStatement;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
// @autor Henry Joe Wong Uruqiza
// Archivo: VentaBD.java
// Creado: 24FEBRERO2011 12:39:08 PM
public class VentaBD {
//Metodo utilizado para insertar una Venta a nuestra Base de datos
public static synchronized boolean insertarVenta(Venta varventa,
ArrayList<DetalleVenta> detalle) {
Connection cn = null;
CallableStatement cl = null;
boolean rpta = false;
try {
//Nombre del procedimiento almacenado y como espera tres parametros
//le ponemos 3 interrogantes
String call = "{CALL spI_venta(?,?)}";
//Obtenemos la conexion
cn = Conexion.getConexion();
//Decimos que vamos a crear una transaccion
cn.setAutoCommit(false);
//Preparamos la sentecia
cl = cn.prepareCall(call);
//Como el codigo se autogenera y es del tipo OUT en el procedimiento
//almacenado le decimos que es OUT y el del tipo Integer en Java
cl.registerOutParameter(1, Types.INTEGER);
//El siguiente parametro del procedimiento almacenado es el cliente
cl.setString(2, varventa.getCliente());
//Ejecutamos la sentencia y si nos devuelve el valor de 1 es porque
//registro de forma correcta los datos
rpta = cl.executeUpdate() == 1 ? true : false;
//Codigo que se genero producto de la insercion ---> codigoVenta
varventa.setCodigoVenta(cl.getInt(1));
if (rpta) {
for (DetalleVenta det : detalle) {
//Establecemos al detalle el codigo genero producto de la
venta
det.setCodigoVenta(varventa.getCodigoVenta());
//Insertamos el detalle y le pasamos la conexion
rpta = DetalleVentaBD.insertarDetalleVenta(det, cn);
//Si nos devuelve false salimos del for
if (!rpta) {
break;

}
}
if (rpta) {
//Confirmamos la transaccion
cn.commit();
} else {
//Negamos la transaccion
Conexion.deshacerCambios(cn);
}
} else {
//Negamos la transaccion
Conexion.deshacerCambios(cn);
}
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (SQLException e) {
e.printStackTrace();
Conexion.deshacerCambios(cn);
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (Exception e) {
e.printStackTrace();
Conexion.deshacerCambios(cn);
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
}
return rpta;
}
//Metodo utilizado para obtener todos las ventas de nuestra base de datos
public static synchronized ArrayList<DetalleVenta> obtenerVentas() {
//El array que contendra todos nuestros productos
ArrayList<DetalleVenta> lista = new ArrayList<DetalleVenta>();
Connection cn = null;
CallableStatement cl = null;
ResultSet rs = null;
try {
//Nombre del procedimiento almacenado
String call = "{CALL spF_venta_All()}";
cn = Conexion.getConexion();
cl = cn.prepareCall(call);
//La sentencia lo almacenamos en un resulset
rs = cl.executeQuery();
//Consultamos si hay datos para recorrerlo
//e insertarlo en nuestro array
while (rs.next()) {
Venta ven=new Venta();
Producto pro=new Producto();

DetalleVenta det=new DetalleVenta();


ven.setCodigoVenta(rs.getInt("CodigoVenta"));
ven.setCliente(rs.getString("Cliente"));
ven.setFecha(rs.getTimestamp("Fecha"));
pro.setCodigoProducto(rs.getInt("CodigoProducto"));
pro.setNombre(rs.getString("Nombre"));
pro.setPrecio(rs.getDouble("Precio"));
det.setCantidad(rs.getDouble("Cantidad"));
det.setDescuento(rs.getDouble("Parcial"));
det.setVenta(ven);
det.setProducto(pro);
lista.add(det);
}
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (SQLException e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
} catch (Exception e) {
e.printStackTrace();
Conexion.cerrarCall(cl);
Conexion.cerrarConexion(cn);
}
return lista;
}
}
4.4. Estructura final de todas las clases

También podría gustarte