Está en la página 1de 42

Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Práctica 2: Creación de aplicaciones web siguiendo el patrón


de diseño MVC en Java.
1- Objetivo.
El objetivo de esta práctica es continuar con la creación de la tienda virtual iniciada en la
primera práctica. Para ello crearemos una aplicación web que siga el patrón de diseño
Modelo/Vista/Controlador (MVC) e implemente en Java la parte dinámica de la tienda.

2- El patrón MVC.
El patrón de diseño MVC es usado en interfaces gráficas de usuario para tener separadas las
responsabilidades en capas de objetos diferentes de manera que las aplicaciones sean más fáciles de
desarrollar y mantener [1]. La siguiente figura representa las tres capas del patrón MVC, que se
detallan a continuación.

Figura 2.1: Diagrama de interacciones en MVC

1. El Controlador es el intermediario entre la Vista y el Modelo, e implementa la lógica de


negocio asociada al funcionamiento de la aplicación. Responde ante acciones del usuario (y
otros eventos) que se traducen en la cita lógica de negocio, pudiendo manipular los objetos
de la capa del Modelo y causar una actualización de los datos de la Vista.

2. La capa del Modelo incluye todos aquellos objetos que encapsulan los datos que maneja la
aplicación. Esta capa oculta al resto de capas las peculiaridades de la tecnología de
almacenamiento de la información (e.g., base de datos empleada, lenguaje de interrogación

1
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

y almacenamiento, etc), y se entiende como la representación de la información de la


aplicación.

3. La Vista presenta la información (modelo) y la lógica de negocio (acciones del controlador)


a través de una interfaz de usuario que facilita la interacción con el mismo.

3- MVC en aplicaciones web desarrolladas con Java.


El patrón MVC tiene diferentes propuestas de implementación para aplicaciones web
basadas en Java [2]. A continuación se describe la opción thin-client, que usaremos en prácticas.
Esta propuesta hace uso de Servlets [3], JavaServer Pages (JSPs) [4] y Java Beans [5] para
implementar el Controlador, la Vista y el Modelo, respectivamente.

Figura 3.1: Diagrama de secuencia para el patrón MVC en su aproximación thin-client

La figura anterior muestra las interacciones entre los diferentes componentes Java de las tres
capas. Los Servlets del controlador están mapeados a urls con extensión .html (e.g., accion.html)
que aunque parecen páginas estáticas son dinamismos en el servidor que se asocian a acciones del
controlador. El usuario de la aplicación hace uso de un navegador web para ejecutar lógica de
negocio a través de peticiones HTTP a estas acciones, que al ejecutarse suelen acceder, crear o
modificar datos de la base de datos. El acceso a la base de datos, MySQL [6] en esta práctica, no se
hace directamente, si no a través de Factories [7], que son un patrón de diseño que permite ocultar
los detalles del acceso a datos mediante el empaquetamiento de la información en JavaBeans.
Finalmente, los Servlets redirigen a una JSP que interpreta los JavaBeans y genera la interfaz de
usuario en HTML.

2
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Por lo tanto, las JSPs son las únicas que generarán HTML accediendo únicamente a tipos
básicos, a clases del paquete java.util.* o a JavaBeans definidos en la aplicación o en otras librerías.
Además los Servlets sólo podrán acceder a las Factories y a los JavaBeans. Finalmente, las
Factories serán las únicas que accedan a JDBC [8] para ejecutar sentencias SQL sobre la base de
datos MySQL.

4- Enunciado.
En esta práctica proporcionaremos el contenido dinámico a las páginas web elaboradas en la
primera práctica, añadiendo un conjunto de Servlets, JavaBeans, Factories y páginas JSPs
interconectados para permitir realizar la compra de los productos de la tienda virtual. Como parte de
la arquitectura de la aplicación web, se deberá diseñar y crear una base de datos MySQL y una
estructura de datos básica para almacenar la información relativa al sitio web creado.

La aplicación a desarrollar debe tener las siguientes características1:

 Dispondrá de un carrito de la compra donde los usuarios podrán ir añadiendo los productos
que deseen.

 Para finalizar el pedido el usuario tendrá que estar previamente registrado en el sistema.
Para ello se habilitarán los formularios necesarios para realizar el registro y el acceso. La
información para el acceso se almacenará en la base de datos.

 El usuario dispondrá de una zona personal para administrar los datos introducidos, ver sus
pedidos, etc.

La práctica se realizará a lo largo de cuatro sesiones de prácticas y se corregirá con el


profesor una vez terminadas las sesiones de práctica. Las cuatro secciones existentes en el guion de
la práctica indican los objetivos mínimos que los alumnos deben alcanzar en cada una de las
sesiones de prácticas, siendo necesario tener finalizados esos objetivos antes de comenzar la
siguiente sesión de prácticas.

1 La parte de administración de la web se implementará utilizando PHP en la tercera práctica, por lo que queda fuera
de los objetivos de esta segunda práctica.

3
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

5- Sesión 1. Creación del carrito de la compra mediante Javascript.


5.1- Configuración de MySQL/MariaDB utilizando phpMyAdmin.
Desde la práctica 0 deberíamos tener instalado XAMPP con Apache, MySQL/MariaDB,
PHP y phpMyAdmin. Si no se tiene instalado es un buen momento para realizar la instalación tal y
como se explicaba, pues a partir de este punto se necesita para poder realizar la práctica.

Entre las herramientas que debemos haber instalado se encuentra phpMyAdmin.


PhpMyAdmin es una aplicación PHP que permite gestionar de forma sencilla las bases de datos
MySQL/MariaDB. Se puede acceder a la misma escribiendo en el navegador la URL:
http://localhost/phpmyadmin o bien pulsando en el panel de control de XAMPP la opción de
“Admin”. En cualquier caso, nos aparecerá la siguiente pantalla:

Figura 5.1.1: Visión general de phpMyAdmin.

La gestión de MySQL/MariaDB con phpMyAdmin es muy sencilla. Como ejemplo vamos a


crear una base de datos para nuestra aplicación y a continuación una tabla que contenga el nombre
de usuario y la contraseña de los usuarios de la tienda virtual.

La creación de una base de datos es tan sencilla como pulsar en el menú de la izquierda la
opción “Nueva”, dar un nombre a la base de datos y pulsar el botón “Crear”:

4
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 5.1.2: Creación de una base de datos con phpMyAdmin.

Una vez creada la base de datos aparece automáticamente el menú de creación de tablas, en
el cual tan solo debemos indicar el nombre de la tabla y su número de columnas, pulsar en
“Continuar”, definir los tipos de datos de los campos y por último pulsar en “Guardar”, tal y como
pueden verse en las siguientes figuras:

Figura 5.1.3: Creación de tablas con phpMyAdmin.

Por último, phpMyAdmin también permite insertar elementos en las tablas de la base de
datos, ejecutar consultas sobre la base de datos y mostrar el resultado, etc., lo que es muy útil a la
hora de rellenar las tablas, comprobar que las consultas que se embeben en el código son correctas y
realizan la acción deseada, etc.

La inserción de elementos se realiza seleccionando la pestaña “Insertar”, rellenando los


campos con sus valores y pulsando en “Continuar”, tal y como se ve a continuación:

5
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 5.1.4: Inserción de elementos en tablas con phpMyAdmin.

Mientras que las consultas sobre la base de datos se realizan seleccionando la pestaña
“SQL”, rellenando la consulta en el área de texto y pulsando “Continuar”, como se puede ver en la
siguiente figura:

Figura 5.1.5: Consultas en tablas con phpMyAdmin.


5.2 – Creación de la base de datos de la tienda online
Una vez nos hemos familiarizado con el uso de phpMyAdmin debemos crear la base de
datos que nos permita manejar el contenido de nuestra tienda online. Para ello, vamos a realizar un
breve análisis de la información que debemos almacenar.

Necesitaremos una tabla para almacenar los productos, de los cuales necesitaremos conocer
su descripción, su precio y sus existencias en el almacén, además de la URL de su imagen asociada
(si se utiliza). Por último, deberíamos añadir un identificador único para poder hacer referencia al
producto2.

Necesitaremos otra tabla para almacenar los usuarios y sus datos, necesitando un
identificador único para el usuario, así como el resto de datos necesarios (usuario, clave, nombre,
apellidos, etc.). Además, deberá existir un campo que indique el estado del usuario (activo o no
activo/baja) y otro campo que indique si el usuario es administrador o no3.

2 Podría ser necesario otro atributo que indique si ese producto aún se vende o no, pero basta con que las existencias
sean 0 para que el producto, si el programa se desarrolla correctamente, no pueda venderse.
3 Este último campo se utilizará en la práctica 3, pero debemos introducirlo ahora pues la base de datos es común
para ambas prácticas.

6
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Por último, necesitamos dos tablas para almacenar los pedidos realizados. Una primera tabla
almacenara la identificación del pedido y la persona que hace el pedido, así como datos adicionales
como la fecha del pedido, el importe total del mismo o el estado del pedido (entregado, cancelado,
etc.), y una segunda tabla será el detalle que contendrá todos los productos distintos que forman ese
pedido, pues es necesario tener en cuenta que un pedido puede contener productos distintos, y que
por cada producto deberá contener el identificador del pedido y del producto, la cantidad pedida y el
precio unitario, pues debemos tener en cuenta que el precio de un producto puede cambiar pero no
en los pedidos ya realizados.

Por tanto, y obviando esta última tabla, el diagrama de una posible base de datos que nos
permita manejar nuestra tienda online sería el siguiente:

Figura 5.2.1: Esquema de una posible base de datos para la tienda online.

Unas sentencias SQL que crearían las tablas de la base de datos anterior, con unos tipos de
datos que podrían ser validos en muchos de los casos, son:

CREATE TABLE productos(


codigo INTEGER NOT NULL AUTO_INCREMENT,
descripcion VARCHAR(255),
precio DECIMAL(8,2),
existencias INTEGER,
imagen VARCHAR(255),
PRIMARY KEY(codigo)
);

CREATE TABLE usuarios(


codigo INTEGER NOT NULL AUTO_INCREMENT,
activo INTEGER,
admin INTEGER,
usuario VARCHAR(32) UNIQUE,
clave VARCHAR(32),
nombre VARCHAR(64),
apellidos VARCHAR(128),
domicilio VARCHAR(128),
poblacion VARCHAR(64),

7
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

provincia VARCHAR(32),
cp CHAR(5),
telefono CHAR(9),
PRIMARY KEY(codigo)
);

CREATE TABLE pedidos(


codigo INTEGER NOT NULL AUTO_INCREMENT,
persona INTEGER NOT NULL,
fecha DATE,
importe DECIMAL(8,2),
estado INTEGER,
PRIMARY KEY(codigo),
FOREIGN KEY(persona) REFERENCES usuarios(codigo)
);

CREATE TABLE detalle(


codigo_pedido INTEGER NOT NULL,
codigo_producto INTEGER NOT NULL,
unidades INTEGER,
precio_unitario DECIMAL(8,2),
PRIMARY KEY(codigo_pedido,codigo_producto),
FOREIGN KEY(codigo_pedido) REFERENCES pedidos(codigo),
FOREIGN KEY(codigo_producto) REFERENCES productos(codigo)
);

5.3- Creación de la aplicación web.


Una vez tenemos instaladas todas las herramientas necesarias, vamos a crear un proyecto de
aplicación web en NetBeans. Para ello ejecutamos NetBeans y seleccionamos la opción de crear un
nuevo proyecto (Archivo → Proyecto Nuevo), escogiendo la categoría “Java Web”, el proyecto
“Web Application” y pulsando en “Siguiente”, tal y como puede verse a continuación4:

Figura 5.3.1: Creación de un proyecto de aplicación web Java.

4 Si nunca se ha generado un proyecto de esta categoría es posible que indique que no está disponible, debiendo
pulsar el botón de “Siguiente” y esperar un rato para que active este tipo de proyectos.

8
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Una vez seleccionado el tipo de proyecto indicamos su nombre y pulsamos “Siguiente”:

Figura 5.3.2: Selección del nombre del proyecto.

A continuación, seleccionamos el servidor de aplicaciones que deseamos utilizar, la versión


de Java mínima que deseamos usar, Java EE 7 Web en el ejemplo (utilizar la más alta disponible en
vuestro equipo), y continuamos presionando en “Siguiente”:

Figura 5.3.3: Selección del servidor de aplicaciones y versión de Java.

Por último, no seleccionaremos ningún framework, por lo que tan solo tenemos que pulsar
en “Terminar” para concluir la creación del nuevo proyecto:

9
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 5.3.4: Selección del Framework a utilizar.

Una vez creada la aplicación nos aparecerá una página inicial “index.jsp” que es la página
inicial de nuestra aplicación web y que habrá que sustituirla por la desarrollada en la práctica 1.
Podemos ejecutar el servicio web pulsando en el icono de Play, apareciendo una ventana del
navegador con la ejecución de la aplicación web, tal y como podemos ver en la siguiente figura:

Figura 5.3.5: Visión general y ejecución del nuevo proyecto creado.


5.4- Colocar las páginas web de la práctica 1 dentro de la aplicación web.
Para poder editar las páginas web que creamos en la práctica 1 debemos añadir los ficheros,
hojas de estilo, etc., a nuestro proyecto. Para ello tan solo debemos copiar los ficheros en el mismo
directorio donde se encuentra el fichero de ejemplo index.jsp que hemos visto que se ha creado al
crear nuestro proyecto de aplicación web5. Una vez se hayan copiado los archivos aparecerán
automáticamente en el programa, tal y como puede verse a continuación:

5 Puede usarse el explorador de Windows para localizar la ubicación del proyecto de aplicación web creado.

10
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 5.4.1: Resultado de añadir los ficheros de la práctica 1 al proyecto.

Si deseamos cambiar la página inicial de nuestra aplicación web debemos pulsar con el
botón derecho sobre el nombre del proyecto y seleccionar propiedades, tal y como podemos ver en
la siguiente figura:

Figura 5.4.2: Opción a seleccionar para modificar la página de inicio del proyecto.

Dentro del apartado Run, en “Relative URL” debemos escribir el nombre de la página inicial
que deseamos se cargue al ejecutar la aplicación, por ejemplo index.html, tal y como podemos ver a
continuación:

11
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 5.4.3: Cambio de la página de inicio del proyecto.

5.5- Instalación del conector MySQL para Java.


La aplicación web que vamos a desarrollar utilizará una base de datos para almacenar la
información de productos, usuarios y pedidos. Dicha base de datos es la que se ha creado con
anterioridad utilizando phpMyAdmin. Para poder utilizar la base de datos necesitamos instalar un
conector de MySQL para Java, que puede descargarse desde la URL
https://dev.mysql.com/downloads/connector/j/6. Dicho conector debe ir en el directorio WEB-INF
del proyecto, por lo que debe copiarse en su interior, pudiéndose crear un subdirectorio de nombre
lib para organizar mejor la aplicación:

Figura 5.5.1: Copia del conector MySQL para Java en el directorio WEB-INF/lib.

Una vez copiado el conector en la carpeta adecuada, debemos agregar el jar como referencia
al proyecto pulsando con el botón derecho en el proyecto y seleccionando la opción Propiedades, tal

6 En la actualidad la versión del conector es la 8.0.23. Adicionalmente, tener en cuenta que se descarga un
fichero .zip el cual debe extraerse el .jar que es el conector propiamente dicho. Para Windows escoger en la opción
del sistema operativo “Platform Independent”.

12
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

y como vimos en la figura 5.4.2. En la ventana que aparece seleccionamos Libraries → Add
JAR/Folder como vemos a continuación:

Figura 5.5.2: Opción de añadir un JAR a las librerías del proyecto.

En la nueva ventana buscamos el JAR dentro de los proyectos de Netbeans, seleccionamos


el conector JAR y pulsamos en Abrir, quedando la librería añadida al proyecto tal y como podemos
ver:

Figura 5.5.3: Selección de la librería JAR a añadir al proyecto.

5.6- Desarrollo de la Práctica


5.6.1- Manejo del carrito de la compra.
La gestión del carrito de la compra se realizará utilizando Javascript. Para ello, en la página
de productos, se debe habilitar el mecanismo para añadir cada uno de los productos al carrito de la
compra (por ejemplo, mediante el uso de botones). Ello exige el uso de una estructura de datos
adecuada para almacenar la información de cada uno de los productos en el carrito de la compra.

Aunque puede realizarse de múltiples formas, se recomienda utilizar una estructura de datos
basada en un objeto que sea un contenedor de objetos, de forma que cada elemento del objeto
contenedor sea uno de los productos del carrito. De esta forma, la estructura de los objetos sería:

13
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

var carrito = new Object(); // Objeto contenedor, se debe crear solo uno.

var producto = new Object(); // Objeto que deseamos almacenar


producto.id = identificador; // Identificador único del objeto
producto.nombre = "Nombre/descripción del producto"; // Nombre del objeto
producto.cantidad = 1; // Cantidad que tenemos en el carrito (1 por ejemplo)
producto.precio = 100.0; // Precio unitario de cada elemento (100.0 por ejemplo)

carrito[identificador] = producto;

La función Javascript utilizada debe comprobar si el producto ya existe en el listado de


productos del carrito de la compra y, en caso afirmativo, tan solo aumentar el valor de su cantidad,
mientras que en caso negativo debe insertar el nuevo producto en el carrito.

Se debe informar al cliente de forma visual que el producto se ha añadido al carrito, bien
mediante una ventana emergente o bien mediante el cambio de algún elemento visual de la página.
5.6.2.- Página del Carrito.
Nuestra página tendrá un apartado donde veremos el listado completo de productos que
hemos añadido al carrito y podremos cambiar la cantidad que deseemos de cada producto, así como
quitar productos de la cesta. Esta funcionalidad también se realizará utilizando Javascript.
5.6.3.- Almacenamiento del Carrito.
El carrito de la compra también será almacenado con uno de los mecanismos de
almacenamiento en el lado del cliente que incorpora HTML5. En concreto, se hará uso de
localStorage, de forma que, si el usuario cierra el navegador web con productos almacenados en el
carrito, la próxima vez que se conecte a nuestra página, la información contenida en el carrito se
restaurará cargando el contenido del localStorage.

14
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

6- Sesión 2. Creación de los JSPs y Servlets para el manejo de los


productos.
6.1- Creación de un paquete Java.
Generalmente se suelen agrupar todas las clases Java que se crean para una aplicación web
en un paquete, de forma que, para su posterior uso, únicamente se debe importar ese paquete.
Vamos por tanto a crear un paquete para nuestra aplicación. Para ello seleccionamos “Source
Packages” y con el botón derecho seleccionamos Nuevo → Java Package, tal y como podemos ver
en la siguiente imagen:

Figura 6.1.1: Opción de creación de un paquete Java.

Le damos un nombre y pulsamos en “Terminar” como podemos ver a continuación:

Figura 6.1.2: Creación de un paquete Java.

15
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

A partir de este momento tendremos un paquete de nombre p2, dentro del cual crearemos
todas nuestras clases Java, los servlets y los javabeans necesarios para nuestra aplicación web.
6.2- Creación de la factoría para acceso a la base de datos.
Vamos a crear una clase factoría que contenga todas las operaciones que tengan que ver con
la base de datos, por ejemplo, el proceso de conexión a la base de datos, las consultas a la base de
datos, etc. Esta clase pertenecerá al paquete p2, por lo que pulsaremos con el botón derecho en el
paquete p2 y seleccionaremos Nuevo → Java Class, dándole el nombre AccesoBD y seleccionando
el paquete p2, tal y como podemos ver a continuación:

Figura 6.2.1: Creación de la clase AccesoBD.

Al crear la nueva clase se obtiene una clase java vacía:

package p2;

public class AccesoBD {


}

La cual debemos rellenar con los datos necesarios, inicialmente se va a definir una variable
singleton o instancia única, de forma que se garantice que tan solo se tiene una instancia de esta
clase a lo largo de nuestra aplicación [7]7:

package p2;
import java.sql.*;

public final class AccesoBD {


private static AccesoBD instanciaUnica = null;
private Connection conexionBD = null;

public static AccesoBD getInstance(){


if (instanciaUnica == null){
instanciaUnica = new AccesoBD();

7 A partir de este punto todo aquello que se añada al código anterior se resaltará en negrita.

16
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

}
return instanciaUnica;
}
}

A continuación, se rellenará la clase con los datos necesarios, en nuestro caso los datos de
conexión a la base de datos:

package p2;
import java.sql.*;

public final class AccesoBD {


private static AccesoBD instanciaUnica = null;
private Connection conexionBD = null;

public static AccesoBD getInstance(){


if (instanciaUnica == null){
instanciaUnica = new AccesoBD();
}
return instanciaUnica;
}

private AccesoBD() {
abrirConexionBD();
}

public void abrirConexionBD() {


if (conexionBD == null)
{ // daw es el nombre de la base de datos que hemos creado con anterioridad.
String nombreConexionBD = "jdbc:mysql://localhost/daw";
try { // root y sin clave es el usuario por defecto que crea XAMPP.
Class.forName("com.mysql.cj.jdbc.Driver");
conexionBD = DriverManager.getConnection(nombreConexionBD,"root","");
}
catch(Exception e) {
System.err.println("No se ha podido conectar a la base de datos");
System.err.println(e.getMessage());
}
}
}
}

Si deseamos comprobar que la conexión se realiza correctamente podemos añadir una nueva
función que, nos devuelva un booleano para indicar si ha sucedido la conexión o no8:

package p2;
import java.sql.*;

public final class AccesoBD {


private static AccesoBD instanciaUnica = null;
private Connection conexionBD = null;

8 En nuestro caso hemos creado la función comprobarAcceso() que devuelve true si la conexión se realiza o false en
caso contrario. Esta función de prueba puede eliminarse con posterioridad si así se desea.

17
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

public static AccesoBD getInstance(){


if (instanciaUnica == null){
instanciaUnica = new AccesoBD();
}
return instanciaUnica;
}

private AccesoBD() {
abrirConexionBD();
}

public void abrirConexionBD() {


if (conexionBD == null)
{ // daw es el nombre de la base de datos que hemos creado con anterioridad.
String nombreConexionBD = "jdbc:mysql://localhost/daw";
try { // root y sin clave es el usuario por defecto que crea XAMPP.
Class.forName("com.mysql.cj.jdbc.Driver");
conexionBD = DriverManager.getConnection(nombreConexionBD,"root","");
}
catch(Exception e) {
System.err.println("No se ha podido conectar a la base de datos");
System.err.println(e.getMessage());
}
}
}

public boolean comprobarAcceso() {


abrirConexionBD();
return conexionBD != null;
}
}

Únicamente para probar el funcionamiento de la clase anterior, crearemos un JSP para que
llame a la función comprobarAcceso(). El código de un sencillo JSP, llamado “comprobar.jsp”, que
ejecuta la llamada es el siguiente:

<%@page contentType="text/html" import="p2.*" pageEncoding="UTF-8"%>


<!DOCTYPE html>
<html lang="es">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Página de comprobación</title>
</head>
<body>
<%
AccesoBD con = AccesoBD.getInstance();
boolean res = con.comprobarAcces();
%>
<h1><%=res%></h1>
</body>
</html>

18
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Donde podemos ver que los delimitadores <% %> nos permiten integrar código Java dentro
del código HTML de la página. Además, los delimitadores <%= %> nos permiten integrar el
contenido de una variable Java dentro del código HTML de la página.

Si cambiamos ahora la página que se ejecuta al lanzar el proyecto, tal y como hemos visto
en el punto 5.4.2, por nuestra página “comprobar.jsp”, y ejecutamos la aplicación obtenemos la
siguiente página web:

Figura 6.2.2: Página web de respuesta de index.jsp.

Si no se consigue conectar correctamente con la base de datos debe detenerse el desarrollo


de la práctica y continuar en este punto hasta arreglar el problema, pues en caso contrario el resto de
la práctica no podrá probarse al no poder obtener los productos, etc., de la base de datos.

Por último, se definirá también la función cerrarConexiónBD(), de forma que se cierren las
conexiones de forma adecuada.

...
public void cerrarConexionBD()
{
if (conexionBD != null)
{
try{
conexionBD.close();
conexionBD = null;
}
catch(Exception e){ //Error en la conexión con la BD
System.err.println("No se ha completado la desconexión a la base de datos");
System.err.println(e.getMessage());
}
}
}

6.3.- Creación de la clase ProductoBD.


En la base de datos tendremos una tabla con los productos de nuestra tienda. En nuestra
aplicación web, en el apartado de productos, mostraremos ese listado de productos. Estos productos
se enviarán dentro de una estructura de datos denominada ProductoBD, que debemos definir por
medio de un javabean.

19
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Para crear el javabean pulsaremos sobre el paquete Java p2 y seleccionaremos Nuevo →


Java Class como podemos ver a continuación:

Figura 6.3.1: Creación de un javabean.

Un javabean debe contener un constructor sin argumentos, unos atributos privados y una
serie de funciones get() y set() para leer y asignar valores a esos atributos.

Por tanto, inicialmente crearemos los atributos necesarios, quedando el código del javabean
como puede verse a continuación9:

package p2;

public class ProductoBD{


private int id;
private String descripcion;
private float precio;
private int stock;
private String imagen;
}

Ahora deberíamos escribir el código de las funciones get() y set() para todos los atributos.
Sin embargo, podemos generarlos de forma automática seleccionando la opción Fuente → Insertar
código, apareciendo un cuadro de diálogo que permite incluir funciones get() y set() para los
elementos deseados, tal y como podemos ver a continuación:

9 A partir de este punto desarrollaremos todo el código suponiendo que se ha creado una base de datos donde los
campos tienen los atributos indicados en el apartado 5.2. Si se modifican esos tipos obviamente debe modificarse el
código aquí mostrado para adecuarlo al tipo de dato que se haya usado. Por ejemplo, si el campo “codigo” de los
productos se ha definido como CHAR en lugar de INTEGER, el tipo de dato de id debe ser String en lugar de int.

20
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 6.3.2: Creación automática de funciones get() y set().

Quedando el código final de la clase de la siguiente forma:

package p2;

public class ProductoBD {


private int id;
private String descripcion;
private float precio;
private int stock;
private String imagen;

public int getId() {


return id;
}
public void setId(int id) {
this.id = id;
}
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
public float getPrecio() {
return precio;
}
public void setPrecio(float precio) {
this.precio = precio;
}
public int getStock() {
return stock;
}
public void setStock(int stock) {

21
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

this.stock = stock;
}
public String getImagen() {
return imagen;
}
public void setImagen(String imagen) {
this.imagen = imagen;
}
}

6.4- Acceso al listado de productos.


Necesitamos poder acceder a los registros de la tabla en la base de datos que contiene los
productos que tenemos a la venta y mostrar los mismos en la página web adecuada. Para ello
modificaremos la clase que accede a la base de datos (AccesoBD) para añadir una nueva función
que permita realizar consultas sobre la base de datos, podemos llamar a esa función
obtenerProductosBD() y devolverá un elemento de tipo ArrayList, que contendrá una lista de
productos de la clase ProductoBD. Su código será similar al siguiente:

...
import java.util.*;
...
public List<ProductoBD> obtenerProductosBD() {
abrirConexionBD();

ArrayList<ProductoBD> productos = new ArrayList<>();

try {
String con;
Statement s = conexionBD.createStatement();
// hay que tener en cuenta las columnas de vuestra tabla de productos
// también se puede utilizar una consulta del tipo:
// con = "SELECT * FROM productos";
con = "SELECT codigo,descripcion,precio,existencias,imagen FROM productos";
ResultSet resultado = s.executeQuery(con);

while(resultado.next()){
producto = new ProductoBD();

producto.setId(resultados.getInt("codigo"));
producto.setDescripcion(resultados.getString("descripcion"));
producto.setPrecio(resultados.getFloat("precio"));
producto.setStock(resultados.getInt("existencias"));
producto.setImagen(resultados.getString("imagen"));

productos.add(producto);
}
}
catch(Exception e) {
System.err.println("Error ejecutando la consulta a la base de datos");
System.err.println(e.getMessage());
}

return productos;
}

22
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

...

Para que nuestro programa llame a la función y reciba la respuesta deberemos modificar el
fichero HTML que hicimos en la práctica 1 y convertirlo en un JSP que llame a esta función y
recoja el resultado de la consulta mostrándolo en el navegador. Un posible código del JSP
“productos.jsp” sería:

package p2;

<%@page import="java.util.List"%>
<%@page contentType="text/html" import="p2.*" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="es">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>&nbsp;</title>
</head>
<body>
<%
AccesoBD con = AccesoBD.getInstance();
List<ProductoBD> productos = con.obtenerProductosBD();
%>

<div>
<table>
<tr>
<th>Código</th>
<th>&nbsp;</th>
<th>Descripción</th>
<th>Precio</th>
<th>&nbsp;</th>
</tr>
<%
for(ProductoBD producto : productos){
int codigo = producto.getId();
String descripcion = producto.getDescripcion();
float precio = producto.getPrecio();
int existencias = producto.getStock();
String imagen = producto.getImagen();
%>
<tr>
<td><%=codigo%></td>
<td><img src="<%=imagen%>" alt="<%=descripcion%>">
<td><%=descripcion%></td>
<td><%=precio%></td>
<td>
<%
if (existencias > 0) {
%>
<input type="button" value="Añadir al carrito" onclick="__F__">
<%
}
else {
%>
&nbsp;

23
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

<%
}
%>
</td>
</tr>
<%
}
%>
</table>
</div>
</body>
</html>

Donde podemos ver como la página web se crea de forma dinámica con todos los productos
existentes en la base de datos mediante el bucle. En la página web mostrada falta el código del
evento onclick, (texto __F__) que debe añadirse para ir de esta página a la página
correspondiente.

Ahora es necesario modificar el código de todas las páginas que llamen a productos.html por
nuestra nueva página productos.jsp. Por ejemplo, hemos de modificar la página de inicio para que
llame a nuestro JSP en lugar del HTML estático:


<a href="#" onclick="Cargar('productos.jsp','cuerpo')">Productos</a>

Donde hemos sustituido “productos.html” por “productos.jsp”.


6.5- Acceso Usuario/Clave mediante Servlets y JSP.
Dentro de las funcionalidades de la aplicación web a realizar, se encuentra la necesidad de estar
registrado en el sistema para poder formalizar un pedido. También este acceso será necesario para poder
acceder al espacio de la aplicación dedicado al usuario, en el cuál puede ver sus datos y los pedidos
realizados.

Como ejemplo, vamos a implementar una versión simplificada de este mecanismo de acceso, que
será un documento jsp que detectará si el usuario se encuentra identificado. En caso afirmativo, permitirá
realizar, formalizar la compra o acceder al apartado de usuario de la página web. En caso negativo, se
mostrará un formulario para registrarse/identificarse.

Para comprobar si un usuario se encuentra registrado o no, se puede emplear una variable en el
entorno de sesión de la aplicación web. Por ejemplo, vamos a crear dentro de ese entorno, una variable
“usuario” que contendrá el nombre del usuario actualmente identificado, en el caso de que esa variable no
exista o no tenga contenido, supondremos que no hay ningún usuario identificado.

Si no hay ningún usuario identificado, se mostrará un formulario, el contenido del cual irá dirigido a
un servlet, que se encargará de procesar la información y de validarla haciendo uso de la base de datos.
Además, creará o rellenará la variable “usuario” del entorno de la sesión, redirigiendo la petición
nuevamente hacia la página jsp, donde esta vez, si el usuario se ha registrado correctamente, permitirá
realizar la acción adecuada (formalizar la compra o acceder al apartado del usuario), en caso contrario se
mostrará un mensaje señalando el error de autentificación y se procederá a mostrar nuevamente el formulario
de ingreso. A continuación, se muestra de forma esquemática este proceso:

24
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Apartado Usuario (jsp)

Si Mostrar Opciones
Usuario registrado Usuario (jsp)

No

Mostrar Formulario
(jsp)

ProcesarFormulario (servlet)
Figura 6.5.1: Esquema de la autenticación de un usuario.

Adicionalmente, también crearemos una variable “Mensaje” en el entorno de la sesión que


utilizaremos para intercambiar mensajes de error / ejecución con los jsp.
6.5.1 El documento JSP.
El documento JSP contendrá inicialmente un formulario que nos permita registrarnos e identificarnos
en nuestra aplicación web.

Figura 6.5.1.1: Formulario básico de acceso/registro a la tienda.

Primeramente crearemos un nuevo jsp dentro del directorio Web Pages, para ello,
colocándonos sobre ese directorio, elegiremos con el botón derecho del ratón la opción: “New →
JSP”. Le pondremos un nombre, por ejemplo, “login”, y pulsaremos finish. El código de “login.jsp”
es el siguiente:

<%@page language="java" import="p2.*" contentType="text/html" pageEncoding="UTF-8"%>


<!DOCTYPE html>
<html lang="es">
<head>

25
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">


<title>&nbsp;</title>
</head>
...

Inicialmente hemos especificado que estamos empleando el lenguaje Java y que vamos a
hacer uso del paquete p2 (creado en el apartado 2.1), dentro del cual definiremos los javabeans y
servlets de nuestra aplicación web. Adicionalmente también añadimos la librería de capas utilizada
en la práctica 1.

A continuación, se accede al entorno de la sesión en busca de algún mensaje enviado por el


servlet. Una vez leído el mensaje, es necesario eliminarlo, dado que sino, permanecería en el
entorno de la sesión hasta que se cerrara el navegador.

Después, se accede al entorno de la sesión en busca de un usuario registrado en la aplicación


web. Si no hay un usuario registrado, se mostrará un formulario para que se registre. Si ya existe un
usuario registrado se mostrarían las diferentes opciones del apartado de usuario. Los datos del
formulario de acceso se enviarán a LoginTienda, que será un servlet creado por nosotros encargado
de comprobar que ese usuario y clave existen en la BD.

...
<body>
<%
//Utilizamos una variable en la sesión para informar de los mensajes de Error
String mensaje = (String)session.getAttribute("mensaje");
if (mensaje != null) { //Eliminamos el mensaje consumido
session.removeAttribute("mensaje");
%>
<h1> <%=mensaje%> </h1>
<%
}
//Se obtiene el usuario actual registrado en el servicio web, del entorno de sesión
String usuarioActual = (String)session.getAttribute("usuario");

if (usuarioActual == null) //No hay usuario registrado


{ //Mostramos el formulario para la introducción del usuario y la clave
%>
<form method="post" onsubmit="ProcesarForm(this,'LoginTienda','cuerpo');return false" >
Usuario: <input name="usuario" type="text"/> <br/><br/>
Contrase&ntilde;a : <input name="clave" type="password"/> <br/><br/>
<input type="radio" name="tipoAcceso" value="Acceso" checked="checked"/> Acceso
<input type="radio" name="tipoAcceso" value="Registro"/> Registro <br/><br/>
<input type="submit" value="Entrar a la Tienda Virtual"/>
</form>
<%
}
else {
//Si existe un usuario, se mostrará las opciones del apartado del usuario
%>
<p>Mostraríamos las diferentes opciones</p>
<%
}
%>

26
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

</body>
</html>

NOTAS:

1. Se debe sustituir el código del formulario por aquel que hayáis desarrollado en la práctica 1.
2. El formulario hace uso de la función “ProcesarForm”, que al igual que la función “Cargar”
se encuentra en el fichero javascript “libCapas2021.js”.
3. La función ProcesarForm() enviará el formulario a un destino, en este caso, a la url del
servlet “LoginTienda”, y el resultado que devuelva ese servlet lo mostrará en una capa, en
este caso “cuerpo”.
6.5.2. El servlet
A continuación, crearemos el servlet con el que procesaremos la información del formulario
incluido en “login.jsp”. Para ello, pulsaremos con el botón derecho del ratón sobre el paquete p2, y
seleccionamos: New->Servlet. Le damos un nombre, por ejemplo, LoginTienda, y como paquete el
paquete creado anteriormente en el apartado 1.6.4, en este caso p2. Pulsamos en siguiente.

Figura 6.5.2.1: Creación del servlet para procesar la información de acceso a la tienda.

Seleccionamos la casilla “Add information to deployment descriptor (web.xml)”, esto será


necesario en el caso de que queremos instalar nuestro servicio web en otro servidor que no esté
gestionado directamente por el Netbeans. Si no se activa la casilla, es probable que el Netbeans no
sea capaz de encontrar los servlets y ejecutarlos. Modificaremos la URL Pattern por /loginTienda y
pulsamos Finish para terminar:

27
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 6.5.2.2: Opción a seleccionar para añadir la información del servlet al fichero
web.xml.

De esta forma se habrá creado un servlet con las funciones básicas, entre ellas, la función
processRequest que es la que se va modificar, la cual es llamada desde las funciones doGet y
doPost, que son los dos métodos de envío existentes en HTTP que vamos a implementar.

Dado que vamos a realizar las mismas acciones independientemente del modo en que nos
lleguen los datos del formulario (modo GET o POST), en las funciones doGet o DoPost únicamente
realizaremos una redirección a la función processRequest, y en esa función implementaremos la
funcionalidad del servlet. Como NetBeans rellena por defecto la función con una página web, habrá
que borrar el contenido e implementar la funcionalidad adecuada.

En este caso, esa funcionalidad se basa en recoger el usuario y la clave enviados con el
formulario, y comprobar si existen en la base de datos. En caso afirmativo, permitiremos el acceso
al apartado del usuario, en caso negativo, se nos volverá a pedir que introduzcamos el usuario y el
password.

En el caso de que el usuario sea correcto, se introducirá una variable “usuario” en el entorno
de la sesión que almacenará ese nombre de usuario, lo que le permitirá saber al jsp al que se redirige
la petición, que un usuario se ha introducido correctamente.

En caso de usuario incorrecto, no introduciremos la variable en el entorno de sesión, por lo


que en el jsp obtendremos ‘null’ al tratar de obtener su valor, de forma que permitirá saber que el
usuario introducido es incorrecto. Se puede introducir en el entorno de sesión la variable “Mensaje”,
que contendrá la información asociada al error, por ejemplo, “Usuario y/o password incorrecto”.
Esta variable “Mensaje” se lee al inicio del documento jsp especificado en el apartado 6.5.110.

El código es el siguiente. Como vemos, el servlet pertenecerá al paquete p2. Además, será
necesario el import “HttpSession”, para acceder al entorno de sesión de la aplicación web.

10 En este ejemplo solo implementamos la lógica que permite comprobar si un usuario/clave es correcto. En el
programa a desarrollar debe implementarse también la lógica que permita realizar el registro de nuevos usuarios.

28
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

package p2;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; //Para acceder al entorno de sesión
...

A continuación, mostramos el código de la función processRequest, en la que inicialmente


obtendremos el nombre y la clave introducidos por el usuario en el formulario, y también
definiremos una conexión con el entorno de sesión de la aplicación web.


protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

String usuario = request.getParameter("usuario"); //Se obtiene el nombre de usuario


String clave = request.getParameter("clave"); //Se obtiene la clave de usuario del formulario
HttpSession sesion = request.getSession(true); //Se accede al entorno de la sesión

A continuación, se comprueba si el usuario y la clave proporcionados por el cliente se


encuentran en la BD, para ello se va a utilizar la clase java definida en el apartado 2.2, en la cual se
realizarán todas las operaciones relacionadas con la base de datos.

Esa clase dispondrá de una función comprobarUsuarioBD, que tendrá como parámetros un
usuario y una clave, y devolverá como respuesta true, si existe un par usuario/clave definido en la
base de datos, o false en caso contrario.

El código del servlet continuaría de la siguiente forma:


AccesoBD con = AccesoBD.getInstance(); //Instancia de la clase factoría AccesoBD

if ((usuario != null) && (clave!=null)) //Se si se han pasado usuario y clave


{
if (con.comprobarUsuarioBD(usuario, clave)) // Se comprueba en la base de datos
{ // Registramos al usuario en el entorno de la sesión
sesion.setAttribute("usuario", usuario);
}
else // El usuario/clave no se encuentra en la BD
{ // Registramos el error en el entorno de la sesión
sesion.setAttribute("mensaje","Usuario y/o clave incorrectos");
}
}
else
{ // Registramos el error en el entorno de la sesión
sesion.setAttribute("mensaje", "Falta introducir el usuario o la clave");

29
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

}

Por último, se redirige la petición al jsp de login.


response.sendRedirect("login.jsp"); //Redirigimos la petición a la página de login
}

NOTA: El código habrá que adaptarlo conveniente a las páginas web realizadas, dirigiendo la
redirección a la página adecuada.
6.5.3. La función comprobarUsuarioBD de la clase AccesoBD
En el apartado 6.2, se definió la clase AccesoBD para contener todas aquellas operaciones
que tengan que ver con la base de datos, entre ellas, se encontrará el proceso de conexión con la
base de datos y las diferentes consultas que se tengan que realizar en ella. Debemos definir una
nueva función comprobarUsuarioBD() que debe comprobar si el par usuario/clave existe en la base
de datos y en caso afirmativo devolver true, devolviendo false en caso contrario. El código de la
función comprobarUsuarioBD() será similar al siguiente:

public boolean comprobarUsuarioBD(String usuario, String clave) {


abrirConexionBD();

try{
String con;
Statement s = conexionBD.createStatement();
// Consulta, buscamos una correspondencia usuario/clave
con = "SELECT * FROM usuarios WHERE usuario='" + usuario + "' and clave='" + clave + "'";
ResultSet resultado = s.executeQuery(con);
if ( resultados.next() ) // El usuario/clave se encuentra en la BD
{
return true;
}
else // El usuario/clave no se encuentra en la BD
{
return false;
}
}
catch(Exception e) { // Error en la conexión con la BD
System.err.println("Error verificando usuaro/clave");
System.err.println(e.getMessage());
return false;
}
}

30
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

7- Sesión 3. Formalizar la compra.


Una vez el cliente ha seleccionado los productos que desea comprar (sesión 1) y ha accedido
al sistema con su usuario y su clave (sesión 2), podemos proceder a formalizar la compra con el
siguiente esquema de funcionamiento:

Carrito (JSP) Inicio (JSP)


Procesar datos de envío
y cobro del pedido

recogerCarrito (servlet)

Cancelar pedido Mostrar resguardo Nuevo pedido

Resguardo (jsp)

Tramitar pedido

Tramitación (servlet) Pedido finalizado (JSP)


Figura 7.1: Esquema de formalización de una compra.

Para formalizar el pedido los datos del carrito de la compra se enviarán a un servlet
(recogerCarrito) a través de una llamada ajax EnviarCarrito(url, capa, carrito).

Una versión de la función EnviarCarrito se encuentra en la librería “libCapas2021.js”. Esta


función genera un JSON que debe ser procesado en el servlet, en el apartado de ayuda se especifica
un ejemplo, el cuál debe ser adaptado a vuestro javabean creado para almacenar productos (ver
apartado 7.1).

El servlet recogerCarrito, se encargará de comprobar que los datos sean correctos (que haya
stock disponible de los productos comprados, por ejemplo) y redirigirá la petición a un documento
JSP (resguardo) que mostrará los datos de la compra y los datos de envío y facturación, junto con
dos botones, uno para llevar a cabo la compra y otro para cancelarla.

En este JSP (resguardo) se permitirá modificar los datos de usuario relacionados con el
envío de la compra (dirección, código postal, etc.), y de pago (tarjeta de crédito, contrarreembolso,
etc.). Los datos que estén previamente almacenados en la base de datos, como nombre, dirección,
etc., deben aparecer en el formulario por defecto. Asimismo, aparecerá el listado de productos a
comprar.

Si se decide tramitar el pedido se pasará a un servlet (Tramitación) que guardará la


información del pedido en la base de datos y redirigirá la petición a otro documento JSP (pedido
finalizado) que indicará que todo el proceso de la compra ha concluido satisfactoriamente y que,
adicionalmente, deberá eliminar todos los elementos del carrito de la compra al ya haberse
efectuado la misma.

31
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

7.1.- Creación de la clase Producto.


La cadena de texto JSON que almacena los productos del carrito de la compra, y que se
envían al servlet, se convertirá en un vector de productos, donde de cada producto se debe
almacenar, como mínimo, el identificador del producto, su nombre, su precio y la cantidad
seleccionada. Para ello debemos definir un javabean denominado “Producto”, con la estructura de
datos adecuada.

Para crear el javabean pulsaremos sobre el paquete Java p2 y seleccionaremos Nuevo →


Java Class como podemos ver a continuación:

Figura 7.1.1: Creación de un javabean.

Un javabean debe contener un constructor sin argumentos, unos atributos privados y una
serie de funciones get() y set() para leer y asignar valores a esos atributos.

Por tanto, inicialmente crearemos los atributos necesarios, quedando el código del javabean
como puede verse a continuación:

package p2;

public class producto {


private int id;
private String nombre;
private float precio;
private int cantidad;
}

Ahora deberíamos escribir el código de las funciones get() y set() para todos los atributos.
Sin embargo, podemos generarlos de forma automática seleccionando la opción Fuente → Insertar
código, apareciendo un cuadro de diálogo que permite incluir funciones get() y set() para los
elementos deseados, tal y como podemos ver a continuación:

32
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Figura 7.1.2: Creación automática de funciones get() y set().

Quedando el código final de la clase de la siguiente forma:

package p2;

public class Producto {


private int id;
private String nombre;
private float precio;
private int cantidad;

public int getId() {


return id;
}
public void setId(int id) {
this.id = id;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public float getPrecio() {
return precio;
}
public void setPrecio(float precio) {
this.precio = precio;
}
public int getCantidad() {
return cantidad;
}
public void setCantidad(int cantidad) {
this.cantidad = cantidad;
}

33
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

34
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

8- Sesión 4. Opciones de administración del usuario.


En esta última sesión proporcionaremos al usuario una serie de herramientas para gestionar
sus datos y sus pedidos. El usuario tendrá la posibilidad de ver sus datos, sus pedidos y
modificarlos, por lo que el usuario tendrá las siguientes opciones:

 Listar y modificar los datos personales.


 Listar y cancelar los pedidos realizados.
 Cerrar la sesión.

Cabe tener en cuenta que los pedidos pueden tener diferentes estados (procesando, enviado,
recibido, …), por lo tanto, el cliente tan sólo podrá cancelar un pedido siempre y cuando este
todavía no haya sido enviado.

En esta sesión el alumno debe realizar todos los JSP y servlets que necesite para
implementar las funcionalidades indicadas con anterioridad. No se os facilita ningún esquema pues
a esta altura de la práctica debéis ser capaces de identificar claramente los JSP y/o servlets que
necesitáis para cada una de las opciones.

Por último, se os indica que para poder acceder a todas esas opciones el usuario debe
haberse identificado ante la aplicación, por lo que en caso de que no lo haya hecho se debe seguir el
mismo esquema que en el punto 6.5.

35
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

9- Aspectos generales de la práctica.


Los puntos anteriores son una guía para la realización de la práctica. A lo largo de su
desarrollo puede ser necesario introducir nuevos elementos (jsp, servlets, javabean) no
especificados en el enunciado de la misma. Además, no es necesario seguir el diseño de clases ni
los diagramas de flujo comentados, debiendo emplearse solo como orientación.
9.1- Tablas de la base de datos.
Para llevar a cabo todos los procesos anteriores será necesario crear las tablas oportunas en
la base de datos de forma que permitan:

 Almacenar los productos de nuestra tienda: producto, descripción, precio, stock, etc.
 Gestionar el acceso de los usuarios a la tienda virtual: usuario, clave.
 Almacenar información de los usuarios: nombre, apellidos, dirección, etc.
 Almacenar la información de los pedidos realizados: productos, unidades, etc.

Para acceder a la base de datos se requerirá definir consultas SQL. Algunos ejemplos de
consultas SQL para diferentes acciones son:

 Búsqueda de información:

String con = "SELECT * FROM productos";


String con = "SELECT * FROM usuarios WHERE usuario='" + usuario + "' AND clave='" + clave + "'";

 Inserción de información:

String con = "INSERT INTO usuarios(id,usuario,clave) VALUES (NULL,'" + usuario + "','" + clave +
"');

 Modificación de información:

String con = "UPDATE productos SET unidades = '" + unidades + "' WHERE id='" + id + "'";

 Eliminación de información:

String con = "DELETE FROM usuarios WHERE usuario='" + usuario + "' AND clave='" + clave + "'";

Para ejecutar las sentencias SQL se deberá utilizar la función executeQuery() para las
sentencias que tengan como resultado la obtención de datos (select), y executeUpdate() para
aquellas que tengan como resultado la modificación de la información (insert, update y delete).

Statement s = conexionBD.createStatement();

// definición de la consulta “con”

// Para obtener información
ResultSet resultado = s.executeQuery(con);

36
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

// Para modificar
int filas = s.executeUpdate(con);

9.2- Prohibiciones.
Dado que se va a seguir el modelo MVC no se permite el uso de “out” tanto en las páginas
JSP como en los servlets, por lo que los servlets no crearan contenido visual (no enviarán nada con
response). Por tanto, está prohibido usar:

response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("...");

En los JSP tampoco se permite el uso de out.println("…"), sino que se deberá utilizar el
delimitador <%=variable%>.
9.3- Recomendaciones.
A la hora de codificar en Java, se recomienda seguir las pautas seguidas en las Java Code
Conventions [9]. Así por ejemplo las clases siempre deben empezar por sustantivo en mayúsculas,
mientras que las variables y métodos de las clases deben empezar por verbo en minúsculas.

Además un código Java bien documentado haciendo uso de Javadoc, ayudar a ser
compartido y mantenido por los miembros de un equipo de desarrolladores (pareja en el caso de las
prácticas de la asignatura).
9.4- Entrega y evaluación.
La corrección de la práctica 2 se realizara comprobando el correcto desarrollo y
funcionamiento de la práctica. El alumno tendrá una sesión de defensa de la práctica con el profesor
en la cuál se le podrá requerir que explique aquellos elementos que el profesor considere relevantes,
entre ellos:

• Creación y manejo del carrito (apartado 5.6).


◦ Se puede añadir un producto nuevo.
◦ Si se añade un producto ya existente se incrementa su cantidad automáticamente.
◦ Se puede modificar la cantidad.
◦ Se puede eliminar el producto.
◦ Se almacena correctamente con localStorage y se recupera al volver a abrir el navegador.
• Carga de los productos desde la base de datos (apartados 6.2, 6.3 y 6.4).
◦ Se cargan los productos de la base de datos correctamente.
◦ Aparece la opción de añadir solo para los productos de los que hay existencias.
◦ Se controlan correctamente los posibles errores en el acceso a la base de datos.
• Login del usuario (apartado 6.5)
◦ Funciona correctamente el login.
◦ Se crea una variable de sesión razonable, esto es, que contenga el id del usuario o bien
su nombre de usuario (suponemos que el nombre de usuario es un campo UNIQUE).
◦ Se muestra un mensaje de error si el usuario o clave que se proporciona no es correcto.
◦ Se controlan correctamente los posibles errores en el acceso a la base de datos.
◦ Se previene la inyección de código SQL utilizando PreparedStatement.

37
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

• Registro de un usuario nuevo (apartado 6.5)


◦ Se solicitan todos los datos necesarios.
◦ Se comprueba que no se dejen vacíos los campos necesarios.
◦ Se añade correctamente en la base de datos el nuevo usuario.
◦ Se reenvía a la página de login una vez añadido el usuario.
◦ Se controlan correctamente los posibles errores en la inserción en la base de datos.
◦ Se previene la inyección de código SQL utilizando PreparedStatement.
• Tramitación de la compra (apartado 7).
◦ Se comprueba que no se solicita más cantidad de un producto que la existente.
◦ Se ha utilizado o modificado correctamente el código que se ha proporcionado para
procesar el JSON.
◦ Se crean adecuadamente los productos solicitados en el resguardo de compra.
◦ Se crean adecuadamente los datos de envío del pedido en el resguardo de compra.
◦ Se pueden modificar los datos de envío del pedido en el resguardo de compra.
◦ Se solicitan los datos de pago de la compra (tarjeta de crédito o transferencia).
◦ Se añade correctamente el pedido en la base de datos.
◦ Se añade correctamente el detalle del pedido en la base de datos.
◦ Se devuelve algún valor de referencia del pedido cuando se finaliza su tramitación.
◦ Se elimina el carrito de productos, tanto de memoria como del localStorage, cuando se
termina la compra.
◦ Se controlan correctamente los posibles errores en las consultas o inserciones en la base
de datos.
◦ Se previene la inyección de código SQL utilizando PreparedStatement.
• Logout (apartado 8→ Cerrar la sesión).
◦ Se destruyen las variables de sesión correctamente.
◦ Se reenvía a otra página web.
• Modificación de los datos del usuario (apartado 8→ Datos personales).
◦ Se cargan correctamente los datos personales del usuario.
◦ Se bloquean (o no se muestran) aquellos datos que no se pueden modificar como el id
del usuario o su nombre de usuario.
◦ Se puede modificar la contraseña con comprobación de validez (doble petición, en dos
campos por ejemplo).
◦ Se modifican adecuadamente los datos en la base de datos.
◦ Se controlan correctamente los posible errores en las consultas o inserciones en la base
de datos.
◦ Se previene la inyección de código SQL utilizando PreparedStatement.
• Modificación de los pedidos (apartado 8 → Pedidos realizados).
◦ Se cargan correctamente los pedidos de los usuarios.
◦ Se cargan correctamente los detalles de los pedidos.
◦ Se permite cancelar únicamente los pedidos que aún no se han enviado o entregado.
◦ Se cancelan adecuadamente los pedidos.
◦ Se controlan correctamente los posibles errores en las consultas o inserciones en la base
de datos.
◦ Se permite que se cancele solamente algún producto de un pedido.
◦ Se previene la inyección de código SQL utilizando PreparedStatement.

38
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

Todos los puntos en color rojo deben cumplirse para que la práctica pueda considerarse
correcta. Los puntos en color verde son mejoras que el alumno puede realizar en la misma.

El alumno deberá subir a aulavirtual, antes de la fecha indicada, un fichero comprimido en


formato ZIP o RAR que deberá contener:

• Exportación de la base de datos utilizada durante el desarrollo del programa. La exportación


se deberá realizar mediante la opción “Exportar” de phpmyadmin.

• Exportación del proyecto de la práctica realizada mediante la opción de exportación del


proyecto a ZIP del entorno de desarrollo NetBeans. Dicha opción se ejecuta como File →
Export Project → To ZIP.
9.5- Duración.
4 sesiones.
9.6- Ayuda.
En aula virtual podéis descargar el fichero “libCapas2021.js”, que contiene un conjunto de
funciones en javascript que permiten cargar páginas web dentro de Capas html (definidas con
<div>). La forma de uso de esas funciones es la siguiente:

 Cargar url local (Ej0.html) en una capa (con el nombre capa1), a través de un enlace (<a>)
del menú:

<a href="#" onclick="Cargar('Ej0.html','capa1')">


Título Menú Enlace 1
</a>

 Cargar la respuesta obtenida de un formulario en una capa. Esta función será útil para la
práctica 2, donde nos permitirá mostrar la respuesta que nos envié un servlet en la capa que
deseemos. En este ejemplo, el formulario se enviará al servlet registro, y lo que nos
devuelva ese servlet se mostrará en la capa con el nombre “capa1”).

<form method="post" onsubmit="ProcesarForm(this,'Registro','capa1'); return false">


... //Elementos del formulario
</form>

 Enviar el contenido del carrito de la compra a un servlet. Esta función convierte el array
asociativo donde se almacena los productos del carrito de la compra en una cadena JSON y
la envía como formato de formulario (atributo1=valor1&atributo2=valor2, …), de forma
que el servlet pueda obtener ese JSON a través del parámetro “carrito” de un formulario.
Esta función será útil para la sesión 3 de la práctica 2, donde se debe llevar a cabo la compra
del contenido del carrito. En este ejemplo, se ha definido un botón que llama a la función
RecogerCarrito, pasándole como parámetros el servlet que va a recibir esa información, la
capa donde se cargará la respuesta que proporcione el servlet, y el vector que contiene los
productos almacenados en el carrito.

39
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

<button id="comprar" onclick="EnviarCarrito('recogerPedido','cuerpo',carrito)"> Comprar </button>

El código actual de la función EnviarCarrito es el siguiente:

function EnviarCarrito(url, capa, valores)


{
var contenido = document.getElementById(capa);
var conexion = nuevaConexion();

conexion.open("POST", url,true);
conexion.onreadystatechange=function()
{
if((conexion.readyState == 4) && (conexion.status == 200))
{
contenido.innerHTML = conexion.responseText;
invokeScript(document.getElementById(capa));
}
}
conexion.setRequestHeader('Content-Type','application/json; charset=utf-8');
conexion.send(JSON.stringify(valores));
}

 Para procesar la cadena JSON en el servlet es necesario utilizar una librería específica.
Existen múltiples librerías, una de ellas, JSON-P, está incluida en el propio estándar de Java.
Un ejemplo de su uso sería el siguiente:
import javax.json.Json;
import javax.json.JsonObject;
import javax.json.JsonReader;
import javax.json.stream.JsonParser;
import javax.json.stream.JsonParser.Event;
import java.util.Iterator;
import java.util.ArrayList;
...
ArrayList <Producto> carrito = new <Producto>ArrayList();

JsonReader jsonReader = Json.createReader(


new InputStreamReader(request.getInputStream()));
JsonObject jobj = jsonReader.readObject();

for (String key : jobj.keySet()) { // Se recorren todos los productos pasados en el JSON
JsonObject prod = (JsonObject)jobj.getJsonObject(key);

Producto nuevo = new Producto();


nuevo.setId(Integer.parseInt(prod.getString("id")));
nuevo.setNombre(prod.getString("nombre"));
nuevo.setPrecio(Float.parseFloat(prod.getString("precio").toString()));
nuevo.setCantidad(Integer.parseInt(prod.getString("cantidad").toString()));

carrito.add(nuevo);
}

40
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

En este código, se obtiene la cadena almacenada en el JSON que contiene los productos que
queremos comprar, y se recorren sus elementos, almacenándose en un ArrayList de
“Producto”. Un ejemplo del formato de la cadena JSON que puede procesar es el siguiente:

{
"1":{
"id":"1",
"nombre":"Elemento 1 del carrito",
"cantidad":1,
"precio":100.0
},
"2":{
"id":"2",
"nombre":"Elementos 2 del carrito",
"cantidad":3,
"precio":120.5
}
}

El tipo Producto está definido en la clase javabean especificada en el apartado 7.1 de la


práctica. Por supuesto, el código deberá ser adaptado al formato del objeto que se haya
definido y por tanto, al formato del JSON que se pasará a la función.

41
Desarrollo de Aplicaciones Web Creación de aplicaciones web siguiendo el...

10- Referencias
1. Burbeck, Steve, “Applications Programming in Smalltalk-80™: How to use Model-View-
Controller (MVC),” in Smalltalk-80 v2.5, 1992 [Online]. Available:
https://www.researchgate.net/publication/238719652_Applications_programming_in_smalltal
k-80_how_to_use_model-view-controller_mvc
2. A. Leff and J. T. Rayfield, “Web-application development using the Model/View/Controller
design pattern,” in Proceedings Fifth IEEE International Enterprise Distributed Object
Computing Conference, 2001, pp. 118–127 [Online]. Available:
http://dx.doi.org/10.1109/EDOC.2001.950428
3. Oracle, “Java Servlet Technology.”
Visitado a 23/2/2020 en https://www.oracle.com/technetwork/java/index-jsp-135475.html ,
2019.
4. Oracle, “JavaServer Pages Technology.”
Visitado a 23/2/2020 en https://www.oracle.com/technetwork/java/index-jsp-138231.html ,
2019.
5. Oracle, “JavaBeans Technology.”
Visitado a 1/3/2020 en https://www.oracle.com/technetwork/java/javase/tech/index-jsp-
138795.html , 2019.
6. Oracle, “MySQL.”
Visitado a 1/3/2020 en https://www.mysql.com , 2019.
7. E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design patterns: elements of reusable
object-oriented software. Addison-Wesley, 1994.
8. Oracle, “JDBC Technology.”
Visitado a 1/3/2020 en https://www.oracle.com/technetwork/java/javase/jdbc/index.html ,
2019.
9. Sun Microsystems, “Java Code Conventions.”
Visitado a 1/3/2020 en https://www.oracle.com/technetwork/java/codeconventions-
150003.pdf, 1997.

42

También podría gustarte