Manual-2016-II-Lenguaje-de-Programacion-II-1894.pdf

April 17, 2017 | Author: Saulzhitho MiraVal Gomez | Category: N/A
Share Embed Donate


Short Description

Download Manual-2016-II-Lenguaje-de-Programacion-II-1894.pdf...

Description

Lenguaje de Programación II

LENGUAJE DE PROGRAMACIÓN II

CARRERA DE COMPUTACIÓN E INFORMÁTICA

2

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

3

Índice Presentación Red de contenidos

4 5

Unidad de Aprendizaje 1

HTML, JQuery, Servlet, JSP y JDBC. 1.1 Tema 1 : HTML, JSP y elementos de script 1.1.1 : Etiquetas HTML 5. 1.1.2 : JSP y elementos de script 1.2 Tema 2 1.2.1 1.2.2 1.2.3

: : : :

JQuery, Servlet y JSP JQuery Validaciones con JQuery Arquitectura del Servlet

7 7 15 20 20 23

1.3 Tema 3 : JDBC, Aplicaciones Parte I 1.3.1 : Aplicación de Logueo 1.3.2 : Aplicación de Listado

35 36 43

1.4 Tema 4 : JDBC, Aplicaciones Parte II 1.4.1 : Aplicación de Mantenimiento

46 46

Unidad de Aprendizaje 2

CRUD con patrón DAO, sesiones y Lenguaje de Expresiones 2.1 Tema 5 : Patrón DAO Parte I 2.1.1 : Patrones de diseño de software 2.1.2 : Patrón DAO 2.1.3 : Aplicación Listado 2.2 Tema 6 2.2.1 2.2.2 2.2.3 2.2.4

: : : : :

Patrón DAO Parte II, Sesiones Web y EL

Lenguaje de expresiones Aplicación Mantenimiento Sesiones web Aplicación de Logueo

55 55 60 65 74 74 74 83 85

Unidad de Aprendizaje 3

Etiquetas JSTL, Transacciones, Ajax y Listeners 3.1 Tema 7 : Custom Tag y JSTL 3.1.1 : Custom Tag 3.1.2 : Creación de etiquetas personalizadas (Custom TAG) 3.1.3 : JSTL y Librerías 3.1.4 : Aplicación Listado con JSTL 3.2 Tema 8 3.2.1 3.2.2 3.2.3

: : : :

Ajax y Transacciones en Web

AJAX Transacciones Aplicación Ajax y Transacción

3.3 Tema 9 : Listeners 3.3.1 : Tipos 3.3.2 : Aplicaciones

CIBERTEC

93 93 93 103 116 118 118 121 125 146 146 149

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

4

Presentación Lenguaje de Programación II pertenece a la línea de cursos de programación y se dicta en la carrera de Computación e Informática. El curso brinda un conjunto de herramientas del lenguaje Java que permite a los estudiantes utilizarlas en la implementación de aplicaciones web en Java. El manual para el curso ha sido diseñado bajo la modalidad de unidades de aprendizaje, las que se desarrollan durante semanas determinadas. En cada una de ellas, hallará los logros que debe alcanzar al final de la unidad; el tema tratado, el cual será ampliamente desarrollado; y los contenidos, que debe desarrollar, es decir, los subtemas. Asimismo, encontrará las actividades que deberá desarrollar en cada sesión, que le permitirán reforzar lo aprendido en la clase. El curso es eminentemente práctico: consiste en desarrollar una aplicación web. En primer lugar, se inicia con crear programas utilizando la tecnología de Servlet y JSP. Continúa con la presentación de nuevas tecnologías como el patrón Data Access Object, sesiones en la web. Luego, se desarrollan los componentes reutilizables mediante CustomTag. Finalmente, se concluye con el uso de transacciones, Ajax, JQuery y Listeners.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

5

Red de contenidos

Lenguaje de Programación II

Servlet y JSP

Sesiones y EL

Customg Tag

JSTL

Sesiones

Tag Dinámicos

JSTL

EL

Generación de Librerías

Servlet

JSP

AJAX

Patrón DAO

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

AJAX

LENGUAJE DE PROGRAMACIÓN II

6

UNIDAD

1 HTML, JQuery, JSP Y JDBC LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, el alumno implementa una aplicación Java Web que utilice las tecnologías JQuery, JSP y Servlet con base de datos.

TEMARIO 1.1 Tema 1 1.1.1 1.1.2 1.2 Tema 2 1.2.1 1.2.2 1.2.3 1.2.4 1.3 Tema 3 1.3.1 1.3.2 1.4 Tema 4 1.4.1

: : : : : : : : : : : : :

HTML, JSP y elementos de script Etiquetas HTML 5 JSP y elementos de script JQuery, Servlet y JSP JQuery Validaciones con JQuery Arquitectura del Servlet Servlet y JSP JDBC, Aplicaciones Parte I Aplicación de Logueo Aplicación de Listado JDBC, Aplicaciones Parte II Aplicación de Mantenimiento

ACTIVIDADES PROPUESTAS  Los alumnos resuelven ejercicios que involucran el uso de etiquetas HTML 5 y validación de datos.  Los alumnos implementan una aplicación con base de datos para realizar mantenimiento y logueo a un portal web.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

7

1.1 HTML, JSP Y ELEMENTOS DE SCRIPT HTML, siglas de HyperText Markup Language (lenguaje de marcas de hipertexto), hace referencia al lenguaje de marcado para la elaboración de páginas web. Es un estándar que sirve de referencia para la elaboración de páginas web en sus diferentes versiones, define una estructura básica y un código (denominado código HTML) para la definición de contenido de una página web, como texto, imágenes, videos, entre otros. Es un estándar a cargo de la W3C, organización dedicada a la estandarización de casi todas las tecnologías ligadas a la web, sobre todo en lo referente a su escritura e interpretación. JSP, es un lenguaje para la creación de sitios web dinámicos, acrónimo de Java Server Pages. Está orientado a desarrollar páginas web en Java. JSP es un lenguaje multiplataforma. Creado para ejecutarse del lado del servidor. JSP fue desarrollado por Sun Microsystems. La tecnología de JSP permite a los desarrolladores y a los diseñadores de web desarrollar rápidamente y mantener fácilmente páginas dinámicas, también permite introducir código para la generación dinámica de HTML dentro de una página web.

1.1.1 Etiquetas HTML5 HTML es el lenguaje usado para escribir las páginas web, describe la estructura y el contenido usando solo texto y lo complementa con objetos tales como imágenes, flash y otros. Los archivos así creados son guardados con la extensión de archivo HTM o HTML. Su estructura se compone de etiquetas o tags entre las cuales van insertados los diferentes elementos que componen la página como son los bloques de texto, scripts y la ruta a la ubicación de archivos externos como imágenes y otros archivos multimedia. Es más ligero al ser más sencillo y simple el código, lo que permite que las páginas escritas en este lenguaje carguen más rápido en el navegador. Si aún no fuera suficiente, introduce infinidad de opciones que hasta ahora estaban vedadas a las páginas web, como insertar directamente video (no flash), música, y casi cualquier elemento. Formulario Es el contenedor principal donde se encuentran los controles que utilizaremos para ingresar información referente a una entidad de un sistema.

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

8

Parámetros de la etiqueta FORM  

   

action: sirve para indicar a donde enviaremos los datos introducidos en los campos del formulario, un destino determinado como: servlet, jsp, etc. method: este atributo indica el modo de transmisión de los datos. El modo GET utiliza la dirección URL para pasar los valores introducidos en los campos del formulario, da como resultado una url como: (www.plataforma.com/enviar.jsp?Apellido=Lara&Nombre=Luis). El modo POST envía los datos como parte de la entrada estándar (no visible en la url). name: Identifica el nombre del formulario, este nombre facilita identificar el formulario desde el script. target: Indica la ventana de destino diferente a la del envió de los datos. accept-charset: Especifica el juego de caracteres que el servidor utiliza para gestionar los datos del formulario. auto-complete: puede ser ON u OFF. Para activar el autocompletado de datos del formulario.

Etiqueta INPUT Esta es la etiqueta más utilizada y también la que presenta más opciones. El atributo TYPE le permite indicar la clase de entrada de datos. El valor predeterminado es TEXT y representa una línea de entrada de datos. Se lista los diferentes tipos de datos que trabaja la etiqueta INPUT:          

TEXT CHECKBOX RESET RADIO PASSWORD BUTTON FILE HIDDEN IMAGE SUBMIT

Atributos de la etiqueta input El principal atributo de la etiqueta INPUT es TYPE, ya que es el que le indica el tipo de datos que debe recibir. A continuación mostraremos una lista de atributos que se le pueden agregar a la etiqueta INPUT.      

TYPE: Mencionado anteriormente, es el que indica el tipo de control de datos que se ha elegido. SRC: Indica el origen de los datos. STEP: Permite establecer la cantidad de valores posibles dentro de un rango. VALUE: Indica el valor que devuelve el control. REQUIRED: Valor booleano que nos indica que es una información obligatoria. PLACEHOLDER: Texto que sirve de información o guía al usuario y desaparece al pulsar dentro del campo, anteriormente este efecto se creaba con JavaScript

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

                   

9

AUTOCOMPLETE: Indica se se activa (on) o se desactiva (off) el auto completado de la entrada de datos. ALT: Se utiliza cuando el tipo es una imagen y no se puede cargar en la interfaz del usuario, se muestra este texto alternativo. AUTOFOCUS: Permite especificar que una parte del formulario debe tener foco para ingresar información cuando se carga la página. CHECKED: Para indicar si el elemento está seleccionado por defecto, solo se utiliza en algunos tipos. DISABLED: Es un valor booleano que indica que el elemento está desactivado, con lo cual no admite entrada de datos. READONLY: Valor booleano que indica que el campo no se puede modificar, solo lectura. FORM ENCTYPE: Indica el modo de envío de los datos. FORM ACTION: Es la dirección Url que se utiliza al activar el elemento. FORM NOVALIDATE: Es un valor booleano que indica que el formulario no se valida antes de enviarse. FORM TARGET: Ventana del destino del formulario. HEIGHT: Altura del campo en cuestión. WIDTH: Anchura del campo en cuestión. SIZE: Indica la cantidad de caracteres que se pueden introducir en el campo. MAX: Valor máximo que se puede entrar en el elemento de datos. MIN: Valor Mínimo que se puede entrar en el elemento de datos. MAXLENGTH: Longitud máxima de la entrada de datos. LIST: Es un identificador de una lista que se define con DATALIST MULTIPLE: Valor booleano que indica que se permite la selección de valores múltiples. NAME: Nombre que identifica al campo de datos. PATTERN: Expresión regular que se utiliza para validar entradas de datos. Este atributo permite hacer validaciones muy complejas y utilizado correctamente puede ahorrarse muchas líneas de código.

Tipos de campos de formulario (Etiqueta - input) 

Input Type:Text El tipo texto representa una línea de texto, como en casi todos los campos de formulario su valor se puede inicializar utilizando el atributo value.



Input Type:Password Representa una entrada de datos de texto que se visualizan asteriscos pero al enviarse se envían los datos reales, el datos introducido en el campo se asigna al atributo value.



Input Type:Hidden Es un control que se mantiene oculto a la vista pero que se pasa al servidor junto con el resto de los campos del formulario. Es un campo adecuado para pasar información de una página a otra y que se puede utilizar en los script como un dato más. Al ser un control oculto, el usuario no puede ni ver ni modificar. El dato se le asigna al atributo value.

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

10



Input Type:Checkbox Es un control que es presentado al usuario por una casilla de verificación; por lo tanto, sólo puede tener dos valores: seleccionado o no seleccionado. Si se utiliza el atributo checked, el campo se muestra seleccionado por defecto.



Input Type:Radio Es un control que es presentado al usuario con botones de opción; una variable asignada a un grupo de botones en el que solo uno puede estar seleccionado. Si se utiliza el atributo checked, el campo aparece seleccionado por defecto, para informarle a HTML que todos los botones forman parte de un grupo de opciones, estos comparten el atributo name.



Input Type:SUBMIT Es un control que se representa por un botón que al ser pulsado envía los datos recogidos por el formulario al destino escrito en el parámetro action, en este caso el atributo value se utiliza para poner el texto dentro del botón.



Input Type:RESET Es un control que se representa por un botón que al ser pulsado reinicia los campos del formulario con los valores predeterminados. El atributo value se utiliza como texto del botón.



Input type:File Este control permite enviar archivos al servidor mediante el método POST. En el navegador se muestra un botón examinar o seleccionar para que podamos elegir el archivo que se requiere enviar.

Etiqueta TEXTAREA Se puede crear áreas de texto (en columnas y filas) dónde el usuario pueda insertar contenido donde requiere gran cantidad de información. A diferencia de los input de tipo text, en los textarea el usuario puede incluir saltos de línea. Rn parámetro rows y cols indica la cantidad de filas y columnas que tendrá el control. Etiqueta FIELDSET Sirve para agrupar los elementos. Se utiliza con su respectiva etiqueta de cierre y crea un recuadro que rodea a los elementos de formulario colocados dentro de ella. Etiqueta LEGEND Sirve para nombrar o etiquetar un grupo creado con FIELDSET. Añade simplemente una nota aclaratoria sobre qué tipo de información se está agrupando en el recuadro.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

11

Ejercicio 01: pagina01.html Diseñar la siguiente página para ingresar y seleccionar datos

Código: Insert title here Datos básicos Nombre Descripción Foto Partida Pago

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

12

Datos económicos Precio    Impuestos 4% 7% 16% 25% Promoción Ninguno Transporte gratuito Descuento 5%

Nuevos Tipos de input En HTML5 se han incluido nuevos tipos de entradas de datos para los formularios, algunos de estos nuevos tipo de entrada tienen la capacidad de comprobar si el valor introducido coincide con su tipo de dato lo que nos ayuda bastante a la hora de solucionar la validación de los datos que el usuario introduce. Input type:url Esta entrada de datos se utiliza para especificar una dirección web. Se muestra como un simple campo de texto normal. Input type:search El tipo de entrada de datos Search(type="search") proporciona un campo de búsqueda, es muy parecido a un campo de texto normal. Input type: email Se utiliza para especificar una o más direcciones de correo electrónico. Soporta el atributo booleano múltiple, para permitir varias direcciones separadas por coma. Input type: number El tipo number (input=”number”) proporciona una entrada de dato para agregar un número. Normalmente se trata de un cuadro donde se puede escribir un número o hacer clic en las flechas arriba o abajo para seleccionarlo. Esta entrada de datos cuenta con los atributos max y min para especificar los valores mínimo y máximos permitidos, también puede utilizar el atributo step, este determina la cantidad a disminuir o aumentar cuando hace clic en las flechas.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

13

Input type: range Este tipo de entrada de datos nos proporciona un deslizador en aquellos navegadores que lo soportan. Al igual que number, permite los atributos min, max y step. Input Type=Date Esto engloba la fecha (año, mes, día) pero no la hora; Ejemplo, 2008-06-22, Podemos seleccionar el año, mes y día. Ejercicio 02: pagina02.jsp

Código: Insert title here Registrar Empleado Nombres:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

14

Apellido Paterno: Apellido Materno: Sexo: Masculino Femenino DNI: Fecha Registro: Celular: Telefono:

Correo: Tipo Empleado: Secretaria Auditor

Direccion:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

15

Distrito: Comas Surco

Foto: Grabar

1.1.2 JSP y elementos de script JSP permite la creación de sitios web dinámicos donde se puede combinar contenido HTML y bloques de programación en java que permitan la programación de sentencias. JSP scripting incluye los siguientes elementos de código Java que pueden aparecer dentro de una página JSP:  Scriptlets  Expresiones Scriptlets Son porciones de código Java mezclados con el lenguaje de marcas de la página. Un scriptlet, o fragmento de código, puede consistir de una o más líneas de código Java y se puede usar con el código HTML o JSP para configurar saltos condicionales o bucles por ejemplo. Un scriptlet JSP está contenido dentro de los símbolos y se escribe usando la sintaxis Java. Expresiones Se evalúan y convierten a valores de String y luego son mostradas en la ubicación respectiva dentro de la página. Una expresión JSP no termina en “;”. Está contenida dentro de los símbolos: . Objeto request

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

16

El objeto request está disponible de forma automática por lo que no es necesario instanciarlo.  getParameter(String), permite recuperar una variable enviada por url.  setAttribute(String, Object), para cargar (setear) el objeto en el request.  getAttribute(String), para recuperar el objeto Ejercicio 03: Acceso.jsp

Código: Insert title here Registro de Viajes Apellidos y Nombres: Destino: Cajamarca Trujillo Arequipa Ayacucho

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

19

RegistroAction.jsp

Ayuda.jsp

Código: Insert title here Cliente : El precio del destino es de S/. nuevos soles.

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

1.2

20

JQuery, Servlet y JSP

1.2.1. JQuery JQuery es una librería gratuita y open source que simplifica la creación de páginas web altamente interactivas. Funciona en todos los exploradores de internet modernos y abstrae características específicas de cada uno de estos, permitiéndonos enforcarnos en el diseño y resultado final, en lugar de tratar de desarrollar funciones complejas en exploradores individuales. Específicamente jQuery facilita:   

La búsqueda y manipulación de contenido en una página HTML; Trabajar con el modelo de eventos de los exploradores modernos; Y añadir efectos y transiciones sofisticadas que vemos en páginas modernas, como animaciones disparadas por eventos.

1.2.2. Validación Una de las tareas más comunes en los sistemas, sea web o escritorio, es la validación de campos, ya que a partir de la información que se genere en formularios, ésta será enviada para ser procesada. Para realizar la validación usamos los siguientes archivos:   

jquery-1.11.3.js, es la librería principaldel JQuery. jquery.validate.js, continene los métodos para realizar la validación en los formularios. jquery.metadata.js, Su funcionamiento permite incluir datos adicionales dentro de nuestro código HTML, estos datos utilizan el formato JSON

Ejercicio 01: registrarPelicula.jsp

Validar lo siguiente:  

Ingresar en forma obligatoria: Nombre, Duración, Director, Actores, Sinopsis. Duración solo número de 1 a 3 cifras

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

21

Código: Registro de Pelicula $(document).ready(function() { $("#dataPelicula").validate(); }); Registro de Película Nombre: Genero: Comedia Drama Ciencia Ficción Romántico Animación Clasificación: Apta para todos

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

4.

50

Crear la página actualizarAlumno.jsp

Código: Insert title here Nombres Paterno Materno Edad CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

5.

51

Crear la página registrarAlumno.jsp

Código: Insert title here $(document).ready( function(){ $("#frmregistro").validate({ rules:{ txtnom:{ required:true, letras:true }, txtapepat:{ required:true, minlength:3 }, txtapemat:{ required:true, minlength:3 } }, messages:{ txtnom:{ required:"Ingrese Nombre", letras:"solo letras" }, txtapepat:{ required:"Ingrese Apellido Paterno", minlength:"Mínimo 3 letras" }, txtapemat:{ required:"Ingrese Apellido Materno", minlength:"Mínimo 3 letras" } } }); }); CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

52

Nombres Paterno Materno Edad

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

53

Resumen 1. Las etiquetas HTML 5 permiten mejorar el aspecto de las páginas y usar Responsive Design. 2. El uso de la librería JQuery permite realizar validaciones en los formularios y a la vez poder crear nuestras propias validaciones con sus mensajes personalizados. 3. Para la creación de validaciones tenemos que usar expresiones regulares o trabajar directamente con JavaScript. 4. El uso de un servlet dentro de una sistema web permite la comunicación entre vista con el modelo usando el paradigma request y response. 5. El uso de métodos dentro del servlet permitirá ordenar las sentencias que se han implementado en el modelo debido a que estos últimos son invocados según el requerimiento del usuario

6. Si desea saber más acerca de estos temas, puede consultar las siguientes páginas.  http://today.java.net/pub/a/today/2003/12/04/exceptions.html Aquí hallará importantes reglas básicas para la gestión de excepciones en java.  http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Exception.html En esta página, hallará documentación detallada de la clase base de todas las excepciones controladas: Exception

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

54

UNIDAD

2 CRUD con patrón DAO, sesiones y EL LOGRO DE LA UNIDAD DE APRENDIZAJE Al término de la unidad, el alumno implementa una aplicación Java Web usando el patrón DAO, sesiones y Lenguaje de Expresiones (EL).

TEMARIO 2.1 Tema 5 2.1.1 2.1.2 2.1.3 2.2 Tema 6 2.2.1 2.2.2 2.23 2.2.4

: : : : : : : : :

Patrón DAO Parte I

Patrones de diseño de software Patrón DAO Aplicación Listado Patrón DAO Parte II, Sesiones web y EL Lenguaje de expresiones Aplicación Mantenimiento Sesiones web Aplicación de Logueo

Actividades propuestas   

Implementar un aplicativo web usando el patrón DAO Crear aplicaciones con conexión a base de datos que resuelvan casos prácticos de la vida real. Trabajar con sesiones que permitan a cada usuario logueado poder trabajar con su propia sesión.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

55

2.1 Patrón DAO Parte I 2.1.1 Patrones de Diseño de Software El diseño es un modelo del sistema, realizado con una serie de principios y técnicas, que permite describir el sistema con el suficiente detalle como para ser implementado. Sin embargo, los principios y reglas no son suficientes. En el contexto de diseño, podemos observar que los buenos ingenieros tienen esquemas y estructuras de solución que usan numerosas veces en función del contexto del problema. Este es el sentido cabal de la expresión "tener una mente bien amueblada", y no el significado de tener una notable inteligencia. Estos esquemas y estructuras son conceptos reusables y nos permiten no reinventar la rueda. Un buen ingeniero reutiliza un esquema de solución ante problemas similares. Historia El concepto de "patrón de diseño" que tenemos en Ingeniería del Software se ha tomado prestado de la arquitectura. En 1977, se publica el libro "A Pattern Language: Towns/Building/Construction", de Christopher Alexander, Sara Ishikawa, Murray Silverstein, Max Jacobson, Ingrid Fiksdahl-King y Shlomo Angel, Oxford University Press. Contiene numerosos patrones con una notación específica de Alexander. Alexander comenta que “cada patrón describe un problema que ocurre una y otra vez en nuestro entorno, para describir después el núcleo de la solución a ese problema, de tal manera que esa solución pueda ser usada más de un millón de veces sin hacerlo siquiera dos veces de la misma forma”. El patrón es un esquema de solución que se aplica a un tipo de problema. Esta aplicación del patrón no es mecánica, sino que requiere de adaptación y matices. Por ello, dice Alexander que los numerosos usos de un patrón no se repiten dos veces de la misma forma. La idea de patrones de diseño estaba "en el aire", la prueba es que numerosos diseñadores se dirigieron a aplicar las ideas de Alexander a su contexto. El catálogo más famoso de patrones se encuentra en “Design Patterns: Elements of Reusable Object-Oriented Software”, de Erich Gamma, Richard Helm, Ralph Johnson y John Vlissides, 1995, Addison-Wesley, también conocido como el libro GOF (Gang-OfFour). Siguiendo el libro de GOF, los patrones se clasifican según el propósito para el que han sido definidos: · · ·

Creacionales: solucionan problemas de creación de instancias. Nos ayudan a encapsular y abstraer dicha creación. Estructurales: solucionan problemas de composición (agregación) de clases y objetos. De Comportamiento: soluciones respecto a la interacción y responsabilidades entre clases y objetos, así como los algoritmos que encapsulan.

Según el ámbito, se clasifican en patrones de clase y de objeto:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

Clase

Creación Método de Fabricación

56

Estructural Adaptador (clases)

Objeto

Fábrica, Constructor, Prototipo, Singleton

CARRERA DE COMPUTACIÓN E INFORMÁTICA

Adaptador (objetos), Puente, Composición, Decorador, Fachada, Flyweight

De Conducta Interprete Plantilla Cadena de Responsabilidad, Comando (orden), Iterador, Intermediario, Observador, Estado, Estrategia, Visitante, Memoria

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

57

Catálogo de patrones J2EE

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

58

Capa de Presentación

Decorating Filter / Intercepting Filter

Front Controller/ Front Component

View Helper

Composite view

Service To Worker

Dispatcher View

CARRERA DE COMPUTACIÓN E INFORMÁTICA

Un objeto que está entre el cliente y los componentes web. Este procesa las peticiones y las respuestas. Un objeto que acepta todos los requerimientos de un cliente y los direcciona a manejadores apropiados. El patrón Front Controller podría dividir la funcionalidad en 2 diferentes objetos: el Front Controller y el Dispatcher. En ese caso, El Front Controller acepta todos los requerimientos de un cliente y realiza la autenticación, y el Dispatcher direcciona los requerimientos a manejadores apropiada Un objeto helper que encapsula la lógica de acceso a datos en beneficio de los componentes de la presentación. Por ejemplo, los JavaBeans pueden ser usados como patrón View Helper para las páginas JSP. Un objeto vista que está compuesto de otros objetos vista. Por ejemplo, una página JSP que incluye otras páginas JSP y HTML usando la directiva include o el action include es un patrón Composite View. Es como el patrón de diseño MVC con el Controlador actuando como Front Controller pero con una cosa importante: aquí el Dispatcher (el cual es parte del Front Controller) usa View Helpers a gran escala y ayuda en el manejo de la vista. Es como el patrón de diseño MVC con el controlador actuando como Front Controller pero con un asunto importante: aquí el Dispatcher (el cual es parte del Front Controller) no usa View Helpers y realiza muy poco trabajo en el manejo de la vista. El manejo de la vista es manejado por los mismos componentes de la Vista

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

59

Capa de Negocios

Business Delegate

Value Object/ Data Transfer Object/ Replicate Object

Session Façade/ Session Entity Façade/ Distributed Facade

Aggregate Entity Value Object Assembler

Value List Handler/ Page-by-Page Iterator/ Paged List

Service Locator

Un objeto que reside en la capa de presentación y en beneficio de los otros componentes de la capa de presentación llama a métodos remotos en los objetos de la capa de negocios. Un objeto serializable para la transferencia de datos sobre la red. El uso de un bean de sesión como una fachada (facade) para encapsular la complejidad de las interacciones entre los objetos de negocio y participantes en un flujo de trabajo. El Session Façade maneja los objetos de negocio y proporciona un servicio de acceso uniforme a los clientes. Un objeto que reside en la capa de negocios y crea Value Objets cuando es requerido Es un objeto que maneja la ejecución de consultas SQL, caché y procesamiento del resultado. Usualmente implementado como beans de sesión Es como el patrón de diseño MVC con el controlador actuando como Front Controller pero con un asunto importante: aquí el Dispatcher (el cual es parte del Front Controller) no usa View Helpers y realiza muy poco trabajo en el manejo de la vista. El manejo de la vista es manejado por los mismos componentes de la Vista Consiste en utilizar un objeto Service Locutor para abstraer toda la utilización JNDI y para ocultar las complejidades de la creación del contexto inicial, de búsqueda de objetos home EJB y recreación de objetos EJB. Varios clientes pueden reutilizar el objeto Service Locutor para reducir la complejidad del código, proporcionando un punto de control.

Capa de Integración

Data Access Object Service Activator

Service Activator

CIBERTEC

Consiste en utilizar un objeto de acceso a datos para abstraer y encapsular todos los accesos a la fuente de datos. El DAO maneja la conexión con la fuente de datos para obtener y almacenar datos. Se utiliza para recibir peticiones y mensajes asíncronos de los clientes. Cuando se recibe un mensaje, el Service Activator localiza e invoca a los métodos de los componentes de negocio necesarios para cumplir la petición de forma asíncrona.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

60

Concepto de patrón de diseño "Una arquitectura orientada a objetos bien estructurada está llena de patrones. La calidad de un sistema orientado a objetos se mide por la atención que los diseñadores han prestado a las colaboraciones entre sus objetos. Los patrones conducen a arquitecturas más pequeñas, más simples y más comprensibles". (Grady Booch) Los patrones de diseño son descripciones de clases cuyos objetos colaboran entre sí. Cada patrón es adecuado para ser adaptado a un cierto tipo de problema. Para describir un caso se debe especificar lo siguiente:         

Nombre Propósito o finalidad Sinónimos (otros nombres por los que puede ser conocido) Problema al que es aplicable Estructura (diagrama de clases) Participantes (responsabilidad de cada clase) Colaboraciones (diagrama de interacciones) Implementación (consejos, notas y ejemplos) Otros patrones con los que está relacionado

Ventajas de los patrones: La clave para la reutilización es anticiparse a los nuevos requisitos y cambios, de modo que los sistemas evolucionen de forma adecuada. Cada patrón permite que algunos aspectos de la estructura del sistema puedan cambiar independientemente de otros aspectos. Facilitan la reusabilidad, extensibilidad y mantenimiento. Un patrón es un esquema o microarquitectura que supone una solución a problemas (dominios de aplicación) semejantes (aunque los dominios de problema pueden ser muy diferentes e ir desde una aplicación CAD a un cuadro de mando empresarial). Interesa constatar una vez más la vieja distinción entre dominio del problema (donde aparecen las clases propias del dominio, como cuenta, empleado, coche o beneficiario) y el dominio de la solución o aplicación (donde además aparecen clases como ventana, menú, contenedor o listener). Los patrones son patrones del dominio de la solución. También, conviene distinguir entre un patrón y una arquitectura global del sistema. Por decirlo en breve, es la misma distancia que hay entre el diseño de un componente (o módulo) y el análisis del sistema. Es la diferencia que hay entre el aspecto micro y el macro; por ello, en ocasiones, se denomina a los patrones como "microarquitecturas". En resumen, un patrón es el denominador común, una estructura común que tienen aplicaciones semejantes. Esto también ocurre en otros órdenes de la vida. Por ejemplo, en nuestra vida cotidiana, aplicamos a menudo el esquema saludopresentación- mensaje-despedida en ocasiones diversas.

2.1.2 Patrón DAO Contexto El acceso a los datos varía dependiendo de la fuente de los datos. El acceso al almacenamiento persistente, como una base de datos, varía en gran medida dependiendo del tipo de almacenamiento (bases de datos relacionales, bases de datos orientadas a objetos, archivos de texto, etc.) y de la implementación del vendedor.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

61

Problema Muchas aplicaciones de la plataforma JEE en el mundo real necesitan utilizar datos persistentes en algún momento. Para muchas de ellas, este almacenamiento persistente se implementa utilizando diferentes mecanismos, y hay marcadas diferencias en los APIS utilizados para acceder a esos mecanismos de almacenamiento diferentes o datos residentes en sistemas diferentes. Típicamente, las aplicaciones utilizan componentes distribuidos compartidos persistentes como los entity bean para representar la data persistente. Una aplicación es considerada que empleará un bean managed persistence para sus entity beans cuando estas entity beans explícitamente accesen al almacén persistente, es decir, cuando el entity bean incluya código para acceder directamente al almacén persistente. Una aplicación con requerimientos simples no utilizaría entity beans y, en vez de ellos, utilizaría session beans o Servlets para acceder directamente al almacén persistente para recuperar y modificar datos. Las aplicaciones pueden usar la API-JDBC para acceder a los datos que residen en un RDBMS. Esta API permite el acceso estándar y la manipulación de datos en un almacén persistente como una base de datos relacional. JDBC permite a las aplicaciones JEE utilizar sentencias SQL estándar. Sin embargo, las sentencias SQL podrían v ariar dependiendo del DBMS. Solución Utilizar un Data Access Object (DAO) para abstraer y encapsular todos los accesos a la fuente de datos. El DAO maneja la conexión con la fuente de datos para obtener y almacenar datos. El DAO implementa el mecanismo de acceso requerido para trabajar con la fuente de datos. El Objeto de Acceso a Datos (DAO) es el objeto principal de este patrón. La fuente de datos podría ser un almacén persistente como un RDBMS, un servicio externo como B2B, un servicio de negocios accesado vía CORBA. Los componentes del negocio que cuentan con los objetos DAO utilizan una interfaz simple expuesta por el DAO para sus clientes. El DAO completamente oculta la implementación de la fuente de datos y lo aparta de los clientes, debido a que la interfaz expuesta por el DAO no cambia cuando la implementación de la fuente de datos cambia. Este patrón permite al DAO adaptarse a diferentes esquemas de almacenamiento sin afectar a sus clientes o componentes de negocio. DAO esencialmente actúa como un adaptador entre el componente de negocio y la fuente de datos (data source).

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

62

Diagrama de Clases

ESTRATEGIAS DE IMPLEMENTACIÓN DEL PATRÓN DAO Factory El patrón DAO se puede flexibilizar adoptando los patrones Factory y Abstract Factory. Cuando el almacenamiento asociado a la aplicación no está sujeto a cambios de una implementación a otra, esta estrategia se puede implementar utilizando el patrón Factory para producir el número de DAOs que necesita la aplicación. En la siguiente figura, podemos ver el diagrama de clases para este caso:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

63

Abstract Factory Cuando el almacenamiento asociado a la aplicación sí está sujeto a cambios de una implementación a otra, esta estrategia se podría implementar usando el patrón Abstract Factory. Este patrón a su vez puede construir y utilizar la implementación Factory. En este caso, esta estrategia proporciona un objeto factoría abstracta de DAOs (Abstract Factory) que puede construir varios tipos de factorías concretas de DAOs: cada factoría soporta un tipo diferente de implementación del almacenamiento persistente. Una vez que obtenemos la factoría concreta de DAOs para una implementación específica, la utilizamos para producir los DAOs soportados e implementados en esa implementación. En la siguiente figura, podemos ver el diagrama de clases para esta estrategia. En él vemos una fábrica base de DAOs, que es una clase abstracta que extienden e implementan las diferentes factorías concretas de DAOs para soportar el acceso específico a la implementación del almacenamiento. El cliente puede obtener una implementación de la factoría concreta del DAO como una RdbDAOFactory y utilizarla para obtener los DAOs concretos que funcionan en la implementación del almacenamiento. Por ejemplo, el cliente puede obtener una RdbDAOFactory y utilizarlas para obtener DAOs específcios como RdbCustomerDAO, RdbAccountDAO, etc. Los DAOs pueden extender e implementar una clase base genérica (mostradas como DAO1 y DAO2) que describa específicamente los requerimientos del DAO para el objeto de negocio que soporta. Cada DAO concreto es responsable de conectar con la fuente de datos y de obtener y manipular los datos para el objeto de negocio que soporta.

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

64

En la siguiente figura, podemos ver el diagrama de secuencia para esta estrategia:

Contexto resultante DAO permite la transparencia de los detalles de la implementación de la fuente de datos. El acceso es transparente porque los detalles de la implementación se ocultan dentro del DAO. La capa de DAO’s permite una migración más fácil, hace más fácil que una aplicación pueda migrar a una implementación de base de datos diferente. Los objetos de negocio no conocen la implementación de datos subyacente; la migración implica cambios sólo en la capa DAO. Reduce la Complejidad del Código de los Objetos de Negocio. Centraliza todos los accesos a datos en una capa independiente.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

65

2.1.3 Aplicación Listado Estructura del Programa

Modelo de Datos

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

66

Pasos: 1.

Crear la clase ProductoDTO dentro del paquete beans, con los siguientes atributos privados, e implemente los métodos de acceso: set y get.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

67

package beans; public class ProductoDTO { private int codigo; private String descripcion; private double precio; private int stock; private int codMarca; private String nomMarca; public int getCodigo() { return codigo; } public void setCodigo(int codigo) { this.codigo = codigo; } public String getDescripcion() { return descripcion; } public void setDescripcion(String descripcion) { this.descripcion = descripcion; } public double getPrecio() { return precio; } public void setPrecio(double precio) { this.precio = precio; } public int getStock() { return stock; } public void setStock(int stock) { this.stock = stock; } public int getCodMarca() { return codMarca; } public void setCodMarca(int codMarca) { this.codMarca = codMarca; } public String getNomMarca() { return nomMarca; } public void setNomMarca(String nomMarca) { this.nomMarca = nomMarca; } }

2.

Crear una interface ProductoDAO dentro del paquete interfaces, con los siguientes métodos:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

68

3.

Registrar los DAOs(interface) dentro de la clase DAOFactory

4.

En la clase DAOFactory se mostrará

la siguiente imagen:

Esto sucede porque la clase MySqlDAOFactory no existe o se ha realizado cambios en el DAOFactory como registrar más DAOs (RECORDAR).

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

69

5.

Hacer clic en el foco y se mostrará la siguiente imagen:

6.

Hacer doble clic en Create class “MySqlDAOFactory” y se mostrará la siguiente ventana:

7.

Clic en botón Finish.

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

70

8.

Se mostrará una clase nueva con el nombre: MySqlDAOFactory, como se muestra en la siguiente imagen:

9.

En la clase MySqlDAOFactory escribir lo siguiente:

10. Clic en el foco y se mostrará la siguiente imagen:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

71

11. Hacer doble clic en Create class “MySqlProductoDAO”, se mostrará la siguiente ventana:

12. Clic en el botón Finish y se mostrará la siguiente imagen:

Se puede observar que en esta clase se debe implementar los métodos creados en la interface ProductoDAO, es aquí donde se debe escribir los códigos para listar, insertar, modificar, eliminar y buscar.

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

72

13. Implementar el código para listar los registros de la tabla tb_producto, escribir las siguientes líneas dentro del método listarProducto().

14. Crear una clase ProductoService dentro del paquete service y escribir los siguientes códigos:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

73

15. Crear un Servlet con el nombre: ServletProducto dentro del paquete misServlets y escriba lo siguiente:

16. En la página listarProducto.jsp escribir lo siguiente:

17. En la página encabezado.jsp escribir lo siguiente:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

74

18. Cuando se ejecuta la página encabezado.jsp se muestra la siguiente figura:

. 19. Clic en Listar y se muestra lo siguiente:

2.2 Patrón DAO Parte II y Sesiones Web y EL 2.2.1 Lenguaje de Expresiones EL es un lenguaje para acceder a datos de varias fuentes en tiempo de ejecución. Su sintaxis es considerablemente más amigable que la de Java, que es el único lenguaje soportado directamente por la especificación JSP 1.2. Todas las acciones JSTL reconocen expresiones EL en sus valores de atributos, y se podrían desarrollar acciones personalizadas para que hicieran lo mismo. Se espera que EL sea incorporado dentro de la próxima versión de la especificación JSP para mejorar su uso en el acceso a los datos sobre el lenguaje Java. Si es así, podremos usar expresiones EL en un valor de atributo de una acción, o incluso en una plantilla de texto. EL toma prestada de JavaScript la sintaxis para acceder a estructuras de datos tanto como propiedades de un objeto (con el operador.) como con elementos con nombres de un array (con el operador ["nombre"]). Como se ve aquí, una expresión EL siempre debe estar encerrada entre los caracteres $ { y } $. Las dos primeras expresiones acceden a una propiedad llamada myProperty en un objeto representado por una variable llamada myObj. La tercera expresión accede a una propiedad con un nombre contenido en una variable. Esta sintaxis se puede utilizar con cualquier expresión que evalúe el nombre de la propiedad. Estas etiquetas tratan de abstraer la complejidad de introducir código Java (scriptlet) dentro de JSP, del mismo modo que trata de evitar que cada equipo de desarrollo cree un juego de etiquetas no estándar para las mismas labores. sessionScope-------------------recupera una variable de sesión requestScope-------------------recupera variable que el servlet envía a un jsp

2.2.2 Aplicación Mantenimiento Trabajar con el proyecto anterior: Proyecto_DAO2. Pasos a seguir:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

1.

75

Implementar los métodos que se encuentra en la clase “MySqlProductoDAO”:

package dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; import utils.MysqlDBConexion; import beans.ProductoDTO; import interfaces.ProductoDAO; public class MySqlProductoDAO implements ProductoDAO{ @Override public ProductoDTO buscarProducto(int cod) { ProductoDTO obj=null; Connection cn=null; PreparedStatement pstm=null; ResultSet rs=null; try { cn=MysqlDBConexion.getConexion(); String sql="select *from tb_producto where cod_pro=?"; pstm=cn.prepareStatement(sql); pstm.setInt(1, cod); rs=pstm.executeQuery(); if(rs.next()){ obj=new ProductoDTO(); obj.setCodigo(rs.getInt(1)); obj.setDescripcion(rs.getString(2)); obj.setPrecio(rs.getDouble(3)); obj.setStock(rs.getInt(4)); obj.setNomMarca(rs.getString(5)); } } catch (Exception e) { e.printStackTrace(); } finally{ try { if(rs!=null)rs.close(); if(pstm!=null)pstm.close(); if(cn!=null)cn.close(); } catch (Exception e2) { e2.printStackTrace(); } } return obj; }

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

76

@Override public int registrarProducto(ProductoDTO obj) { int estado=-1; Connection cn=null; PreparedStatement pstm=null; try { cn=MysqlDBConexion.getConexion(); String sql="insert into tb_producto values(null,?,?,?,?)"; pstm=cn.prepareStatement(sql); pstm.setString(1, obj.getDescripcion()); pstm.setDouble(2, obj.getPrecio()); pstm.setInt(3, obj.getStock()); pstm.setInt(4, obj.getCodMarca()); estado=pstm.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ try { if(pstm!=null)pstm.close(); if(cn!=null)cn.close(); } catch (Exception e2) { e2.printStackTrace(); } } return estado; } @Override public int actualizarProducto(ProductoDTO obj) { int estado=-1; Connection cn=null; PreparedStatement pstm=null; try { cn=MysqlDBConexion.getConexion(); String sql="update tb_producto set des_pro=?,pre_pro=?,stock_act_pro=?,cod_mar= ? where cod_pro=?"; pstm=cn.prepareStatement(sql); pstm.setString(1, obj.getDescripcion()); pstm.setDouble(2, obj.getPrecio()); pstm.setInt(3, obj.getStock()); pstm.setInt(4, obj.getCodMarca()); pstm.setInt(5, obj.getCodigo()); estado=pstm.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ try { if(pstm!=null)pstm.close(); if(cn!=null)cn.close(); } catch (Exception e2) { e2.printStackTrace(); } } return estado; }

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

77

@Override public int eliminarProducto(int cod) { int estado=-1; Connection cn=null; PreparedStatement pstm=null; try { cn=MysqlDBConexion.getConexion(); String sql="delete from tb_producto where cod_pro=?"; pstm=cn.prepareStatement(sql); pstm.setInt(1, cod); estado=pstm.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ try { if(pstm!=null)pstm.close(); if(cn!=null)cn.close(); } catch (Exception e2) { e2.printStackTrace(); } } return estado; } @Override public List listarProducto() { List data=new ArrayList(); ProductoDTO obj=null; Connection cn=null; PreparedStatement pstm=null; ResultSet rs=null; try { cn=MysqlDBConexion.getConexion(); String sql="select p.cod_pro,p.des_pro,p.pre_pro,p.stock_act_pro," + "m.nom_mar from tb_producto p inner join tb_marca m " + "on p.cod_mar=m.cod_mar"; pstm=cn.prepareStatement(sql); rs=pstm.executeQuery(); while(rs.next()){ obj=new ProductoDTO(); obj.setCodigo(rs.getInt(1)); obj.setDescripcion(rs.getString(2)); obj.setPrecio(rs.getDouble(3)); obj.setStock(rs.getInt(4)); obj.setNomMarca(rs.getString(5)); data.add(obj); } } catch (Exception e) { e.printStackTrace(); } return data; }

}

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

78

2. Modificar la clase ProductoService: package service; import interfaces.ProductoDAO; import java.util.List; import utils.Constantes; import dao.DAOFactory; import beans.ProductoDTO; public class ProductoService { DAOFactory fabrica=DAOFactory.getDAOFactory(Constantes.ORIGEN_DATOS); ProductoDAO objPro=fabrica.getProducto(); public List listaProducto() { return objPro.listarProducto(); } public ProductoDTO buscaProducto(int cod) { return objPro.buscarProducto(cod); } public int registraProducto(ProductoDTO obj) { return objPro.registrarProducto(obj); } public int actualizaProducto(ProductoDTO obj) { return objPro.actualizarProducto(obj); } public int EliminaProducto(int cod) { return objPro.eliminarProducto(cod); } }

3.

Modificar el servlet ServletProducto:

package misServlets; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import beans.ProductoDTO; import service.ProductoService; public class ServletProducto extends HttpServlet { private static final long serialVersionUID = 1L; ProductoService serviProducto=new ProductoService(); protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub String xtipo=request.getParameter("tipo"); if(xtipo.equals("listar")) listar(request,response); else if(xtipo.equals("buscar")) buscar(request,response); else if(xtipo.equals("registrar")) registrar(request,response); else if(xtipo.equals("actualizar")) actualizar(request,response); else if(xtipo.equals("eliminar")) eliminar(request,response); }

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

79

private void eliminar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int cod=Integer.parseInt(request.getParameter("cod")); serviProducto.EliminaProducto(cod); listar(request, response); } private void buscar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int cod=Integer.parseInt(request.getParameter("cod")); request.setAttribute("Producto",serviProducto.buscaProducto(cod)); request.getRequestDispatcher("actualizarProducto.jsp"). forward(request, response); } private void actualizar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int marca,stock,cod; cod=Integer.parseInt(request.getParameter("txt_cod")); String des=request.getParameter("txt_des"); double pre=Double.parseDouble(request.getParameter("txt_pre")); stock=Integer.parseInt(request.getParameter("txt_stock")); marca=Integer.parseInt(request.getParameter("cbo_marca")); ProductoDTO obj=new ProductoDTO(); obj.setCodigo(cod); obj.setDescripcion(des); obj.setPrecio(pre); obj.setStock(stock); obj.setCodMarca(marca); serviProducto.actualizaProducto(obj); listar(request, response); } private void registrar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int marca,stock; String des=request.getParameter("txt_des"); double pre=Double.parseDouble(request.getParameter("txt_pre")); stock=Integer.parseInt(request.getParameter("txt_stock")); marca=Integer.parseInt(request.getParameter("cbo_marca")); ProductoDTO obj=new ProductoDTO(); obj.setDescripcion(des); obj.setPrecio(pre); obj.setStock(stock); obj.setCodMarca(marca); serviProducto.registraProducto(obj); listar(request, response); } private void listar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("data", serviProducto.listaProducto()); request.getRequestDispatcher("listarProducto.jsp"). forward(request, response); } }

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

80

4. Cuando se ejecuta la página encabezado.jsp se muestra la siguiente figura:

5. Clic en Nuevo, se mostrará la página: registrarProducto.jsp

Código: Insert title here $(document).ready( function(){ $("#frmagregar").validate(); }); o gt = o gt && o and || o or ! o not empty

105

División Módulo (resto) Comprueba Igualdad. Comprueba desigualdad. Comprueba menor que. Comprueba mayor que. Comprueba menor o igual que. Comprueba mayor o igual que. Comrpueba AND lógico. Comprueba OR lógico. Complemento binario booleano Comprueba un valor vacío (null, string vacío o una collección vacía)

Lo que no encontraremos en EL son sentencias como asignaciones, if/else o while. Para este tipo de funcionalidades, en JSP se usan los elementos Action. EL no está pensado para utilizarse como un lenguaje de programación de propósito general, sólo un lenguaje de acceso a datos. Cualquier objeto en uno de los ámbitos de JSP (página, solicitud, sesión o aplicación) se puede utilizar como una variable en una expresión EL. Por ejemplo, si tenemos un bean con una propiedad firstName en el ámbito de la solicitud bajo el nombre customer, esta expresión EL representa el valor de la propiedad firstName del bean. ${customer.firstName} Sin embargo, EL también hace que la información de la solicitud y la información general del contenedor esté disponible como un conjunto de variables implícitas: Variable Param paramValues Header headerValues Cookie initParams pageContext pageScope requestScope sessionScope applicationScope

Descripción Una collection de todos los valores de los parámetros de la solicitud como un sólo valor string para cada parámetro Una collection de todos los valores de los parámetros de la solicitud como un array de valores string por cada parámetro Una collection de todas las cabeceras de solicitud como un sólo valor string por cada cabecera Una collection de todos los valores de cabecera de la solicitud como un array de valores string por cada cabecera Una collection con todas las cookies de la solicitud en un sólo ejemplar de javax.servlet.http.Cookie por cada cokkie Una collection de todos los parámetros de inicialización de la aplicación en un sólo valor string por cada parámetro Un ejemplar de la clase javax.servlet.jspPageContext Una collection de todos los objetos en el ámbito de la página Una collection de todos los objetos en el ámbito de la solicitud Una collection de todos los objetos en el ámbito de la sesión Una collection de todos los objetos en el ámbito de la aplicación

Las cinco primeras variables implícitas de la tabla nos ofrecen acceso a los valores de parámetros, cabeceras y cookies de la solicitud actual. Aquí hay un ejemplo de cómo acceder a un parámetro de solicitud llamado listType y a la cabecera User-Agent:

${param.listType} ${header['User-Agent']}

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

106

Observe cómo se debe usar la sintaxis de array para la cabecera, porque el nombre incluye un guion; con la sintaxis de propiedad, sería interpretado como la expresión variable header.User menos el valor de una variable llamada Agent. La variable initParameter proporciona acceso a los parámetros de inicialización que se definen en el archivo web.xml de la aplicación. La variable pageContext tiene varias propiedades que proporcionan acceso al objeto servlet que representa la solicitud, la respuesta, la sesión y la aplicación, etc. Las cuatro últimas variables son colecciones que contienen todos los objetos de cada ámbito específico. Podemos usarlas para limitar la búsqueda de un objeto en sólo un ámbito en lugar de buscar en todos ellos, lo que está por defecto si no se especifica ningún ámbito. En otras palabras, si hay un objeto llamado customer en el ámbito de sesión, estas dos primeras expresiones encuentran el mismo objeto, pero la tercera vuelve vacía: ${customer} ${sessionScope.customer} ${requestScope.customer} Todas las acciones JSTL aceptan expresiones EL cómo valores de atributo, para todos los atributos excepto para var y scope, porque estos valores de atributo podrían usarse para chequear el tipo en el momento de la traducción en una futura versión. Hay un atributo de una acción JSTL adicional que no toma un valor de expresión EL, pero sólo se usa en la librería XML, por eso lo ignoraremos por ahora. Se pueden usar una o más expresiones EL en el mismo valor de atributo, y el texto fijo y las expresiones EL se pueden mezclar en el mismo valor de atributo: First name: <c:out value="${customer.firstName}" /> <c:out value="First name: ${customer.firstName}" />

Antes de saltar a ver ejemplos de utilización de las acciones Core, se verá lo que dijimos anteriormente: todas las acciones JSTL de la librería EL aceptan expresiones EL. Realmente hay un conjunto paralelo de librerías JSTL, llamado conjunto de librería RT que sólo acepta expresiones Java del antiguo estilo: First name:

Procesamiento Condicional y Bucles Veamos algunos ejemplos de cómo podemos usar el JSTL condicional y las acciones de iteración: ; , , y un triple ; y . Por el camino, también usaremos acciones de salida básica y de selección de variables: y . nos permite incluir, o procesar, condicionalmente una parte de una página, dependiendo de la información durante la ejecución. Este ejemplo incluye un saludo personal si el usuario es un visitante repetitivo, según lo indica la presencia de una cookie con el nombre del usuario:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

107

Welcome back

El valor del atributo test es una expresión EL que chequea si la cookie existe. El operador empty combinado con el operador "not" (!) significa que evalúa a true si el cookie no existe, haciendo que el cuerpo del elemento sea procesado. Dentro del cuerpo, la acción añade el valor de la cookie a la respuesta. Así de sencillo. Pasar a través de una colección de datos es casi tan sencillo. Este fragmento itera sobre una colección de filas de una base de datos con información del tiempo de diferentes ciudades: City: Tomorrow's high: Tomorrow's low: La expresión EL para el valor items obtiene el valor de la propiedad rows desde un objeto representado por la variable forecasts. Como aprenderemos más adelante, las acciones de bases de datos de JSTL representan un resultado de consulta como un ejemplar de una clase llamada javax.servlet.jsp.jstl.sql.Result. Esta clase se puede utilizar como un bean con varias propiedades. La propiedad rows contiene un array de ejemplares java.util.SortedMap, donde cada uno representa una fila con valores de columnas. La acción procesa su cuerpo una vez por cada elemento de la colección especificado por el atributo ítems. Además de que con arrays, la acción funciona con cualquier otro tipo de dato que represente una colección, como ejemplares de las clases java.util.Collection o java.util.Map. Si se especifica el atributo var, el elemento actual de la colección se hace disponible para las acciones del cuerpo como una variable con el nombre especificado. Aquí se llamaba city y, como la colección es un array de maps, esta variable contiene un nuevo map con valores de columnas cada vez que se procesa el cuerpo. Los valores de las columnas se añaden a la respuesta por el mismo tipo de acciones que hemos visto en ejemplos anteriores. Para ilustrar el uso del resto de las acciones condicionales, extendamos el ejemplo de iteracción para procesar sólo un conjunto fijo de filas por cada página solicitada, añadamos enlaces "Previous" y "Next" a la misma página. El usuario puede entonces pasar sobre los resultados de la base de datos, mirando unas pocas filas cada vez, asumiendo que el objeto Result se ha grabado en el ámbito de la sesión. Aquí está cómo procesar sólo algunas filas:

City: Tomorrow's high: Tomorrow's low:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

108

La acción selecciona una variable con el valor especificado por el atributo value; que puede ser un valor estático, como en este ejemplo, o una expresión EL. También, podemos especificar el ámbito de la variable con el atributo scope (page, request, session o application). En este ejemplo, hemos seleccionado una variable llamada noOfRows a 10 en el ámbito de la página (por defecto). Este es el número de filas que mostraremos en cada solicitud. El , en este ejemplo, toma los mismos valores para los atributos ítems y var como antes, pero hemos añadido dos nuevos atributos:  El atributo begin toma el índice (base 0) del primer elemento de la colección a procesar. Aquí se selecciona al valor de un parámetro de solicitud llamado first. Para la primera solicitud, este parámetro no está disponible, por eso la expresión se evalúa a 0; en otras palabras, la primea fila.  El atributo end específica el índice del último elemento de la colección a procesar. Aquí lo hemos seleccionado al valor del parámetro first más noOfRows menos uno. Para la primera solicitud, cuando no existe el parámetro de la solicitud, este resultado es 9, por eso la acción itera sobre los índices del 0 al 9. Luego, añadimos los enlaces "Previous" y "Next":

Previous Page Previous Page Next Page Next Page

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

109

El agrupa una o más acciones , cada una especificando una condición booleana diferente. La acción chequea cada condición en orden y sólo permite la primera acción con una condición que se evalúe a true para procesar su cuerpo. El cuerpo también podría contener un . Su cuerpo sólo se procesa si ninguna de las condiciones de los es true. En este ejemplo, la primera acción comprueba si el parámetro first es mayor que cero, es decir, si la página muestra un subconjunto de filas distinto del primero. Si esto es cierto, el cuerpo de la acción añade un enlace a la misma página con un parámetro first seleccionado al índice del subconjunto anterior. Si no es true, se procesa el cuerpo de la acción , añadiendo sólo el texto "Previous Page". El segundo bloque proporciona lógica similar para añadir el enlace "Next Page".

Internacionalización y Formateo Las grandes sites normalmente necesitan complacer a los visitantes de todo el mundo, por lo que servir el contenido sólo en un idioma no es suficiente. Para desarrollar una site que proporcione una elección de idiomas, tenemos dos opciones:  Escribir un conjunto de páginas para cada idioma  Escribir un conjunto compartido de páginas que ponga el contenido en diferentes idiomas desde fuentes externas Frecuentemente, terminaremos con una mezcla de estas técnicas, usar páginas separadas para la mayoría de las grandes cantidades de contenido estático y páginas compartidas cuando la cantidad de contenido sea pequeña, pero dinámica (por ejemplo, una página con unas pocas etiquetas fijas mostradas en diferentes idiomas y todos los demás datos que vengan desde una base de datos). Preparar una aplicación para varios idiomas se llama internacionalización (comúnmente abreviado i18n); y hacer que el contenido esté disponible para un idioma específico se llama localización (o l10n). Para hacer esto, necesitamos considerar otras cosas además del idioma: cómo se formatean las fechas y números entre los diferentes países e, incluso, dentro de los países. También, podríamos necesitar adaptar los colores, las imágenes y otro contenido no textual. El término localidad se refiere a un conjunto de reglas y contenido aceptable para una región o cultura. Formateo de Fechas y Números Sensible a la Localidad JSTL incluye un conjunto de acciones para simplificar la internacionalización, principalmente cuando páginas compartidas se usan para varios idiomas. Primero, veamos cómo formatear apropiadamente fechas y números. Este ejemplo formatea la fecha actual y un número basándose en las reglas de la localidad por defecto: Formatting with the default locale Date: Number: CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

110

La primera línea es la directiva taglib para la librería JSTL que contiene las acciones de formateo e internacionalización. El prefijo por defecto, usado aquí, es fmt. Para obtener un valor a formatear, entonces crea un objeto java.util.Date que representa la fecha y hora actuales, y lo graba como una variable llamada now. Ya estamos preparados para hacer algún formateo sensible a la localidad. La acción JSTL formatea el valor de la variable now asignado al valor del atributo value usando el tipo de expresión EL que aprendimos en la página anterior. El atributo dateStyle le dice a la acción cómo debe formatear la fecha. Podemos usar cualquiera de los valores default, short, medium, long, o full para el atributo dateStyle. El tipo de formateo que representa cada uno de estos tipos depende exactamente de la localidad. Para la localidad English, full resulta en un string como Thursday, August 29, 2002. En este ejemplo, sólo hemos formateado la parte de la fecha, pero también podemos incluir la parte de la hora (o formatear sólo la hora), y definir reglas de formateo personalizadas tanto para la fecha como para la hora en lugar de los estilos dependientes de la localidad: El atributo pattern toma un patrón de formateo personalizado del mismo tipo que la clase java.text.SimpleDateFormat. El patrón usado aquí resulta en Thursday, 29 August 2002, 17:29 con la localidad English. La acción soporta atributos similares para especificar cómo formatear un número usando estilos dependientes de la localidad para números normales, valores de moneda, o un porcentaje, así como usar patrones personalizados de diferentes tipos. Acceder a una Base de Datos Un sujeto de controversia es la inclusión en JSTL de acciones para acceder a bases de datos. Alguna gente ve esto como una mala práctica y argumenta que todos los accesos a bases de datos se deberían realizar desde componentes Java puros en una aplicación basada en MVC en lugar de desde página JSP. Este precepto es para aplicaciones que son extensas, ya que resulta bien práctico utilizar JSTL para aplicaciones sencillas. Sin el soporte de JSTL, estas aplicaciones normalmente terminan con el código para acceder a la base de datos dentro de scriptles, lo que es peor todavía para un mantenimiento y desarrollo correctos. Por lo tanto, veremos cómo acceder a bases de datos desde páginas JSP; sin embargo, esta aproximación no es la mejor para todos los tipos de aplicaciones. Si el equipo de desarrollo incluye programadores Java, se debería considerar seriamente encapsular el código de acceso a la base de datos en clases Java, y utilizar las JSP sólo para mostrar los resultados. Las acciones de bases de datos de JSTL están basadas en el API JDBC de Java y usan las abstracciones javax.sql.DataSource presentada en JDBC 2.0 para representar una base de datos. Un DataSource proporciona conexiones a una base de datos y puede implementar una característica llamada almacén de conexiones. Abrir una conexión física a una base de datos es una operación que consume mucho tiempo. Con el almacenamiento de conexiones, sólo necesitamos hacerlo una vez, y la misma conexión se puede reutilizar una y otra vez, sin los riesgos de problemas asociados con otras aproximaciones de compartición de conexiones.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

111

Poner un objeto DataSource a Disposición de JSTL JSTL soporta varias formas para hacer que un objeto DataSource esté disponible para las acciones de bases de datos. En un contenedor web con soporte JNDI (Java Naming and Directory Interface), se puede definir un DataSource por defecto como un recurso JNDI con un parámetro de contexto en el archivo web.xml: < context-param>

javax.servlet.jsp.jstl.sql.dataSource jdbc/Production Se deben utilizar las herramientas de configuración JNDI del contenedor WEB para configurar un recurso JNDI con el nombre especificado; por ejemplo, con un nombre de usuario y un password de una cuenta de usuario en una base de datos, las conexiones mínimas y máximas en el almacen, etc. La forma de realizar esto varía entre los contenedores y está fuera del ámbito de este artículo. Una alternativa para los contenedores que no soportan JNDI es que un oyente del ciclo de vida de la aplicación (contexto del servlet) cree y configure un DataSource y lo seleccione como el valor por defecto usando la clase Config de JSTL: import javax.servlet.*; import javax.servlet.http.*; import oracle.jdbc.pool.*; public class AppListener implements ServletContextListener { private OracleConnectionCacheImpl ds =null; public void contextInitialized(ServletContextEvent sce){ ServletContext application =sce.getServletContext(); try { ds = new OracleConnectionCacheImpl(); ds.setURL("jdbc:oracle:thin:@voyager2:1521:Oracle9i"); ds.setMaxLimit(20); ds.setUser("scott"); ds.setPassword("tiger"); } catch (Exception e){ application.log("Failed to create data source:"+ e.getMessage()); } Config.set(application, Config.SQL_DATASOURCE, ds); } ... }

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

112

La clase oyente de este ejemplo crea un DataSource con capacidades de almacén de conexiones para una base de datos Oracle9i, y la hace disponible como por defecto para las acciones JSTL usando la clase Config para seleccionar la variable de configuración correspondiente. Otra forma, sólo disponible para prototipos o aplicaciones que no van a utilizarse tan duramente como para necesitar el almacén de conexiones, es usar la acción : Esta acción crea una sencilla fuente de datos, sin almacenamiento, para la URL JDBC especificada, con el usuario y la password, usando el driver JDBC especificado. Podríamos usar esta acción para empezar, pero recomendamos la utilización de una de las otras alternativas para una site del mundo real. Además de privarnos del almacén de conexiones para una fuente de datos creada de esta forma, no es una buena idea incluir información sensible como la URL de la base de datos, el nombre de usuario y la password en una página JSP, ya que sería posible para alguien acceder al código fuente de la página. Leer Datos de la Base de Datos Con una DataSource a nuestra disposición, podemos acceder a la base de datos. Aquí podemos leer datos desde una base de datos representada por el DataSource por defecto: Reading database data ... Primero, necesitamos declarar la librería JSTL que contiene las acciones de bases de datos, usando la directiva taglib de la parte superior de este ejemplo. La acción ejecuta la sentencia SQL SELECT especificada por el atributo sql (o como el cuerpo del elemento acción) y graba los resultados en una variable nombrada por el atributo var. El resultado de la consulta a la base de datos se devuelve como un bean del tipo javax.servlet.jsp.jstl.sql.Result con varias propiedades de solo lectura:

Propiedad Rows

Tipo Java

Descripción Un array con un mapa insensible a las java.util.SortedMap[] mayúsculas por cada fila con las claves

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

rowsByIndex

Object[][]

columnNames rowCount

String[] Int

limitedByMaxRows

boolean

113

correspondiendo con los nombres de columna y valores correspondiendo con los valores de columna Un array con un array por fila con valores de columna Un array con nombres de columnas El número de filas en el resultado true si no se han incluido todas las filas debido a que se ha alcanzado el límite máximo de filas especificado

Ya vimos cómo utilizar la acción para mostrar todas o sólo algunas filas, por eso ahora veremos cómo podemos obtener sólo algunas filas para mostrarlas todas en esta parte. Los enlaces Next y Previous le permiten al usuario solicitar un conjunto diferente. Primero, aquí está cómo leer un subconjunto de filas y luego mostrar el subconjunto completo: SELECT * FROM Employee

El atributo startRow para la acción se envía a una expresión EL que lee el valor de un parámetro de solicitud llamado start. Luego veremos cómo cambia este valor cuando se pulsa sobre los enlaces Next y Previous. La primera vez que se accede a la página, el parámetro no existe, por eso la expresión se evalúa a 0. Esto significa que el resultado de la consulta contiene filas empezando con la primera que corresponda (índice 0). El atributo maxRows limita el número total de filas del valor de la variable noOfRows, lo seleccionamos a 10 en este ejemplo. La acción hace un bucle sobre todas las columnas del resultado y genera una lista de ítems con los valores de columna por cada fila. También, debemos generar los enlaces Next y Previous para permitir que el usuario seleccione un nuevo conjunto de filas: Previous Page Previous Page Next Page Next Page CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

114

El primer bloque es idéntico al de la página 1; si el parámetro de la solicitud start es mayor que cero, la página actual muestra un subconjunto de filas distinto del primero, por eso se añade un enlace Previous. El enlace apunta hacia la misma página, e incluye el parámetro start con un valor que es el valor actual menos el número de filas mostrado por cada página. El segundo bloque se aprovecha de la propiedad limitedByMaxRows del resultado de la consulta. Si esta propiedad es true, significa que se ha truncado el resultado al número de filas mostrado por cada página. De aquí, se genera el enlace Next con valor del parámetro start para el nuevo subconjunto de filas. Escribir Datos en la Base de Datos Además de leer datos desde una base de datos, también podemos usar JSTL para actualizar información. Este ejemplo muestra cómo insertar una nueva fila en una tabla: INSERT INTO Employee (FirstName, LastName, EmpDate) VALUES(?, ?, ?)

Antes de insertar la fila, este ejemplo ilustra cómo usar las acciones de validación JSTL. La página espera que todos los datos para la nueva fila se envíen como parámetros de solicitud (quizás introducidos en un formulario HTML), incluyendo una fecha de contratación. Antes de que la fecha se pueda insertar en la base de datos, debemos convertirla a su forma nativa Java. Esto es lo que hace la acción . El atributo value contiene una expresión EL que obtiene el valor del parámetro de solicitud empDate. La acción trata de interpretarlo como una fecha escrita en el formato especificado por el atributo pattern (un año de cuatro dígitos, seguido por dos dígitos del mes y dos dígitos del día, separados por barras inclinadas). Si tiene éxito, almacena la fecha en su forma nativa con el nombre especificado por el atributo var. La acción tiene en cuenta los strings inválidos. Si el valor del parámetro no puede ser interpretado como una fecha, el lanza una excepción, que la acción captura y graba en la variable especificada. Cuando esto sucede, la condición de comprobación de la acción se evalúa a true, por lo que la fecha de contratación es creada por la acción anidada. Para insertar la fila, usamos la acción . Como la acción de consulta, la sentencia SQL se puede especificar como el cuerpo del elemento o mediante un atributo sql. La acción se puede usar para ejecutar sentencias INSERT,

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

115

UPDATE, DELETE, así como sentencias para crear o eliminar objetos en la base de datos, como CREATE TABLE y DROP TABLE. El número de filas afectado por la sentencia puede capturarse de forma opcional en una variable nombrada por el atributo var. En este ejemplo (como en las mayoría de las aplicaciones del mundo real), no se conocen los nombres de las columnas en tiempo de ejecución; vienen de los parámetros de la solicitud. Por lo tanto, la sentencia INSERT de SQL incluye una marca de interrogación por cada valor como un contenedor y parámetros internos de la acción que seleccionan el valor dinámicamente. Las columnas FirstName y LastName son columnas de texto y las acciones seleccionan sus valores al valor del parámetro de solicitud correspondiente. Sin embargo, la columna EmpDate es una columna de fecha, demandando una atención especial. Primero de todo, debemos usar una variable que contenga la fecha en su forma nativa (un objeto java.util.Date) en lugar de usar el valor del parámetro de solicitud, usamos la variable creada por las acciones o . Segundo, debemos usar la acción para seleccionar el valor. En este ejemplo, hemos usado la parte de la fecha, por eso hemos seleccionado el atributo opcional type a date. Otros valores válidos son time y timestamp (por defecto), para las columnas que sólo toman la hora, o la fecha y la hora. Hay una acción JSTL más que no hemos descrito hasta ahora: . Podemos usarla para agrupar varias acciones update (o incluso query) donde todas ellas se deben ejecutar como parte de la misma transacción de la base de datos. El ejemplo estándar es transferir una cantidad de dinero de una cuenta a otra; implementada como una sentencia SQL que elimina el dinero de la primera cuenta y otra sentencia que lo añade a la segunda. Si encapsulamos todos los accesos a una base de datos en clases Java en lugar de usar las acciones de JSTL, todavía hay una parte de JSTL que nos puede ser útil. Es una clase llamada javax.servlet.jsp.jstl.sql.ResultSupport, con estos dos métodos: public static Result toResult(java.sql.ResultSet rs); public static Result toResult(java.sql.ResultSet rs, int maxRows); Podemos usar esta clase para convertir un objeto ResultSet estándar JDBC en un objeto Result JSTL antes de reenviarlo a la página JSP para mostrarlo. Las acciones JSTL pueden acceder fácilmente a los datos de un objeto Result, como vimos anteriormente. Otra aproximación, todavía mejor, es pasar el resultado de la consulta a la página JSP como una estructura de datos personalizada, como una List de beans que contienen los datos de cada fila, pero el objeto Result aún es un buen candidato para prototipos y pequeñas aplicaciones. Función fn:contains(string, substring) fn:containsIgnoreCase(string, substring) fn:endsWith(string, suffix) fn:escapeXml(string)

CIBERTEC

Descripción Devuelve true si el string contiene substring. Devuelve true si el string contiene a substring, ignorando capitalización. Devuelve true si el string termina con suffix. Devuelve el string con todos aquellos caracteres con especial significado en

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

fn:indexOf(string, substring) fn:join(array, separator)

fn:length(item)

fn:replace(string, before, after)

fn:split(string, separator)

fn:startsWith(string, prefix) fn:substring(string, begin, end)

fn:substringAfter(string, substring) fn:substringBefore(string, substring) fn:toLowerCase(string)

fn:toUpperCase(string)

fn:trim(string)

116

XML y HTML convertidos a sus códigos de escape pertinentes. Devuelve la primera ocurrencia de substring en el string. Devuelve un string compuesto por los elementos del array, separados por separator. Devuelve el número de elementos en ítem (si un array o colección), o el número de caracteres (es un string). Devuelve un string donde todas las ocurrencias del string before han sido reemplazadas por el string after. Devuelve un array donde los elementos son las partes del string separadas por separator. Devuelve true si el string comienza por prefix. Devuelve la parte del string que comienza por el índice begin y que acaba en el índice end. Devuelve la parte del string que sigue a substring. Devuelve la parte de string que precede a substring. Devuelve un string con todos los caracteres de la entrada convertidos a minúsculas. Devuelve un string con todos los caracteres de la entrada convertidos a mayúsculas. Devuelve un string sin espacios en sus laterales.

3.1.4 Aplicación Listado con JSTL Recuperar el proyecto anterior Pasos a seguir: 1. Proceda a copiar todos los jar que se entregó en clase dentro de la carpeta lib del proyecto web.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

117

2. Abrir la página listarProducto.jsp y escribir la directiva para trabajar con jstl.

3.

Modificar el listado de los productos como se muestra en la siguiente imagen:

Cambiar por

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

118

3.2 Ajax y Transacciones en Web 3.2.1 Ajax Ajax es una tecnología asíncrona, en el sentido de que los datos adicionales se solicitan al servidor y se cargan en segundo plano sin interferir con la visualización ni el comportamiento de la página.

Realizar peticiones al servidor y esperar respuesta puede consumir tiempo (el tiempo necesario para recargar una página completa). Para agilizar los desarrollos web surgió Ajax (inicialmente Asynchronous JavaScript And XML, aunque hoy día ya no es una tecnología ligada a XML con lo cual no pueden asociarse las siglas a estos términos), una tecnología que busca evitar las demoras propias de las peticiones y respuestas del servidor mediante la transmisión de datos en segundo plano usando un protocolo específicamente diseñado para la transmisión rápida de pequeños paquetes de datos. Con Ajax, se hace posible realizar peticiones al servidor y obtener respuesta de este en segundo plano (sin necesidad de recargar la página web completa) y usar esos

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

119

datos para, a través de JavaScript, modificar los contenidos de la página creando efectos dinámicos y rápidos. En el esquema anterior vemos las ideas en torno a Ajax de forma gráfica. En la parte superior hemos representado lo que sería un esquema de comunicación tradicional: el cliente solicita una página web completa al servidor. El servidor recibe la petición, se toma su tiempo para preparar la respuesta y la envía. El resultado, una pequeña demora debido al tiempo que tarda en llegar la petición al servidor, el tiempo que éste tarda en preparar la respuesta, y el tiempo que tarda en llegar la respuesta más recargarse en el navegador. En la parte inferior vemos lo que sería un esquema de comunicación usando Ajax: el cliente tiene una página web cargada (puede ser una página web completa, o sólo el esqueleto de una página web). El cliente sigue trabajando y en segundo plano (de ahí que hayamos dibujado con líneas punteadas las comunicaciones) le dice al servidor que le envíe un paquete de datos que le hacen falta. El servidor procesa la petición. Ahora la respuesta es mucho más rápida: no tiene que elaborar una página web completa, sino sólo preparar un paquete de datos. Por tanto el tiempo de respuesta es más rápido. El servidor envía el paquete de datos al cliente y el cliente los usa para cambiar los contenidos que se estaban mostrando en la página web. Funciones para Ajax Las funciones y utilidades relacionadas con AJAX son parte fundamental de jQuery. El método principal para realizar peticiones AJAX es $.ajax() (importante no olvidar el punto entre $ y ajax). A partir de esta función básica, se han definido otras funciones relacionadas, de más alto nivel y especializadas en tareas concretas: $.get(), $.post(), $.load(), etc. La sintaxis de $.ajax() es muy sencilla: $.ajax(opciones);

La URL que se solicita también se incluye dentro del array asociativo de opciones. A continuación se muestra un ejemplo básico realizado con $.ajax(): $.ajax({ url: 'pagina o servlet', type: 'POST', async: true, data: 'parametro1=valor1¶metro2=valor2', success: procesaRespuesta, error: muestraError });

La siguiente tabla muestra todas las opciones que se pueden definir para el método $.ajax():

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

Opción

120

Descripción

async

Indica si la petición es asíncrona. Su valor por defecto es true, el habitual para las peticiones AJAX

beforeSend

Permite indicar una función que modifique el objeto XMLHttpRequest antes de realizar la petición. El propio objeto XMLHttpRequest se pasa como único argumento de la función

complete

Permite establecer la función que se ejecuta cuando una petición se ha completado (y después de ejecutar, si se han establecido, las funciones de success o error). La función recibe el objetoXMLHttpRequest como primer parámetro y el resultado de la petición como segundo argumento

contentType

Indica el valor de la cabecera Content-Type utilizada para realizar la petición. Su valor por defecto esapplication/x-www-form-urlencoded

data

Información que se incluye en la petición. Se utiliza para enviar parámetros al servidor. Si es una cadena de texto, se envía tal cual, por lo que su formato debería ser parametro1=valor1¶metro2=valor2. También se puede indicar un array asociativo de pares clave/valor que se convierten automáticamente en una cadena tipo query string

dataType

El tipo de dato que se espera como respuesta. Si no se indica ningún valor, jQuery lo deduce a partir de las cabeceras de la respuesta. Los posibles valores son: xml (se devuelve un documento XML correspondiente al valor responseXML), html (devuelve directamente la respuesta del servidor mediante el valor responseText), script (se evalúa la respuesta como si fuera JavaScript y se devuelve el resultado) y json (se evalúa la respuesta como si fuera JSON y se devuelve el objeto JavaScript generado)

error

Indica la función que se ejecuta cuando se produce un error durante la petición. Esta función recibe el objeto XMLHttpRequest como primer parámetro, una cadena de texto indicando el error como segundo parámetro y un objeto con la excepción producida como tercer parámetro

ifModified

Permite considerar como correcta la petición solamente si la respuesta recibida es diferente de la anterior respuesta. Por defecto su valor es false

processData

Indica si se transforman los datos de la opción data para convertirlos en una cadena de texto. Si se indica un valor de false, no se realiza esta transformación automática

success

Permite establecer la función que se ejecuta cuando una petición se ha completado de forma correcta. La función recibe como primer parámetro los datos recibidos del servidor, previamente formateados según se especifique en la opción dataType

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

Opción timeout

type url

121

Descripción Indica el tiempo máximo, en milisegundos, que la petición espera la respuesta del servidor antes de anular la petición El tipo de petición que se realiza. Su valor por defecto es GET, aunque también se puede utilizar el método POST La URL del servidor a la que se realiza la petición

3.2.2 Transacciones Un sistema de procesamiento de transacciones (TPS por sus siglas en inglés) es un tipo de sistema de información que recolecta, almacena, modifica y recupera toda la información generada por las transacciones producidas en una organización. Una transacción es un evento que genera o modifica los datos que se encuentran eventualmente almacenados en un sistema de información. Para que un sistema informático pueda ser considerado como un TPS, este debe superar el test ACID. Desde un punto de vista técnico, un TPS monitoriza los programas transaccionales (un tipo especial de programas). La base de un programa transaccional está en que gestiona los datos de forma que estos deben ser siempre consistentes (por ejemplo, si se realiza un pago con una tarjeta electrónica, la cantidad de dinero de la cuenta sobre la que realiza el cargo debe disminuir en la misma cantidad que la cuenta que recibe el pago, de no ser así, ninguna de las dos cuentas se modificará), si durante el transcurso de una transacción ocurriese algún error, el TPS debe poder deshacer las operaciones realizadas hasta ese instante. Si bien este tipo de integridad es que debe presentar cualquier operación de procesamiento de transacciones por lotes, es particularmente importante para el procesamiento de transacciones on-line: si, por ejemplo, un sistema de reserva de billetes de una línea aérea es utilizado simultáneamente por varios operadores, tras encontrar un asiento vacío, los datos sobre la reserva de dicho asiento deben ser bloqueados hasta que la reserva se realice, de no ser así, otro operador podría tener la impresión de que dicho asiento está libre cuando en realidad está siendo reservado en ese mismo instante. Sin las debidas precauciones, en una transacción podría ocurrir una reserva doble. Otra función de los monitores de transacciones es la detección y resolución de interbloqueos (deadlock), y cortar transacciones para recuperar el sistema en caso de fallos masivos. Características Respuesta rápida En este tipo de sistemas resulta crítico que exista un rendimiento elevado con tiempos de respuesta cortos. Una empresa no puede permitirse tener clientes esperando por una respuesta del SPT; el tiempo total transcurrido desde que se inicia la transacción hasta que se produce la salida correspondiente debe ser del orden de unos pocos segundos o menos. Fiabilidad Muchas organizaciones basan su fiabilidad en los SPT; un fallo en un SPT afectará negativamente a las operaciones o incluso parará totalmente el negocio. Para que un SPT sea efectivo, su tasa de fallos debe ser muy baja. En caso de fallo de un SPT,

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

122

debe existir algún mecanismo que permita una recuperación rápida y precisa del sistema. Esto convierte en esencial la existencia procedimientos de copia de seguridad y de recuperación ante fallos correctamente diseñados. Inflexibilidad Un SPT requiere que todas las transacciones sean procesadas exactamente de la misma forma, independientemente del usuario, el cliente o la hora del día. Si los SPT fuesen flexibles, habría entonces demasiadas posibilidades de ejecutar operaciones no estándar. Por ejemplo, una aerolínea comercial necesita aceptar de forma consistente reservas de vuelos realizadas por un gran número de agencias de viaje distintas; aceptar distintos datos de transacción de cada agencia de viajes supondría un problema. Procesamiento controlado El procesamiento en un SPT debe apoyar las operaciones de la organización. Por ejemplo, si una organización establece roles y responsabilidades para determinados empleados, el SPT debe entonces mantener y reforzar este requisito. Propiedades Atomicidad Los cambios de estado provocados por una transacción son atómicos: o bien ocurren todos o bien no ocurre ninguno. Estos cambios incluyen tanto modificaciones de la base de datos, como envío de mensajes o acciones sobre los transductores. Consistencia Una transacción es una transformación de estado correcta. Las acciones consideradas en su conjunto no violan ninguna de las restricciones de integridad asociadas al estado. Esto implica que la transacción debe ser un programa correcto. Aislamiento Incluso cuando varias transacciones se ejecuten de forma concurrente, para cada transacción T debe parecer que el resto de transacciones se han ejecutado antes o después de T, pero no antes y después. Durabilidad Una vez que una transacción ha finalizado con éxito (compromiso), cambia hacia un estado estable a prueba de fallos. Transacciones en JDBC Hay momentos en los que no desea una declaración entre en vigor a menos que otra completa. Por ejemplo, cuando el propietario de The Coffee Break actualiza la cantidad de café que se vende cada semana, el propietario también desee actualizar la cantidad total vendida hasta la fecha. Sin embargo, la cantidad vendida por semana y la cantidad total vendida debe actualizarse al mismo tiempo; de lo contrario, los datos serán inconsistentes. La manera de estar seguro de que se produzcan, ya sea ambas acciones o ninguna acción ocurre es utilizar una transacción.Una transacción es un conjunto de una o más sentencias que se ejecuta como una unidad, por lo que o bien todas las sentencias se ejecutan, o ninguna de las declaraciones se ejecuta. Desactivación del modo de confirmación automática

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

123

Cuando se crea una conexión, que está en modo auto-commit. Esto significa que cada sentencia SQL individuo es tratado como una transacción y se compromete de forma automática después de que se ejecuta. (Para ser más precisos, el valor predeterminado es para una sentencia SQL que se comete cuando se haya completado, no cuando se ejecuta. Se completa una declaración cuando todos sus conjuntos de resultados y cuentas de actualización se han recuperado. En casi todos los casos, sin embargo, se completa una declaración, y por lo tanto comprometido, justo después de que se ejecute.) La manera de permitir que dos o más declaraciones a agruparse en una transacción es desactivar el modo auto-commit. Esto se demuestra en el siguiente código, donde con una conexión activa: con.setAutoCommit (false); Uso de transacciones para Preservar la integridad de los datos Además de la agrupación de estados juntos para la ejecución como una unidad, las transacciones pueden ayudar a preservar la integridad de los datos en una tabla. Por ejemplo, imagine que un empleado tenía que ingresar los nuevos precios del café en la tabla COFFEES pero no lo hizo durante unos días. Mientras tanto, los precios subieron, y en la actualidad el propietario se encarga de introducir los precios más altos. El empleado finalmente consigue ingresar los precios ahora obsoletos, al mismo tiempo que el dueño está tratando de actualizar la tabla. Después de insertar los precios desfasados, el empleado se da cuenta de que ya no son válidos y llama al método rollback de la Connection para deshacer sus efectos. (El método rollback aborta la transacción y restaura los valores a lo que eran antes del intento de actualización.) Al mismo tiempo, el propietario está ejecutando una declaración SELECT para la impresión de los nuevos precios. En esta situación, es posible que el propietario imprimirá un precio que se había deshecho de su valor anterior, por lo que el precio impreso es incorrecto. Este tipo de situación se puede evitar mediante el uso de transacciones para proporcionar algún nivel de protección contra los conflictos que surgen cuando dos usuarios intentan acceder a los datos al mismo tiempo. Para evitar conflictos durante una transacción, un DBMS utiliza bloqueos, mecanismos para bloquear el acceso de otros a los datos que se esté accediendo a la transacción. (Tenga en cuenta que el modo de auto-commit, donde cada sentencia es una transacción, bloqueos se mantienen durante una sola declaración.) Después se establece un bloqueo, que permanece en vigor hasta que la transacción se confirma o se deshace. Por ejemplo, un DBMS podría bloquear una fila de una tabla por los cambios que se han comprometido. El efecto de este bloqueo sería la de evitar que un usuario conseguir una lectura sucia, es decir, la lectura de un valor antes de que se haga permanente. (Acceso a un valor actualizado que no se ha confirmado se considera una lectura sucia porque es posible que el valor que se revierte a su valor anterior. Si se lee un valor que luego se deshace, se ha leído un valor no válido) Cómo se establecen bloqueos está determinado por lo que se llama un nivel de aislamiento, que puede ir desde no apoyar transacciones en absoluto para apoyar transacciones que hacen cumplir las reglas de acceso muy estrictas. Un ejemplo de un nivel de aislamiento es TRANSACTION_READ_COMMITTED, que no permitirá que un valor sea accedido hasta después que se haya confirmado. En otras palabras, si el nivel de aislamiento de transacción se establece en

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

124

TRANSACTION_READ_COMMITTED , el DBMS no permite lecturas sucias que se produzcan. La interfaz Connection incluye cinco valores que representan los niveles de aislamiento de transacción que puede utilizar en JDBC:

Una lectura no repetible se produce cuando la transacción A recupera una fila, la transacción B posteriormente actualiza la fila, y la primera transacción más tarde recupera la misma fila de nuevo. Transacción A recupera la misma fila dos veces, pero ve datos diferentes. Una lectura fantasma se produce cuando la transacción A recupera un conjunto de filas que satisfacen una condición dada, la transacción B posteriormente inserta o actualiza una fila de tal manera que la fila ahora cumple la condición en la transacción A, y la primera transacción más tarde repite la recuperación condicional. Transacción A ahora ve una fila adicional. Esta fila se conoce como un fantasma. Por lo general, usted no tiene que hacer nada sobre el nivel de aislamiento de transacción; sólo puede utilizar el valor predeterminado para su DBMS. El nivel de aislamiento de transacción por defecto depende de su DBMS. Por ejemplo, para Java DB, TRANSACTION_READ_COMMITTED . JDBC permite averiguar cuál es el nivel de aislamiento de transacción de su DBMS (utilizando el método getTransactionIsolation de Connection) y también le permite establecerlo a otro nivel (usando el método setTransactionIsolation de Connection). Nota: Un controlador JDBC no admite todos los niveles de aislamiento de transacción. Si un conductor no soporta el nivel de aislamiento especificado en una invocación de setTransactionIsolation , el conductor puede sustituir un nivel de aislamiento más restrictivo superior. Si un conductor no puede sustituir a un nivel de transacción superior, lanza una SQLException. Utilice el método DatabaseMetaData.supportsTransactionIsolationLevel para determinar si el controlador es compatible con un determinado nivel. Ajuste y Recuperando los Puntos de salvaguarda El método Connection.setSavepoint, establece un objeto Savepoint dentro de la transacción actual. El método Connection.rollback está sobrecargado para tomar un argumento Savepoint. Liberar Puntos de salvaguarda El método Connection.releaseSavepoint toma un objeto Savepoint como parámetro y lo elimina de la transacción actual. Después que un punto de rescate ha sido puesto en libertad, y se trata de hacer referencia a ella en una operación de reversión puede causar que se lance una

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

125

SQLException. Cualquier punto de salvaguarda que se han creado en una transacción se liberan automáticamente y dejan de ser válidas cuando se confirma la transacción, o cuando la transacción se devuelve. Rodar una transacción a un punto de salvaguarda se desconecta automáticamente y hace inválido a cualquier otro punto de rescate que se crearon tras el punto en cuestión. Al llamar al método rollback Como se mencionó anteriormente, la llamada al método rollback termina una transacción y devuelve los valores que se han modificado a sus valores anteriores. Si usted está tratando de ejecutar una o más declaraciones en una transacción y obtiene una SQLException, llame al método rollback para poner fin a la operación y comenzar la operación de nuevo. Esa es la única manera de saber lo que se ha cometido y lo que no se ha cometido. La captura de un SQLException te dice que algo está mal, pero no le dice lo que fue o no fue cometido. Porque no se puede contar con el hecho de que nada se haya cometido, una llamada al método rollback es la única manera de estar seguro. El método CoffeesTable.updateCoffeeSales demuestra una transacción e incluye una catch bloque que invoca el método rollback . Si la aplicación continúa y utiliza los resultados de la transacción, esta llamada a la rollback método en la catch bloque impide el uso de datos posiblemente incorrectos.

3.2.3 Aplicación Ajax y Transacción Recuperar el proyecto anterior. Pasos a seguir: 1. Crear la clase ClienteDTO, BoletaDTO,DeatalleBoletaDTO dentro del paquete beans, según la siguiente imagen:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

126

Clase DetalleBoletaDTO

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

127

Clase ClienteDTO

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

128

Clase BoletaDTO

2. Crear la interface ClienteDAO, BoletaDAO dentro del paquete interfaces, según la siguiente imagen:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

129

ClienteDAO

BoletaDAO

Actualizar la interface ProductoDAO

3. Registrar el DAO BoletaDAO y ClienteDAO dentro de la clase DAOFactory.

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

130

4. Actualizar la clase MySqlDAOFactory, según la siguiente imagen:

5. Actualizar la clase MySqlProductoDAO en el método buscarProducto, según la siguiente imagen:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

6.

131

Programar en la clase MySqlClienteDAO en el método buscarCliente según la siguiente imagen:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

132

7. Programar en la clase MySqlBoletaDAO en el método registrarBoleta, según la siguiente imagen:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

133

8. Crear la clase ClienteService dentro del paquete services, según la siguiente imagen:

9. Actualizar la clase ProductoService, según la siguiente imagen:

10. Crear la clase BoletaService dentro del paquete services, según la siguiente imagen:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

134

11. Crear el servlet ServletCliente dentro del paquete misServlets y escribir las siguientes instrucciones:

12.

Actualizar el servlet ServletProducto, según la siguiente imagen:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

135

13. Crear la página: registrarBoleta.jsp y escribir las siguientes instrucciones: Boleta function addProducto(){ document.getElementById("tipo").value ='ingresa'; document.getElementById("frmBoleta").action = 'ServletBoleta'; document.getElementById("frmBoleta").submit(); } function addBoleta(){ document.getElementById("tipo").value ='registra'; document.getElementById("frmBoleta").action = 'ServletBoleta'; document.getElementById("frmBoleta").submit(); } function verCliente(){ document.getElementById("fondo").style.display ='block'; document.getElementById("divCliente").style.display ='block'; } function verProducto(){ document.getElementById("fondo").style.display ='block'; document.getElementById("divProducto").style.display ='block'; } function ocultaCliente(){ document.getElementById("fondo").style.display ='none'; document.getElementById("divCliente").style.display ='none'; } function ocultaProducto(){ document.getElementById("fondo").style.display ='none'; document.getElementById("divProducto").style.display ='none'; } .black_overlay { display: none; position: absolute; top: 0%; left: 0%; width: 100%; height: 100%; background-color: aqua; z-index: 1001; -moz-opacity: 0.8; opacity: .80; filter: alpha(opacity = 80); } .white_content { display: none; position: absolute; top: 25%; left: 25%; width: 50%; height: 50%; padding: 16px;

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

136

border: 2px solid orange; background-color: white; z-index: 1002; overflow: auto; } Boleta de Venta Datos del Cliente Código: Apellidos y Nombres: Seleccione Producto Código: Descripcion: Precio: Cantidad   

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

137

Buscar Cliente Apellidos y Nombres: Buscar Producto Descripcion:

14. Al ejecutar la página registroBoleta.jsp se mostrará la siguiente imagen:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

138

15. Abrir el archivo jquey.functions.js y escribir las siguientes instrucciones:

16. Crear las páginas: buscarCliente.jsp y escribir las siguientes instrucciones: Insert title here ID Apellidos y Nombres Sexo DNI Direccion Distrito

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

139

${f.codigo} ${f.apellido} ${f.nombre} ${f.sexo} ${f.dni} ${f.direccion} ${f.nomDistrito}

17. Crear las páginas: buscarProducto.jsp y escribir las siguientes instrucciones: Insert title here ID Descripcion Precio Stock Marca ${f.codigo} ${f.descripcion} ${f.precio} ${f.stock} ${f.nomMarca}

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

140

18. Al ejecutar la página registroBoleta.jsp se mostrará la siguiente imagen:

Al hacer clic se mostrará una ventana para buscar el cliente por el campo apellido

Al hacer clic se mostrará una ventana para buscar el producto por su descripción.

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

141

19. Crear el servlet : ServletBoleta y escribir las siguientes instrucciones: package misServlets; import java.io.IOException; public class ServletBoleta extends HttpServlet { BoletaService serviBoleta=new BoletaService(); private static final long serialVersionUID = 1L; public ServletBoleta() { super(); } protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String tipo=request.getParameter("tipo"); if(tipo.equals("verCliente")) verCliente(request,response); else if(tipo.equals("verProducto")) verProducto(request,response); else if(tipo.equals("ingresa")) ingresa(request, response); else if(tipo.equals("elimina")) eliminar(request, response); else if(tipo.equals("registra")) registra(request, response); } private void registra(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(); //Boleta que esta en sesion ArrayList boleta =(ArrayList) session.getAttribute("boleta"); //Cliente que esta en sesion String cliente[]= (String[])session.getAttribute("datoCliente"); int codCliente = Integer.parseInt(cliente[0]); //Creamos la Boleta EmpleadoDTO codEmpleado=(EmpleadoDTO) session.getAttribute("datos"); BoletaDTO b = new BoletaDTO(); b.setCodEmpleado(codEmpleado.getCodigo()); b.setCodCiente(codCliente); //Creamos el detalle ArrayList detalles = new ArrayList(); for (ProductoDTO x : boleta) { DetalleBoletaDTO det = new DetalleBoletaDTO(0, x.getCodigo(), x.getStock(), x.getPrecio()); detalles.add(det); } serviBoleta.registrarBoleta(b, detalles); //limpiamos la sesion session.removeAttribute("boleta"); session.removeAttribute("datoCliente"); session.removeAttribute("datoProducto"); //reenvio request.getRequestDispatcher("registrarBoleta.jsp"). forward(request, response); }

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

142

private void eliminar(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id"); int codi = Integer.parseInt(id); HttpSession session = request.getSession(); ArrayList boleta = (ArrayList) session.getAttribute("boleta"); for (int i = 0; i < boleta.size(); i++) { if(boleta.get(i).getCodigo() == codi){ boleta.remove(i); break; } } //la lista se agrega a sesion session.setAttribute("boleta", boleta); //reenvio request.getRequestDispatcher("registrarBoleta.jsp"). forward(request, response); } private void ingresa(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String cod = request.getParameter("txt_cod_pro"); String des = request.getParameter("txt_des_pro"); String can= request.getParameter("txt_can_pro"); String pre= request.getParameter("txt_pre_pro"); int codi = Integer.parseInt(cod.trim()); int cant = Integer.parseInt(can.trim()); double prec = Double.parseDouble(pre.trim()); ArrayList boleta ; //Se verifica si existe en sesion HttpSession session = request.getSession(); if(session.getAttribute("boleta") == null){ boleta = new ArrayList(); }else{ 20. Modificar la pagina: registrarBoleta.jsp y escribir las siguientes instrucciones: boleta = (ArrayList) session.getAttribute("boleta"); } //Se crear el objeto ProductoDTO p = new ProductoDTO(); p.setCodigo(codi);p.setDescripcion(des); p.setPrecio(prec); p.setStock(cant); boolean noExiste = true; //se verifica los repetidos for (int i = 0; i < boleta.size(); i++) { if(boleta.get(i).getCodigo() == codi){ boleta.set(i, p); noExiste = false; break; } } //Si no existe se agrega if(noExiste){ boleta.add(p); } //la lista se agrega a sesion session.setAttribute("boleta", boleta); request.getRequestDispatcher("registrarBoleta.jsp"). forward(request, response); }

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

143

private void verProducto(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String codigo = request.getParameter("codigo"); String des = request.getParameter("des"); String pre = request.getParameter("pre"); String producto[]=new String[3]; producto[0]=codigo;producto[1]=des;producto[2]=pre; HttpSession session = request.getSession(); session.setAttribute("datoProducto", producto); request.getRequestDispatcher("registrarBoleta.jsp"). forward(request, response); } private void verCliente(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String codigo = request.getParameter("codigo"); String datos = request.getParameter("datos"); String cliente[]=new String[2]; cliente[0]=codigo;cliente[1]=datos; HttpSession session = request.getSession(); session.setAttribute("datoCliente", cliente); request.getRequestDispatcher("registrarBoleta.jsp"). forward(request, response); } }

21. Actualizar la página: registrarBoleta.jsp y escribir las siguientes instrucciones:

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

144

22. Ejecutar la página index.jsp y se mostrará lo siguiente:

23. Se mostrará la página con los tres menús, luego clic en Boleta.

24. Se mostrará la página registrarBoleta.jsp, como se muestra a continuación:

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

145

25. Clic en el botón (…) que se encuentra cerca de la caja de Apellidos y Nombres, se mostrará lo siguiente:

26. Clic en el botón (…) que se encuentra cerca de la caja de Cantidad, se mostrará lo siguiente:

Ingresar una cantidad, luego clic en el botón agregar

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

146

27. Luego de realizar la venta de los productos para registrar la venta, clic en el botón Registrar y en las tablas: tb_boleta y tb_boleta_has_producto se realizó el registro, como se muestra a continuación: Tabla: tb_boleta

Tabla: tb_boleta_has_producto

3.3 Listeners 3.3.1 Tipos En aplicación web los eventos son nuevos, a partir en la especificación Servlet 2.3. Ellos le dan mayor grado de control sobre su aplicación web. En este capítulo, se va a estudiar la aplicación de dos importantes eventos:  Inicio y apagado de una aplicación  La creación y la invalidación de sesiones Como sus nombres indican, la aplicación de inicio de evento se produce cuando su aplicación web se carga por primera vez y comenzó por el contenedor de Servlets; y solicitud de cierre se produce cuando la aplicación web se cierra. El período de sesiones se produce en la creación de una nueva sesión cada vez que se crea en el servidor y de manera similar el período de sesiones se origina con la invalidación de una sesión cada vez que se anula. Para hacer uso de estas aplicaciones web y eventos para hacer algo útil, tendrá que crear y hacer uso de "clases oyentes". De aquí en adelante, vamos a implementar clases oyentes y cómo se pueden utilizar. Clases oyentes Estos son simples clases Java que implementan una de las dos siguientes interfaz: - javax.servlet.ServletContextListener

CARRERA DE COMPUTACIÓN E INFORMÁTICA

CIBERTEC

LENGUAJE DE PROGRAMACIÓN II

147

- javax.servlet.http.HttpSessionListener La implementación de ServletContextListener permite escuchar la creación o destrucción del contexto. La implementación de HttpSessionListener le permite escuchar la creación de una sesión. Veamos cuáles son los diferentes métodos de esta interfaz, que se tendrán que aplicar. ServletContextListener: Esta interfaz contiene dos métodos:  

public void contextInitialized (ServletContextEvent SCE); //Creación de un Contexo. public void contextDestroyed (ServletContextEvent SCE); //Destrucción de un contexto.

Un ejemplo de esa clase es el siguiente:

import javax.servlet.ServletContextListener; import javax.servlet.ServletContextEvent; public class ApplicationWatch implements ServletContextListener ( public static applicationInitialized long = 0L; / * Aplicación de inicio del evento * / public void contextInitialized (ServletContextEvent ce) ( applicationInitialized = System.currentTimeMillis (); ) / * Aplicación del evento de apagado * / public void contextDestroyed (ServletContextEvent ce) () ) En el código anterior, una clase Java ApplicationWatch implementa ServletContextListener. Al implementar sus dos métodos realmente sólo usa uno de ellos y el segundo método sigue teniendo el cuerpo vacío. En esta categoría, se observa en el momento de la solicitud de inicio en public static que puede ser llamado desde otra aplicación para saber qué clase fue la última vez que esta solicitud se inició. Se explicará cómo decirle al servidor de aplicaciones que tienen esta clase de oyente; además, se quiere que se les diga la aplicación de estos acontecimientos en un momento, pero primero vamos a ver cuáles son los diferentes métodos de HttpSessionListener interfaz. HttpSessionListener Esta interfaz te permite poder escuchar al crear o destruir una sesión.  

public void sessionCreated (HttpSessionEvent se); public void sessionDestroyed (HttpSessionEvent se);

CIBERTEC

CARRERA DE COMPUTACIÓN E INFORMÁTICA

LENGUAJE DE PROGRAMACIÓN II

148

Al igual que lo que hicimos en el caso de ApplicationWatch anterior, tendrá que crear una clase Java y aplicar HttpSessionListener interfaz. Un ejemplo de esa clase es el siguiente: import javax.servlet.http.HttpSessionListener; import javax.servlet.http.HttpSessionEvent; public class SessionCounter implements HttpSessionListener ( private static int activeSessions = 0; / * Creación de eventos de sesión * / public void sessionCreated (HttpSessionEvent se) ( activeSessions + +; ) / * Sesión de invalidación del evento * / public void sessionDestroyed (HttpSessionEvent se) ( if (activeSessions> 0) activeSessions -; ) public static int getActiveSessions () ( activeSessions retorno; ) ) En el código anterior, SessionCounter clase implementa HttpSessionListener para contar el número de sesiones activas. Se ha aprendido cuáles son los eventos de aplicaciones web, interfaz de lo que está disponible para nosotros y también se han visto ejemplos de la aplicación de la interfaz de las clases. Veamos cómo decirle al servidor de aplicaciones acerca de estas clases oyentes. Registro de las clases oyentes en el web.xml Eso es lo que hacemos poniendo classpath de estas clases en / WEB-INF/web.xml archivo con etiquetas especiales . Un ejemplo de este tipo de archivo web.xml es el siguiente:
View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF