Download Proyecto GestiónStockWeb

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

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