Professional Documents
Culture Documents
Mdulo 1
Objetivo
El objetivo de esta prctica es implementar la separacin de capas usando el patrn de
Arquitectura MVC (Modelo, Vista y Controlador) en los Servlets utilizando el IDE
NetBeans.
"Quemar etapas"
Es importante que
saques provecho de cada
mdulo y consultes
todos los temas que se
van tratando, sin
adelantar etapas.
Aclaracin importante: los patrones de diseo son "la mejor solucin encontrada para
resolver un problema genrico y recurrente", pero, la solucin es una "gua" y no un
"manual" para resolver un problema especfico, ya que cada contexto tendr sus
particularidades. Servlet "implementa su versin" del patrn de diseo, por lo tanto
no significar nunca que lo que veamos de Servlet es sinnimo puro de MVC, en realidad
veremos que existen muchos frameworks que implementan su propia versin del patrn,
y todas estarn correctas.
hola-mundo-servlet-mvc->Source Packages->com.formacionbdi.servlets.saludar
/** ETC...*/
response.setContentType("text/html;charset=UTF-8");
/** ETC...*/
hola-mundo-servlet-mvc->Source Packages->com.formacionbdi.servlets.saludar
/** ETC...*/
protected void processRequest(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
14. Modificamos en contenido que viene por defecto segn el cdigo de abajo:
</body>
</html>
AUTOR: Andrs Guzmn Fontecilla. 13
Email: andresguzf@gmail.com
WEB: http://www.bolsadeideas.com
LICENCIA: http://creativecommons.org/licenses/by-nc/4.0 | Arquitectura MVC Servlet
Curso: "Java EE 7 y Frameworks" 2017
package models;
/**
* @author Andrs Guzmn F
*/
public class Producto {
private int id;
private String nombre;
private int precio;
public Producto() {
}
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Andrs Guzmn F
*/
public class CatalogoDb {
public CatalogoDb() {
productos.add(new Producto(1, "Panasonic Pantalla LCD", 259990));
productos.add(new Producto(2, "Sony Cmara digital DSC-W320B", 123490));
productos.add(new Producto(3, "Apple iPod shuffle ", 69990));
productos.add(new Producto(4, "Sony Notebook Z110 ", 1499990));
productos.add(new Producto(5, "Hewlett Packard Multi F2280", 37990));
productos.add(new Producto(6, "Bianchi Bicicleta Aro 26", 69990));
productos.add(new Producto(7, "Mica Cmoda 5 Cajones", 69990));
productos.add(new Producto(8, "Movistar Celular Nokia X6 ", 299990));
}
if (producto.getId() == id) {
resultado = producto;
break;
}
}
return resultado;
}
}
package controllers;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import models.CatalogoDb;
/**
* Web application lifecycle listener.
*
* @author Andrs Guzmn F
*/
public class CatalogoEventListener implements ServletContextListener {
ServletContext servletContext;
servletContext = sce.getServletContext();
servletContext.setAttribute("catalogoDb", new CatalogoDb());
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
modelo = (CatalogoDb) config.getServletContext()
.getAttribute("catalogoDb");
}
Adems vamos a abrir y ejecutar una aplicacin web con base de datos, analizaremos
y estudiaremos el cdigo que nos permite construir un sistema CRUD/Crear, actualizar,
Borrar y Listar MVC con Sevlet/JSP (Un mantenedor de Productos) utilizando
NetBeans IDE.
5. Luego, clic derecho sobre el string de conexin (ya con conexin) y seleccionar
Execute Command.
INSERT INTO productos (nombre, precio, cantidad) VALUES('Panasonic Pantalla LCD', 259990, 20);
INSERT INTO productos (nombre, precio, cantidad) VALUES('Sony Cmara digital DSC-W320B', 123490, 12);
INSERT INTO productos (nombre, precio, cantidad) VALUES('Apple iPod shuffle', 1499990, 25);
INSERT INTO productos (nombre, precio, cantidad) VALUES('Sony Notebook Z110', 37990, 10);
INSERT INTO productos (nombre, precio, cantidad) VALUES('Hewlett Packard Multifuncional F2280', 69990,
7);
INSERT INTO productos (nombre, precio, cantidad) VALUES('Bianchi Bicicleta Aro 26', 69990, 5);
INSERT INTO productos (nombre, precio, cantidad) VALUES('Mica Cmoda 5 Cajones', 299990, 20);
Listo ;-)
Nuestra aplicacin debe ser capaz de obtener los datos y de persistirlos en algn lugar,
pero no tiene por qu saber de dnde los est sacando o dnde se almacenan.
Hay una forma de hacer esto que ha resultado bastante eficiente en el mundo JEE y de
aplicaciones web, pero que es aplicable a cualquier tipo de aplicacin que deba
recuperar los datos de algn sitio y almacenarlos. Es lo que se conoce como patrn
DAO (Data Access Object).
La idea de este patrn es sencilla. En primer lugar, debemos crear las clases que
representan nuestros datos, las entidades. Por ejemplo, podemos escribir una clase
Producto implementada con JDBC de Java, pero ya la tenemos! Ms adelante veremos
cmo implementarla con el ORM Hibernate.
Luego creamos una interface. Esta interface tiene que tener los mtodos necesarios
para obtener y almacenar los productos (contrato de implementacin) con las
operaciones bsicas que tpicamente son: listar, obtener por id, guardar, eliminar etc.
Entonces resumiendo un DAO es simplemente una clase del modelo que se encarga
de implementar las operaciones bsicas de acceso a datos que debe implementar un
contrato, la interfaz.
package models.dao;
import java.util.List;
import models.entity.Producto;
Entonces una clase DAO (Data Access Object) nos permite disponer de las
funcionalidades y operaciones bsicas como actualizar, crear, eliminar, listar y ver
detalle. Para este ejemplo vamos a implementar de manera muy simple la clase de
Modelo DAO ProductoDao que usa la clase de modelo Producto (Entity), donde una
clase Entity representa los datos o registros de una tabla en la base de datos.
package models.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import util.ConexionJdbc;
import models.entity.Producto;
if (conn == null) {
conn = new ConexionJdbc().getConnection();
}
return conn;
}
try {
getConnection().close();
conn = null;
} catch (SQLException e) {
e.printStackTrace();
@Override
public List<Producto> listar() {
lista.add(producto);
}
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeConnection();
}
return lista;
}
@Override
public Producto buscarPorId(int id) {
Producto producto = null;
try {
PreparedStatement stmt = getConnection().prepareStatement(
"SELECT * FROM productos WHERE id = ?");
stmt.setInt(1, id);
ResultSet resultado = stmt.executeQuery();
if (resultado.next()) {
producto = new Producto();
producto.setId(resultado.getInt("id"));
producto.setNombre(resultado.getString("nombre"));
producto.setPrecio(resultado.getInt("precio"));
producto.setCantidad(resultado.getInt("cantidad"));
}
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
AUTOR: Andrs Guzmn Fontecilla. 45
Email: andresguzf@gmail.com
WEB: http://www.bolsadeideas.com
LICENCIA: http://creativecommons.org/licenses/by-nc/4.0 | Arquitectura MVC Servlet
Curso: "Java EE 7 y Frameworks" 2017
closeConnection();
}
return producto;
}
@Override
public void guardar(Producto producto) {
try {
PreparedStatement stmt = null;
if (producto.getId() > 0) {
String sql = "UPDATE productos SET nombre=?,precio=?,cantidad=?
WHERE id=?";
stmt = getConnection().prepareStatement(sql);
stmt.setInt(4, producto.getId());
} else {
String sql = "INSERT INTO productos(nombre, precio, cantidad)
VALUES (?,?,?)";
stmt = getConnection().prepareStatement(sql);
}
stmt.setString(1, producto.getNombre());
stmt.setInt(2, producto.getPrecio());
stmt.setInt(3, producto.getCantidad());
stmt.executeUpdate();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeConnection();
}
}
@Override
public void eliminar(Producto producto) {
try {
PreparedStatement stmt = getConnection().prepareStatement(
"DELETE FROM productos WHERE id=?");
stmt.setInt(1, producto.getId());
stmt.executeUpdate();
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeConnection();
}
}
}
Podemos observar, en primer lugar, que hacemos uso del modelo Producto. Vamos a
utilizar este objeto para implementar las operaciones en la tabla de base de datos de
nuestros productos. La instancia de ProductoDao contiene el objeto de Conexin a la
Base de datos mediante el API JDBC.
El mtodo obtenerTodos() retorna todos los objetos productos desde la base de datos
como un List, PreparedStatement es usado para preparar las consultas y luego ejecutar
las operaciones de la base de datos, el objeto ResultSet es usado para recorrer un
cursor retornando cada uno de los registros, por pada registro se crea un objeto entity
Producto y se almacena en la lista, al final se retorna el resultado como una lista de
objetos del tipo Producto.
@WebServlet("/catalogo/listado")
public class ListadoController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("productos", lista);
request.setAttribute("titulo", "Listado de Productos");
request.getRequestDispatcher("/WEB-INF/views/listado.jsp")
.forward(request, response);
}
}
<%@page import="models.entity.Producto"%>
<%@page import="java.util.List"%>
<h3><%=titulo%></h3>
<a href="<%=request.getContextPath()%>/catalogo/form">crear producto</a>
<table border="0">
<tr>
<th>Id</th>
<th>Nombre</th>
<th>Precio</th>
<th>Cantidad</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
<% for (Producto producto : lista) {%>
<tr>
<td><%=producto.getId()%></td>
<td><%=producto.getNombre()%></td>
<td><%=producto.getPrecio()%></td>
<td><%=producto.getCantidad()%></td>
<td>
<a href="<%=request.getContextPath()%>
/catalogo/form?id=<%=producto.getId()%>">editar</a>
</td>
<td>
<a href="<%=request.getContextPath()%>
/catalogo/eliminar?id=<%=producto.getId()%>">eliminar</a>
</td>
</tr>
<%}%>
</table>
</body>
AUTOR: Andrs Guzmn Fontecilla. 49
Email: andresguzf@gmail.com
WEB: http://www.bolsadeideas.com
LICENCIA: http://creativecommons.org/licenses/by-nc/4.0 | Arquitectura MVC Servlet
Curso: "Java EE 7 y Frameworks" 2017
</html>
@WebServlet("/catalogo/form")
public class FormController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Producto producto;
String titulo;
if (id > 0) {
producto = dao.buscarPorId(id);
titulo = "Modificar Producto";
} else {
producto = new Producto();
titulo = "Crear Producto";
}
request.setAttribute("producto", producto);
request.setAttribute("titulo", titulo);
request.getRequestDispatcher("/WEB-INF/views/form.jsp")
.forward(request, response);
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
int precio = 0;
try {
precio = Integer.parseInt(request.getParameter("precio"));
} catch (NumberFormatException e) {
errores.add("precio vacio o formato incorrecto");
}
int cantidad = 0;
try {
cantidad = Integer.parseInt(request.getParameter("cantidad"));
} catch (NumberFormatException e) {
errores.add("cantidad vacia o formato incorrecto");
}
if (nombre.isEmpty()) {
errores.add("nombre es requerido");
}
if (precio == 0) {
errores.add("precio es requerido");
}
if (cantidad == 0) {
errores.add("cantidad es requerida");
}
if (errores.isEmpty()) {
dao.guardar(producto);
request.setAttribute("producto", producto);
AUTOR: Andrs Guzmn Fontecilla. 51
Email: andresguzf@gmail.com
WEB: http://www.bolsadeideas.com
LICENCIA: http://creativecommons.org/licenses/by-nc/4.0 | Arquitectura MVC Servlet
Curso: "Java EE 7 y Frameworks" 2017
request.setAttribute("titulo", "Validando Producto");
request.setAttribute("errores", errores);
request.getRequestDispatcher("/WEB-INF/views/form.jsp")
.forward(request, response);
}
}
}
En el Servlet omitimos el uso del mtodo processRequest(request,
response y utilizamos directamente doGet(request, response) /
doPost(request, response) para manejar las peticiones.
Usamos doGet(request, response) para manejar una peticin HTTP
GET y doPost(request, response) para POST. Entonces doGet se
encarga de mostrar el formulario al usuario mientras que doPost se
encarga de procesar el formulario cuando este es enviado por el usuario.
En doGet, entonces segn si existe el parmetro id se va a buscar el
producto a la base de datos, de lo contrario se crea un nuevo objeto
producto, es decir para editar o crear un nuevo producto respectivamente,
en la base de datos usando la clase Dao.
Mientras que doPost procesa el form, recibe los datos del formulario
mediante el objeto request, luego valida que estos datos no sean vacos y
de ser as guarda/edita el producto en la base de datos, si los datos no se
validan correctamente entonces retornamos de regreso al formulario con
los mensajes de errores.
<form method="post">
<input name="id" type="hidden" value="<%=producto.getId()%>" />
<table>
<tr>
<td>Nombre:</td>
<td><input name="nombre" type="text"
value="<%=(producto.getNombre() == null) ? "" : producto.getNombre()%>" />
</td>
</tr>
<tr>
<td>Precio:</td>
<td><input name="precio" type="text"
value="<%=(producto.getPrecio() == 0) ? "" : producto.getPrecio()%>" />
</td>
</tr>
<tr>
<td>Cantidad</td>
<td><input name="cantidad" type="text"
value="<%=(producto.getCantidad() == 0) ? "" : producto.getCantidad()%>" />
</td>
</tr>
<tr>
<td colspan="2"><input name="enviar" type="submit"
value="<%=titulo%>" />
</td>
</tr>
</table>
</form>
</body>
AUTOR: Andrs Guzmn Fontecilla. 53
Email: andresguzf@gmail.com
WEB: http://www.bolsadeideas.com
LICENCIA: http://creativecommons.org/licenses/by-nc/4.0 | Arquitectura MVC Servlet
Curso: "Java EE 7 y Frameworks" 2017
</html>
package util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public ConexionJdbc() {
conectar();
}
Resumen
En este workshop, hemos aprendido el concepto de separacin de capas usando el
patrn de Arquitectura MVC (Modelo, Vista y Controlador) en los Servlets, luego vimos
cmo utilizar y levantar el servicio de base de datos de Java, adems creamos una
base de datos con su tabla producto y finalmente hemos analizado/estudiado el cdigo
detrs de la aplicacin Catlogo MVC, utilizando Servlet como controlador y JSP como
las vistas.