Download Proyecto GestiónStockWeb

Document related concepts
no text concepts found
Transcript
ARQUITECTURA DE TRES CAPAS
Una aplicación Web es un programa informático
 que puede dar servicio simultáneamente a múltiples usuarios
 que lo ejecutan a través de Internet.
 Normalmente se estructura en base a una arquitectura de tres capas
Cliente
Capa Intermedia
Capa de Datos
Red
Capa Cliente

interactúa con el usuario de la aplicación,
o normalmente usa el navegador Web de la máquina cliente.
 Captura datos, los envía a la capa intermedia.
 Presenta al usuario los resultados generados por la aplicación.
Capa Intermedia




Esta constituida por la aplicación en sí.
Instalada en una máquina independiente, (servidor)
Los clientes acceden a ella a través de la red, vía protocolo HTTP.
En la máquina servidor:
o La aplicación es ejecutada por un motor de aplicación (p.e. Tomcat)
 permite que una instancia de la aplicación atienda múltiples clientes.
o La aplicación requiere de un servidor Web (p.e. Apache)
 interfaz entre ella y el cliente ,realizando el diálogo http.
Capa de datos

almacenamiento permanente de la información
o manejada por la aplicación y la gestión de la seguridad de los mismos.
o Esta tarea es soportada, generalmente, por las bases de datos (Oracle, MySQL,
SQL Server, etc.).
1
Patrón
de
Diseño
Modelo-Vista-Controlador
–
(MVC.
Model-View-
Controller)
Fundamental implementar correctamente la capa intermedia de la aplicación.
 definimos un modelo formado por una serie de bloques o componentes,
 de modo que cada uno pueda desarrollarse de manera independiente
 con responsabilidades claramente definidas:
 patrón Modelo-Vista-Controlador (MVC).
Cliente
Capa Intermedia
Capa de Datos
Red
Browser
Datos
Controlador
(Servlet)
Vista
(Jsp)
Modelo
(Clases)
El controlador


Es el cerebro de la aplicación.
Todas las peticiones desde el cliente son dirigidas al controlador,
o Por cada peticion invoca al resto de los componentes de la aplicación
 .jsp
 .class
Por ejemplo:
 petición del cliente requiriendo datos de una base
 el controlador solicitará los datos necesario al modelo
 recibe los datos del modelo
 se los proporcionará a la vista.
En una aplicación JEE, el controlador es implementado a través
 de un servlet
 un JavaBean
 una etiqueta personalizada.
o Pueden existir mas de uno de estos componentes
La vista
La vista será la encargada de generar las respuestas (generalmente HTML o XML)
 Si esta respuesta tiene que incluir datos proporcionados por el controlador,
o el código HTML de la página no será fijo
o sino que deberá ser generado de forma dinámica,
o su implementación correrá a cargo de una página JSP.
2
El modelo
En la arquitectura MVC la lógica de negocio de la aplicación,
 el acceso a datos y su manipulación,
 esta encapsulada dentro del modelo.
En una aplicación JEE el modelo puede ser implementado
 mediante clases estándar Java o
 mediante Enterprise JavaBeans.
APLICACIÓN DE MVC. GestionStockWeb.
Veamos el uso del modelo MVC en un caso práctico.
 Se propone una aplicación Web donde
o se registran los movimientos de stock de determinados productos de un negocio.
o Al momento de registrar un egreso de productos,
o la aplicación deberá controlar que el stock actual sea suficiente
o En caso de serlo,
 deberá informar si el stock resultante se equipara con el nivel mínimo de
seguridad previsto para el artículo.
o En caso de no serlo
 Si no existe disponibilidad
 o la cantidad ingresada no es correcta,
 deberá notificarse al usuario.
El esquema de resolución es el siguiente:
Controller
Param: operacion= “login”
1. validarUsuario(usr, pwd)
2. registrarMovStock(nom, tipo, ctd)
GestorStock
Usuario: albert
Contraseña: genio
Modelo
Producto
Param:
Sigue el proyecto completo
operacion = “registrar”
Ing. Martín Polliotto, 05 de agosto de 2009.
3
Ejemplo 6: Proyecto GestionStockWeb.
Es un ejemplo de un nivel técnico superior.
 Implementa Servlets, y a diferencia de ejemplos anteriores:
 Todo organizado según el patrón MVC (Modelo Vista Controlador).
o Capa Modelo las clases GestorStock y Producto contienen toda la lógica de
negocio.
o Capa Controlador viene implementado con un Servlet(clase Controller)
o Capa Vista las páginas login.jsp y registrarMovStock.jsp.
Lo más importante de este ejemplo
 Separación las capas de presentación de la de lógica de negocio
 Implementación de un Servlet que haga de vínculo entre ellas.
…..
<web-app version="2.5" …
<servlet>
<servlet-name>Controller</servlet-name>
<servlet-class>controlador.Controller</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Controller</servlet-name>
<url-pattern>/controller</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<taglib>
<taglib-uri>http://jakarta.apache.org/taglibs/
request-1.0</taglib-uri>
<taglib-location>/WEB-INF/taglibs-request.tld </
taglib-location></taglib>
</web-app>
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<title>Gestión de Stock Web</title>
</head>
<body>
<jsp:forward page = "/vista/login.jsp"/>
</body>
</html>
4
login.jsp
<%-Document : login
Created on : 01/08/2009, 23:58:18
Author : fenix
--%>
Nota: La codificación de esta JSP se ha
realizado usando GUI Builder
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Gestión de Stock Web</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
</style>
<%@ taglib uri="/WEB-INF/taglibs-request.tld" prefix="req" %>
<link rel="stylesheet" href="estilos.css" type="text/css">
</head>
<body>
<form name="frmLogin" action="controller" method="POST">
<input type="hidden" value="login" name="operacion">
<!-El input 'operacion' permite enviar, sin mostrar al usuario,
la acción que deberá procesar nuestro servlet Controller
cuando reciba la petición desde este formulario...
-->
<br/>
<div>
<table>
<h3>Gestión de Stock Web</h3>
<br/>
<h4 style="color:white;">Ingrese su nombre de usuario y contraseña</h4>
<tbody style="">
<tr>
<td>Usuario</td>
<td><input type="text" name="usuario" value="" size="25" /></td>
</tr>
<tr>
<td>Password</td>
<td><input type="password" name="clave" value="" size="25" /></td>
</tr>
</tbody>
</table>
<input type="submit" value="Ingresar" name="btnLogin" style="fontfamily:arial;font-size:11px;"/>
<br/>
<h5 style="color:red;"><req:attribute name="error"/></h5>
</div>
</form>
</body>
</html>
5
Esto se ve:
Al clickear sobre Ingresar el control es
tomado por el indicado en la cláusula
action de la sentencia form:
Controller, usándose el método post.
Controller.java
package controlador;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import modelo.GestorStock;
/**
*
* @author fenix
*/
public class Controller extends HttpServlet {
private GestorStock gestor;
@Override
public void init() throws ServletException {
super.init();
gestor = new GestorStock();
}
protected void init(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { processRequest(request, response);}
6
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String operacion = request.getParameter("operacion");
RequestDispatcher despachador = null;
/*El objeto 'despachador' permite encaminar (despachar) la respuesta a la solicitud
* recibida en función del resultado de la operación solicitada.
El input type = “hidden”, con
*/
nombre
“operación”,
tiene
asociado
el
valor
“login”.
Entonif(operacion.equals("login")){
ces ejecutamos el cuerpo de esta
String usuario = request.getParameter("usuario");
llave. Si gestor.validarUsuario
String clave = request.getParameter("clave");
(usuario, clave), retorna “Ok”,
String rtdo = gestor.validarUsuario(usuario, clave);
vamos a movimentar stock:
"/vista/registrarMovStock.jsp"
if(rtdo.equals("Ok")){
request.setAttribute("lstProductos", gestor.getProductos());
despachador = request.getRequestDispatcher("/vista/registrarMovStock.jsp");
}
else{
request.setAttribute("error", rtdo);
despachador = request.getRequestDispatcher("/vista/login.jsp");
}
seteamos, como atributo de la respuesta, el
despachador.forward(request, response);
mensaje de error y solicitamos nueva
}
identificación: /vista/login.jsp
else
if(operacion.equals("registrar")){
despachador = request.getRequestDispatcher("/vista/registrarMovStock.jsp");
String nombreProd = request.getParameter("producto");
String cantidad = request.getParameter("cantidad");
String tipoMov = request.getParameter("tipoMov");
request.setAttribute("mensaje", gestor.registrarMovStock(nombreProd,tipoMov,
cantidad));
request.setAttribute("lstProductos", gestor.getProductos());
despachador.forward(request, response);
}
}
public String getServletInfo() {
return "Servlet Controller. Su objetivo es recibir la peticiones desde" +
"las páginas, delegar según el trabajo solicitado mediante el " +
"el parámetro 'operacion' al modelo (clases GestorStock y Producto) " +
"y con la respuesta del modelo redirigir a la página que corresponda.";
}// </editor-fold>
}
/vista/registrarMovStock.jsp
La codificación de esta página, pg 8
7
Nota: La codificación de esta JSP se ha
<%-realizado usando el GUI Builder
Document : registrarMovStock
Created on : 02/08/2009, 01:13:18
Author : fenix
--%>
….
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Gestión de Stock Web</title>
<%@ taglib uri="/WEB-INF/taglibs-request.tld" prefix="req"%>
<link rel="stylesheet" href="estilos.css" type="text/css">
</head>
<body>
<form name="frmRegistarMovStock" action="controller" method="POST">
<input type="hidden" value="registrar" name="operacion">
<div style="background-color:blue;width:270px;height:250px;">
<h3 align="center" style="color:yellow;">Movimientos de Stock</h3>
<table align="center">
<tbody>
<tr>
<td>Producto</td>
<td>
<select name="producto">
<%java.util.ArrayList prods = (java.util.ArrayList)
request.getAttribute("lstProductos");
for (int i = 0; i < prods.size(); i++) {
modelo.Producto p = (modelo.Producto) prods.get(i);%>
<option><%=p.getNombre()%></option>
<%}%>
</select>
</td> </tr>
<tr>
<td>Cantidad</td>
<td><input type="text" name="cantidad" size="10" /></td>
</tr>
<tr>
<td>Ingreso</td>
<td><input type="radio" name="tipoMov" value="I" checked="checked" /></td>
</tr>
<tr>
<td>Egreso</td>
<td><input type="radio" name="tipoMov" value="E" /></td>
</tr>
</tbody>
</table><br/>
<input type="submit" value="Registrar" name="btnRegistrar" style="fontfamily:arial;font-size:11px;"/>
<br/>
<h5 style="color:white;"><req:attribute name="mensaje"/></h5>
</div>
</form>
</body>
</html>
8
package modelo;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class GestorStock {
private List productos;
private final String user = "Frodo";
private final String pwd = "Bolson";
public GestorStock() {
productos = new ArrayList();
productos.add(new Producto("Gaseosa Cola 2.5 lts"));
productos.add(new Producto("Galletitas Surtidas x 250 grs."));
productos.add(new Producto("Alfajor chico"));
productos.add(new Producto("Cigarrillo Acme"));
productos.add(new Producto("Yogurt x 500 cm3"));
}
public List getProductos() { return productos;}
public String validarUsuario(String user, String pwd) {
String r = "Usuario o clave incorrectos.";
if (this.user.equals(user) && this.pwd.equals(pwd)) { r = "Ok"; }
return r;
}
public String registrarMovStock(String prod, String tipo, String ctd) {
String r = "Operación registrada exitosamente.";
try {
int cant = Integer.parseInt(ctd);
Producto p = buscarProducto(prod);
if (tipo.equals("E")) {
if (p.getStock() >= cant) {
p.setStock((p.getStock() - cant));
if (p.getStock() <= p.getPtoReorden())
r = "Producto a reponer.";
}else r = "Stock insuficiente.";
} else p.setStock((p.getStock() + cant));
r+=("<br>" + p.getNombre()+". Stock actual: " + p.getStock());
} catch (NumberFormatException e) { r = "Cantidad incorrecta."; }
return r;
}
private Producto buscarProducto(String nombre) {
for (Iterator it = productos.iterator(); it.hasNext();) {
Producto x = (Producto) it.next();
if (x.getNombre().equals(nombre)) {return x;}
}
return null;
}
}
9
package modelo;
public class Producto {
private String nombre;
private int stock;
private int ptoReorden;
public Producto(String n){
nombre = n;
stock = (int)(Math.random()*100); //como máximo 100 articulos en stock
ptoReorden = (int) (Math.random()*6 + 10); // punto de reorden: [10;15]
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
public int getPtoReorden() {
return ptoReorden;
}
public void setPtoReorden(int ptoReorden) {
this.ptoReorden = ptoReorden;
}
public String toString(){
return "Producto: " + nombre + "\nStock: " + stock + "\nPunto Reorden: " + ptoReorden;
}
}
10