Está en la página 1de 164

Desarrollo de Aplicaciones Web I

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

NDICE
Presentacin Red de contenidos Unidad de aprendizaje 1: Modelo Vista Controlador Patrn MVC
1.1 Tema 1

Pgina

5 6

: Fundamentos de Struts 2

9 9 13 29 51 63

1.1.1. : Arquitectura y Configuracin de aplicaciones 1.1.2. : La clase Action 1.1.3. : Libreras de etiquetas de Struts 2 1.1.4. : Internacionalizacin I18N 1.2 Tema 2

: Acceso optimizado a base de datos y otras caractersticas Struts 2

1.2.1. : Uso de un pool de conexiones para acceso a la fuente

63

de datos
1.2.2. : Librera de Etiquetas de Struts 2 Principales

72

componentes
1.2.3. : Patrn Composite View Struts 2 Tiles

87

Unidad de aprendizaje 2: Persistencia de datos Framework IBATIS


2.1 Tema 3

: Introduccin a IBATIS

101 101 110

2.1.1. : IBATIS Introduccin 2.1.2. : Operaciones bsicas de acceso a base de datos con

IBATIS
2.2 Tema 4

: Otras operaciones con IBATIS

119 119 128

2.2.1. : Otras operaciones y caractersticas de IBATIS 2.2.2. : Tpicos avanzados de IBATIS e Integracin con

Struts 2

Unidad de aprendizaje 3: Reportes en Sistemas empresariales


3.1 Tema 5

: Reportes con JasperReport

139

CIBERTEC

CARRERAS PROFESIONALES

3.1.1. : Diseo e implementacin de reportes con la

141

herramienta Ireport
3.2 Tema 6

: Struts 2 y JasperReport

142 142 157 167 172

3.2.1. : Integracin de Struts 2 y JasperReport

Anexo 1 Anexo 2 Anexo 3

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

PRESENTACIN
Desarrollo de Aplicaciones Web I pertenece a la lnea de Programacin y Desarrollo de Aplicaciones. Es un curso de especialidad slo en la carrera de Computacin e Informtica. Permite al estudiante concretizar proyectos informticos web, aplicando conocimientos previos aprendidos en diferentes cursos y poniendo en prctica la teora adquirida. De esta manera, consolida conocimientos de diversos cursos de especialidad. Es prctico y desarrollado en laboratorio. Se implementarn soluciones web que utilizarn los Frameworks Struts 2 e IBATIS en forma combinada.

El manual para el curso ha sido diseado 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. Por ltimo, encontrar las actividades que deber desarrollar en cada sesin, que le permitirn reforzar lo aprendido en la clase.

El curso es eminentemente prctico y se desarrolla ntegramente en laboratorio. En primer lugar, se inicia con el reconocimiento de los principales patrones de arquitectura de software, destacndose el patrn Model View Controller (MVC). Luego, contina con la presentacin del Framework MVC Struts 2. Se profundiza en sus principales caractersticas y componentes. Despus, se desarrollan conceptos de persistencia de datos utilizando para ello el Framework IBATIS. Por ltimo, se concluye con la elaboracin de reportes empresariales, utilizando la herramienta IReport, el lenguaje jasperReport e integrndolos a aplicaciones web creadas con Struts 2.

CIBERTEC

CARRERAS PROFESIONALES

RED DE CONTENIDOS

Desarrollo de Aplicaciones Web 1

Modelo Vista Controlador Patrn MVC

Persistencia de datos Framework IBATIS

Reportes en sistemas empresariales

Fundame ntos de Struts 2

Otras Caractersticas Struts 2

Introduccin a IBATIS

Otras operaciones IBATIS

Tema 5 JasperReport

Tema 6 Struts 2 y Jasper

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

UNIDAD DE APRENDIZAJE

MODELO VISTA CONTROLADOR PATRN MVC


LOGRO DE LA UNIDAD DE APRENDIZAJE
Al finalizar la unidad, el alumno, utilizando el framework MVC STRUTS 2, implementa una aplicacin web que contenga, en su estructura, el componente Action, las principales etiquetas del framework y acceso a base de datos a travs de un pool de conexiones. Al finalizar la unidad, el alumno se integra a un equipo de trabajo que refleja en su estructura los roles de un equipo de proyecto de desarrollo de software.

TEMARIO 1.1 Tema 1 : Fundamentos de Struts 2 1.1.1. : Arquitectura y Configuracin de aplicaciones 1.1.2. : La clase Action 1.1.3. : Libreras de etiquetas de Struts 2 1.1.4. : Internacionalizacin I18N

1.2 Tema 2 : Acceso optimizado a base de datos y otras caractersticas de Struts 2 1.2.1. : Uso de un Pool de conexiones para acceso a la fuente de datos 1.2.2. : Librera de Etiquetas de Struts 2 Principales componentes. 1.2.3. : Patrn Composite View Struts 2 Tiles

ACTIVIDADES PROPUESTAS
Los alumnos implementan una aplicacin web bsica, utilizando las principales caractersticas del framework MVC Struts 2.

CIBERTEC

CARRERAS PROFESIONALES

1.1 Fundamentos de Struts 2


Struts 2 es un framework que implementa el patrn de arquitectura MVC en Java. ste organiza de manera independiente las capas: Model (Objetos del Modelo del Negocio), View (interfaz con el usuario u otro sistema) y la capa Controller (controlador del flujo de la aplicacin. Se muestra, a continuacin, el esquema bsico de funcionamiento de esta arquitectura. La capa Model en Struts 2 inicia con los componentes Action. Debajo de stos, se tendrn diversos componentes: Services (Lgica pura de negocio) DAOs (objetos de persistencia de datos), entre otros. Se muestra, a continuacin, el esquema bsico de la arquitectura MVC implementado por el framework Struts 2.

Figura 1.1

Una caracterstica tpica de la capa View de Struts 2 es el uso de unos componentes especiales denominados Results. stos normalmente son representados por una pgina JSP; sin embargo, puede constituir, tambin, flujos de bytes, objetos del framework Tiles, etc.

1.1.1. Arquitectura y configuracin de aplicaciones


La arquitectura MVC funciona en Struts 2 bsicamente de la siguiente manera: a travs de un navegador se genera una solicitud. sta es capturada por la capa Controller (implementada por el componente FilterDispathcher representado por un nico filtro especializado). Este filtro analizar la solicitud y verificar si el componente invocado se

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

encuentra registrado en el archivo de configuracin XML de Struts 2. ste tiene por defecto el nombre struts.xml. El componente invocado, normalmente un Action de Struts 2, instanciar y/o utilizar diversos objetos de negocio para concretar la tarea solicitada. Segn el resultado que retorne el componente Action, la capa Controller derivar la respuesta generada a un objeto Result (normalmente una pgina JSP).

1.1.1.1. Ejercicio 1: Aplicacin web bsica de Struts 2 Se probar una aplicacin web con los componentes mnimos para el correcto funcionamiento del framework Struts 2. a) Paso 1: mportar el archivo struts2-blank-2.1.8.1.war Al descargar el framework struts2 ,se tendr acceso a una aplicacin web de prueba, que cuenta con las caractersticas mnimas para que pueda ser ejecutada. Esta aplicacin viene empaquetada dentro del archivo struts2-blank-2.1.8.1.war. Luego, de importarla, se visualizar un proyecto web, tal como se muestra a continuacin:

Notas:

CIBERTEC

CARRERAS PROFESIONALES

10

1) El principal archivo de configuracin del Framework es el archivo struts.xml. En l, se registrarn sus principales componentes. Se inicia esta sesin con el registro de la clase Action. 2) Puede observar las libreras mnimas con las que todo proyecto basado en Struts 2 debera contar. Dentro de ellas, destaca el archivo struts2-core-2.1.8.1.jar.

b) Paso 2: Revisar el archivo web.xml

<?xml version="1.0" encoding="UTF-8"?> <web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>Struts Blank</display-name> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> </web-app>

Notas: 1) Note el registro del filtro controlador del framework Struts 2. Este componente atrapar todas las solicitudes (request) generadas desde un cliente, dado que tiene como alias /*.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

11

c) Paso 3: Ejecutar la aplicacin

d) Paso 4: Excelente!, ha culminado el proceso de probar exitosamente la aplicacin web struts2-blank-2.1.8.1

CIBERTEC

CARRERAS PROFESIONALES

12

1.1.2. La clase Action


Un action es, en Struts 2, el primer componente de la capa Model dentro de la arquitectura MVC. Un actions realiza bsicamente tres pasos dentro de una aplicacin web. En primer lugar, recibe las solicitudes (request) enviadas por un cliente y realiza el trabajo inicial para atenderla. Es el componente que interacta con la capa controladora y la capa view. En segundo lugar, acta como un transportador natural de datos entre el objeto request y los componentes de la capa view, esto gracias a las caractersticas de transferencia automtica de datos que tiene struts 2 entre estos. Finalmente, apoya al framework determinando qu result ser retornado en la respuesta que se genere a la solicitud realizada.

Se detalla, a continuacin, un ejercicio, en el cual se apreciarn los principales componentes de la arquitectura MVC utilizando Struts 2.

1.1.2.1. Ejercicio 1: Funcionalidad de Logueo Versin 1 Se simular la funcionalidad de logueo con los componentes bsicos del framework Struts 2 y sin acceso a base de datos.

a) Paso 1: Copiar las principales libreras y archivos configuracin al proyecto web funcionalidadLogueov1_Inicial

de

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

13

Notas: 1) Observe que solo se puede copiar el archivo struts.xml dentro de la carpeta src, utilizando la vista Navigator. 2) Distinga las principales libreras y archivos de configuracin en las ubicaciones correctas: libreras en la carpeta lib y archivo de configuracin struts.xml en la carpeta src junto a los archivos fuente.

b) Paso 2: Registrar el filtro controlador de Struts 2 dentro del archivo web.xml


<!-- registramos el filtro controlador de struts 2 --> <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

c) Paso 3: Crear el primer componente Struts 2 de la aplicacin, la clase LogueoAction

Notas: 1) Agregue el paquete aprendamos.java.action y, dentro de l, genere la clase LogueoAction. La clase LogueoAction debe contar con la siguiente lgica:

CIBERTEC

CARRERAS PROFESIONALES

14

package aprendamos.java.action; public class LogueoAction { private String usuario; private String clave;

public String getUsuario() { return usuario; } public void setUsuario(String usuario) { this.usuario = usuario; } public String getClave() { return clave; } public void setClave(String clave) { this.clave = clave; } public String execute(){ String vista="exito"; return vista; } }

d) Paso 4: Registrar la clase LogueoAction en el archivo struts.xml 1

<package name="default" namespace="/" extends="struts-default">

<action name="logueo" class="aprendamos.java.action.LogueoAction" > <result name="error" <result name="exito" </action> </package> >/logueo.jsp </result> >/bienvenida.jsp </result>

Notas: 1) El alias de la clase action es logueo; por lo tanto, debe modificar el archivo logueo.jsp. Ya no invocar a la clase LogueoServlet sino a LogueoAction.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

15

e) Paso 5: Ejecutar la aplicacin web 1

Notas: 1) Se puede observar en el url que el alias invocado es logueo. Recuerde que en Struts 2 todas las solicitudes son atrapadas por el filtro controlador del framework. ste invocar al action respectivo sobre la base del registro realizado en el archivo struts.xml. f) Paso 6: Bien!, ha culminado la funcionalidad de logueo

versin 1

1.1.2.2. Ejercicio 2: Funcionalidad de Logueo Versin 2 Se efecta la funcionalidad de logueo con los componentes bsicos del framework e implementando los patrones de diseo DAO (Data Access Object), Service y Business Delegate.

a) Paso 1: Modificar la clase MySqlClienteDAO y verificar su correcta relacin con las clases que implementan el patrn de diseo DAO.

CIBERTEC

CARRERAS PROFESIONALES

16

Dentro de la clase MySqlClienteDAO, debe modificar el mtodo buscaPorUsuario. Complete el cdigo con la lgica mostrada a continuacin:
//ejecutamos ResultSet rs=pst.executeQuery(); //si hay datos, recuperamos un regsitro if(rs.next()){ objClienteDTO = new ClienteDTO(); objClienteDTO.setUsuario(rs.getString(1)); objClienteDTO.setClave(rs.getString(2)); objClienteDTO.setNombre(rs.getString(3)); objClienteDTO.setSueldo(rs.getDouble(4)); objClienteDTO.setSexo(rs.getString(5)); objClienteDTO.setFecnac(rs.getDate(6)); } cn.close();

El patrn de diseo DAO (Data Access Object) permite que un componente pueda acceder a diferentes orgenes de datos de manera independiente y transparente. En este proyecto, se cuentan con componentes DAO para acceder al motor de base de datos MySql. Adicionalmente, se podran contar con DAOs para acceder a otros orgenes de datos, tales como Oracle, Microsoft SQL Server, archivos XML, etc.

Por cada entidad dentro del modelo de datos, se debe crear un componente DAO.

Verifique si existe la interface ClienteDAO. sta debe ser implementada por la clase MySqlClienteDAO:
public interface ClienteDAO {

public int registraCliente(ClienteDTO objCliente) throws Exception; public ClienteDTO buscaPorUsuario(String usuario) throws Exception; . . . }

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

17

Una interface permite exponer al mundo las operaciones de la clase que la implementa. Verifique si MySqlClienteDAO es retornado por la fbrica de DAOs para MySql:

public class MySqlDAOFactory extends DAOFactory { // Esta es una fabrica que crea DAOs especificos para Mysql

@Override public ClienteDAO getClienteDAO() { // TODO Auto-generated method stub return new MySqlClienteDAO(); }

Verifique si la clase MySqlClienteDAO ha sido registrada en la fbrica de fbricas DAOFactory:

public abstract class DAOFactory { public public public public public static static static static static final final final final final int int int int int MYSQL = 1; ORACLE = 2; DB2 = 3; SQLSERVER = 4; XML = 5;

1
// Existir un mtodo por cada DAO que pueda ser creado. // Ejemplo: //public abstract ArticuloDAO getArticuloDAO(); // registramos nuestros daos public abstract ClienteDAO getClienteDAO(); //public abstract ProductoDAO getProductoDAO();

public static DAOFactory getDAOFactory(int whichFactory){ switch(whichFactory){ case MYSQL: return new MySqlDAOFactory(); case XML: return new XmlDAOFactory(); case ORACLE: return new OracleDAOFactory();

CIBERTEC

CARRERAS PROFESIONALES

18

Notas: 1) El registro de la clase MySqlClienteDAO es la creacin de un mtodo abstracto en la clase DAOFactory que retorna a la interface que implementa MySqlClienteDAO.

b) Paso 2: Crear la clase LogueoService y la interface LogueoService_I

2
public class LogueoService implements LogueoService_I { // Referenciamos a la fabrica de daos para mysql DAOFactory fabrica = DAOFactory.getDAOFactory(DAOFactory.MYSQL); // Referenciamos al dao de la entidad cliente ClienteDAO objClienteDAO = fabrica.getClienteDAO();

public ClienteDTO validaUsuario(ClienteDTO cliente) throws Exception { // aqui podriamos tener mas logica return objClienteDAO.buscaPorUsuario(cliente.getUsuario()); } }

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

19

Notas: 1) Agregue el paquete aprendamos.java.action y dentro de l genere la clase LogueoAction. 2) Un servicio es un componente, que pertenece a la capa Model del patrn de diseo MVC. Representa, en la programacin, el inicio de la lgica de negocio. Por cada caso de uso de sistema identificado en la aplicacin, se debe implementar un servicio. ste puede invocar a uno o ms DAOs.

Debe exponer las operaciones de la clase LogueoService; por lo tanto, debe crear la interface LogueoService_I

public interface LogueoService_I { public abstract ClienteDTO validaUsuario(ClienteDTO cliente) throws Exception; }

c) Paso 3: Crear la clase PaqueteBusinessDelegate

CIBERTEC

CARRERAS PROFESIONALES

20

2
public class PaqueteBusinessDelegate { private PaqueteBusinessDelegate() { // TODO Auto-generated constructor stub } public static LogueoService_I getLogueoService(){ return new LogueoService(); } // agregar aqui mas llamadas a otros servicios

Notas: 1) Dentro del paquete aprendamos.java.service, genere la clase PaqueteBusinessDelegate. 2) Por cada paquete de un modelo de anlisis, se debe tener un componente BusinessDelegate. Esta clase ser invocada por los actions y retornar componentes tipo Service.

d) Paso 4: Invocar los componentes de lgica de negocio, desde la clase LogueoService, y crear la sesin web.

Genere, dentro de la clase LogueoAction, el atributo mensaje para poder visualizar posibles mensajes de error en la capa de presentacin. No debe olvidar crear los mtodos setter y getter para el nuevo atributo.

public class LogueoAction {

private String usuario; private String clave; private String mensaje;

public String getMensaje() { return mensaje; } public void setMensaje(String mensaje) { this.mensaje = mensaje; }

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

21

Agregue la lgica que permitir validar los datos ingresados y almacenarlos en la sesin web.

public String execute(){ String vista="exito"; System.out.println("dentro de nuestro primer action"); System.out.println(this.getUsuario()); System.out.println(this.getClave()); // invocamos a nuestro servicio (logica de negocio) LogueoService_I logueoservice = PaqueteBusinessDelegate.getLogueoService();

ClienteDTO usuarioCandidato= new ClienteDTO(); usuarioCandidato.setUsuario(this.getUsuario());

ClienteDTO objUsuario=null; try { objUsuario = logueoservice.validaUsuario(usuarioCandidato); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } if(objUsuario!=null){ if(objUsuario.getClave().equals(this.getClave())){ // creamos la sesion web al estilo struts 2 Map<String,Object> lasesion= ActionContext.getContext().getSession(); lasesion.put("b_usuario", objUsuario);

}else{ vista="error"; this.setMensaje( "Lo sentimos, la clave es incorrecta"); } }else{ vista="error"; this.setMensaje("Es una pena, el usuario no existe!"); } return vista; }

CIBERTEC

CARRERAS PROFESIONALES

22

Recuerde que debe utilizar Expression Language (EL) en el JSP logueo.jsp para visualizar el mensaje de error definido en la clase LogueoAction.
<tr> <td class="error general"> <!-- podemos visualizar el mensaje de error usando EL --> ${requestScope.mensaje} </td> </tr>

Recuerde que debe utilizar Expression Language (EL) en el JSP bienvenida.jsp para visualizar los datos del cliente cargados en la sesin web.
<tr> <td class="error general"> <!-- podemos visualizar el mensaje de error usando EL --> ${requestScope.mensaje} </td> </tr>

e) Paso 5: Ejecutar la aplicacin Primero, ingrese un usuario invlido.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

23

Luego, ingrese el usuario correcto, pero la clave equivocada.

Por ltimo, ingrese los datos correctamente.

Excelente!, ha culminado la funcionalidad de logueo versin 2

CIBERTEC

CARRERAS PROFESIONALES

24

1.1.3. Libreras de etiquetas de Struts 2


1.1.3.1. Ejercicio 1: Funcionalidad de Logueo Versin 3 Agregue una nueva funcionalidad al logueo implementado, a travs del uso de archivos de recursos y nuevas caractersticas del framework Struts 2.

a) Paso 1: Definir el archivo de recursos para Struts 2 Se copia el archivo struts.properties dentro de la carpeta src del proyecto.

Se puede observar que, a travs de la key struts.custom.i18n.resources, se define la ubicacin del archivo de recursos.

struts.custom.i18n.resources=aprendamos.java.recursos.MisRecursos struts.ui.theme=simple struts.action.extension=action,,dudu

b) Paso 2: Agregar nuevas keys al archivo de recursos MisRecursos.properties Puede agregar las keys correspondientes a los mensajes de error del logueo.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

25

# Definiremos keys y sus respectivos valores # Una key es un identificador asociado a alguna descripcion #keys para el logueo : completar Pagina de Inicio - Que facil es JEE :):) logueo.titulo = logueo.mensaje.error.usuario=Lo sentimos, el usuario ingresado no existe :( logueo.mensaje.error.clave=Es una pena, la clave ingresada no

c) Paso 3: Referenciar las keys dentro de la clase LogueoAction Para poder referenciar las keys, la clase LogueoAction debe heredar de la clase ActionSupport. Esto permitir incluir funcionalidad adicional dentro de la misma.

package aprendamos.java.action; import java.util.Map; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import aprendamos.java.bean.ClienteDTO; import aprendamos.java.service.LogueoService_I; import aprendamos.java.service.PaqueteBusinessDelegate; public class LogueoAction extends ActionSupport {

private String usuario; private String clave; private String mensaje;

Invoque el mtodo getText, heredado de la clase ActionSupport.

. . . }else{ vista="error"; this.setMensaje( this.getText( "logueo.mensaje.error.clave")); } }else{ vista="error"; this.setMensaje(this.getText("logueo.mensaje.error.usuario")) ; } . . .

CIBERTEC

CARRERAS PROFESIONALES

26

d) Paso 4: Modificar el JSP logueo.jsp Debe referenciar a la librera de etiquetas de struts 2.

<%@ taglib prefix="s" uri="/struts-tags" %>

Transforme las etiquetas html en sus equivalentes de Struts 2.

<s:form action="logueo"

method="post"

>

<table > <tr class="etiqueta" > <td colspan="2" > <img alt="El loguito" src="imagenes/logo_tiny.png" </td> </tr> <tr class="etiqueta" > <td> <fmt:message key="logueo.usuario" /> </td> <td> <s:textfield name="cliente.usuario" /> </td> </tr> <tr class="etiqueta" > <td > <fmt:message key="kclave" /> </td> <td> <s:password name="cliente.clave" /> </td> </tr> <tr> <td colspan="2" align="right" > <s:submit name="boton01" value="Ingresar" type="submit" /> </td> </tr> <tr> <td class="error general"> ${requestScope.mensaje} </td> </tr> <tr> <td > <fmt:message key="logueo.imagen" /> </td> </tr>

>

</table> </s:form>
CARRERAS PROFESIONALES CIBERTEC

DESARROLLO DE APLICACIONES WEB I

27

Note que se han modificado los nombres de los campos usuario y clave por cliente.usuario y cliente.clave. e) Paso 5: Referenciar a los campos cliente.usuario y cliente.clave dentro de la clase LogueoAction Agregue el atributo cliente en la clase LogueoAction.
public class LogueoAction extends ActionSupport {

private ClienteDTO cliente=null; public ClienteDTO getCliente() { return cliente; } public void setCliente(ClienteDTO cliente) { this.cliente = cliente; }

Modifique el mtodo execute.


public String execute(){ String vista="exito"; System.out.println("dentro de nuestro primer action"); System.out.println(this.cliente.getUsuario()); System.out.println(this.cliente.getClave());

// invocamos a nuestro servicio (logica de negocio) LogueoService_I logueoservice = PaqueteBusinessDelegate.getLogueoService();

ClienteDTO usuarioCandidato= new ClienteDTO(); usuarioCandidato.setUsuario(this.getCliente().getUsuario());

ClienteDTO objUsuario=null; try { objUsuario = logueoservice.validaUsuario(usuarioCandidato); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); Notas: } if(objUsuario!=null){

if(objUsuario.getClave().equals(this.getCliente().getClave())){
CIBERTEC CARRERAS PROFESIONALES

28

1) Los datos son obtenidos a partir del nuevo atributo cliente. 2) Se obtienen nuevamente los datos a partir del atributo cliente. Esta vez invocando al mtodo getCliente().

f)

Paso 6: Ejecutar la aplicacin

Primero, ingrese un usuario invlido.

Luego, ingrese el usuario correcto, pero la clave equivocada.

Por ltimo, ingrese los datos correctamente.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

29

g) Paso 7: Muy buen trabajo!

CIBERTEC

CARRERAS PROFESIONALES

30

1.1.3.2. Ejercicio 2: Funcionalidad Registro de cliente Se implementa la funcionalidad indicada, haciendo uso de de las utilidades incluidas en el framework para procesar archivos (en el ejemplo la imagen del cliente) a travs de un formulario HTML y gestionarlos dentro de la aplicacin web implementada. a) Paso 1: Importar el proyecto FuncionalidadRegistraImagen_Inicial.war web

Notas: 1) Note que, dentro del proyecto, cuenta con el script de base de datos FacilitoBaseDatos.sql. En l, se debe verificar que la tabla tbcliente cuenta con un tipo de dato adecuado para almacenar un archivo de cualquier modelo.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

31

b) Paso 2: Verificar que la tabla tbcliente cuente con un campo de tipo longblog

CREATE DATABASE IF NOT EXISTS facilito; USE facilito; --- Definition of table `tbcliente` -DROP TABLE IF EXISTS `tbcliente`; CREATE TABLE `tbcliente` ( `nombre` varchar(100) DEFAULT NULL, `sueldo` double DEFAULT NULL, `sexo` char(1) DEFAULT NULL, `fecnac` datetime DEFAULT NULL, `usuario` varchar(15) NOT NULL DEFAULT '', `clave` varchar(15) NOT NULL DEFAULT '', `foto` longblob DEFAULT NULL, PRIMARY KEY (`usuario`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;

Notas: 1) Observe que, en el campo foto, se almacenar la imagen asociada al cliente que registrar en su aplicacin web.

CIBERTEC

CARRERAS PROFESIONALES

32

c) Paso 3: Modificar el archivo nuevoCliente.jsp

Dentro de la pgina nuevoCliente.jsp, se debe modificar el formulario HTML. Complete el cdigo con la lgica mostrada a continuacin:
<s:form action="ingresaCliente" method="post" enctype="multipart/form-data" >

<table> <tr class="titulo" > <td colspan="2" align="center" > Registro de Clientes </td> </tr> <tr class="control" > <td> <s:text name="key.cliente.nombre" /> </td> <td> <s:textfield name="cliente.nombre" /> </td> </tr>

. . .

. . .
<tr class="control" > <td> Fotografa: </td> <td> <s:file name="cliente.foto" </tr> <tr class="control" > <td align="right" > <input type="submit" name="boton01" value="Registrar" > </td> </tr> </table> </s:form>

/>

</td>

Notas: 1) Debe utilizar el atributo enctype del formulario con el valor multipart/form-data. De esta manera,se habilita el formulario para soportar campos tipo File. 2) Agregue la etiqueta file de Struts 2., cuyo nombre es cliente.foto, es decir, har referencia a un objeto de nombre cliente que cuente con un atributo llamado foto.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

33

d) Paso 4: Registrar el alias ingresaCliente en el archivo struts.xml

<action name="ingresaCliente" class="aprendamos.java.action.ClienteAction" method="registra" > <result name="exito" </action> >/listado.jsp</result>

Notas: 1) El alias ingresaCliente fue definido en el formulario de la pgina nuevoCliente.jsp. Note que al invocar este alias se ejecutar dentro de la clase ClienteAction el mtodo registrar.

e) Paso 5: Crear el mtodo registrar en la clase ClienteAction

La clase ClienteAction debe contar con la siguiente lgica:

package aprendamos.java.action; import java.util.List; import aprendamos.java.bean.ClienteDTO; import aprendamos.java.service.ClienteService_I; import aprendamos.java.service.PaqueteBusinessDelegate; public class ClienteAction { // creamos un atributo de tipo Lista de Clientes ClienteDTO cliente; List<ClienteDTO> clientes;

...

CIBERTEC

CARRERAS PROFESIONALES

34

...
ClienteService_I servicioCliente = PaqueteBusinessDelegate.getClienteService();

// creamos el metodo registra public String registra(){ String vista="exito"; try { servicioCliente.registraElCliente(cliente); // lo retornado por el servicio lo asignamos al atributo de tipo Lista de clientes cliente.setNombre(""); clientes= servicioCliente. listaClientesPorNombre(cliente.getNombre()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return vista; }

3 4

Notas: 1) Se ha definido la variable cliente de tipo ClienteDTO. De manera automtica, el Framework instancia el objeto y almacena en l los datos que llegan desde la pgina nuevoCliente.jsp. Note que en la pgina nuevoCliente.jsp todos los campos llevan como prefijo en el nombre la palabra cliente, la cual hace referencia a la variable definida en ClienteAction. 2) El objeto servicioCliente es un componente de la lgica de negocio y expone las operaciones que puede realizar la clase ClienteAction. 3) Note que el mtodo registraCliente recibe como parmetro el objeto cliente. Dentro de l, deben existir los campos necesarios para poder gestionar la imagen del cliente seleccionada en la pgina nuevoCliente.jsp 4) Una vez registrado el nuevo cliente se blanquea el atributo nombre del objeto cliente y se invoca la funcionalidad de listado antes de retornar a la vista respectiva.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

35

f)

Paso 6: Modificar la clase ClienteDTO

La clase ClienteDTO debe contar con la siguiente lgica:


public class ClienteDTO implements Serializable {

private static final long serialVersionUID = 1L; private private private private private private String nombre; Date fecnac; String sexo; double sueldo; String usuario; String clave;

1 2

private File foto; private String fotoContentType; private String fotoFileName; private InputStream isFoto; public String getFotoContentType() { return fotoContentType; } public void setFotoContentType(String fotoContentType) { this.fotoContentType = fotoContentType; }

. . .

Notas: 1) Dado que en la pgina nuevoCliente.jsp se ha definido un campo tipo file con el nombre cliente.foto, es necesario definirlo en la clase ClienteDTO, de modo que se pueda recepcionar la imagen enviada desde el formulario. 2) Es necesario, tambin, por requerimiento del Framework, definir los campos fotoContentType y fotoFileName. Ambos se cargarn de manera automtica y proporcionarn importante informacin relacionada con la variable foto. Adicionalmente, se define la variable isFoto de tipo InputStream, debido a que sta ser utilizada por el componente MySqlClienteDAO en el registro de la imagen en la tabla tbcliente.

CIBERTEC

CARRERAS PROFESIONALES

36

g) Paso 7: Modificar la clase ClienteService La clase ClienteService debe contar con la siguiente lgica en el mtodo registraElCliente:

public int registraElCliente(ClienteDTO objCliente) throws Exception { // aqui agremos un poco de logica // como sabemos que el atributo isFoto esta llegando nulo // lo generamos a partir del atributo foto (de tipo File) if(objCliente.getFoto()!=null){ InputStream tempo = new FileInputStream(objCliente.getFoto()); objCliente.setIsFoto(tempo); } return objClienteDAO.registraCliente(objCliente); }

Notas:

1) Si el cliente seleccion en la pgina nuevoCliente.jsp una imagen, el atributo foto debe ser diferente del valor null. De ser el caso, se crea un objeto temporal de tipo InputStream en base al atributo foto. Luego, se asigna el objeto tempo al atributo isFoto (utilizado en la clase MySqlClienteDAO para grabar la imagen en la tabla tbcliente).

Recuerde que el mtodo registraElCliente debe ser expuesto registrndolo en la interface ClienteService_I. La clase ClienteService implementa la interface ClienteService_I.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

37

h) Paso 8: Modificar la clase MySqlClienteDAO La clase MySqlClienteDAO debe implementar la siguiente lgica en el mtodo registraCliente:

public int registraCliente(ClienteDTO objCliente) throws Exception{ int resultado =0; Connection cn = MySqlDBConn.obtenerConexion(); String sql = "insert into tbcliente(nombre,sueldo,sexo,fecnac," + "usuario,clave,foto) values (?,?,?,?,?,?,?)"; PreparedStatement pst = cn.prepareStatement(sql); // asignamos valores a las interrogantes pst.setString(1, objCliente.getNombre()); pst.setDouble(2, objCliente.getSueldo()); pst.setString(3, objCliente.getSexo()); // no olvidemos insertar la fecha :) java.sql.Date bdfecha= new java.sql.Date(objCliente.getFecnac().getTime()); pst.setDate(4, bdfecha); pst.setString(5, objCliente.getUsuario()); pst.setString(6, objCliente.getClave()); pst.setBinaryStream(7, null,0); if(objCliente.getFoto()!=null){ pst.setBinaryStream(7, objCliente.getIsFoto(), objCliente.getIsFoto().available()); }

// ejecutamos la sentencia resultado = pst.executeUpdate(); cn.close(); return resultado; }

Notas: 1) Recuerde que para insertar una fecha en base de datos debe convertir las fechas de tipo java.util.Date al tipo java.sql.Date.

2) Por defecto, se asume que no insertar ninguna imagen en el campo foto:

CIBERTEC

CARRERAS PROFESIONALES

38

pst.setBinaryStream(7, null,0); Sin embargo, si el valor del atributo es diferente de null, registra la imagen, tomando como base al atributo de tipo InputStream isFoto: pst.setBinaryStream(7, objCliente.getIsFoto(), objCliente.getIsFoto().available());

El mtodo available() de un objeto de tipo InputStream retorna la cantidad de bytes (el tamao), en este caso, de la imagen a insertar en la tabla. De esta manera, se enva como tercer parmetro del mtodo setBinaryStream().

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

39

i)

Paso 9: Ejecutar la aplicacin web

Seleccione del listado de Clientes el enlace Nuevo Cliente:

CIBERTEC

CARRERAS PROFESIONALES

40

En la pantalla mostrada, ingrese los campos solicitados.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

41

Al hacer clic sobre el botn Registrar, se grabar un nuevo registro en la base de datos y se visualizar nuevamente el listado de Clientes.

CIBERTEC

CARRERAS PROFESIONALES

42

Se puede verificar el correcto registro de la imagen, utilizando la herramienta MySql Query Browser:

Notas: 1) Al hacer clic sobre la lupa, visualizar en una nueva ventana la imagen registrada en la tabla tbcliente.

j)

Paso 10: Bien!, ha culminado la funcionalidad registra imagen exitosamente.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

43

1.1.4. Internacionalizacin I18n


Tradicionalmente, los desarrolladores de software se centran en construir aplicaciones que resuelvan en forma inmediata problemas de negocio. Mientras hacen eso es fcil y a veces necesario realizar asunciones acerca del lenguaje o lugar de residencia de los usuarios. En muchos casos, estas asunciones son vlidas y no hay preguntas sobre quin ser la audiencia. Sin embargo, es probable, alguna vez, que se deba reconstruir una aplicacin, porque estas asunciones fueron incorrectas. Internacionalizacin (I18N) es el proceso de disear su software con soporte en tiempo real de mltiples lenguajes y regiones. Dada esta caracterstica, no ser necesario redisear nuestras aplicaciones cada vez que se necesite soporte para un nuevo lenguaje. Una aplicacin que dice tener soporte para internacionalizacin debe contar con las siguientes caractersticas: Puede soportar lenguajes adicionales sin requerir cambios adicionales de cdigo. Los elementos de texto, mensajes e imgenes son almacenados externamente al cdigo fuente. Dependencia culturales de datos, tales como fecha y hora, y valores decimales son correctamente formateados para el lenguaje del usuario y localizacin geogrfica. Caracteres no estndares son soportados. La aplicacin puede ser fcilmente adaptada a nuevos lenguajes y regiones.

Cuando se internacionaliza una aplicacin, no se puede producirla para elegir qu opciones desea soportar. Se deben implementar todas ellas o el proceso colapsar. Si un usuario visita un sitio web y todos sus textos, imgenes y botones estn en el lenguaje correcto, pero los nmeros y fechas no son formateados correctamente, sta ser una experiencia desagradable para el usuario. Asegurar que una aplicacin puede soportar mltiples lenguajes y regiones solo es el primer paso. Se deben crear versiones localizadas de la aplicacin para cada lenguaje especfico y regin que debe soportar. Afortunadamente, aqu es donde los beneficios de I18N en la plataforma java se ejecutan. Para aplicaciones que estn siendo apropiadamente internacionalizadas, todo el trabajo para soportar nuevos lenguajes o naciones, son externas al cdigo fuente. Una clase locale es una regin (usualmente geogrfica, pero no necesariamente) que comparte personalizaciones, cultura y lenguaje. Aplicaciones que son escritas para una sola localizacin son comnmente referenciadas como miopes. Localizacin (L10N) es el proceso de adaptar su aplicacin, la cual ha sido internacionalizada apropiadamente con la especfica. Para aplicaciones donde el soporte I18N no ha sido planeado o incorporado, esto usualmente significa cambios de texto, imgenes y mensajes que son incluidos dentro

CIBERTEC

CARRERAS PROFESIONALES

44

del cdigo fuente. Despus de los cambios aplicados, ste debe de ser recopilado. Imagine hacer eso cada vez para una nueva localizacin soportada. De acuerdo con Richard Gillam, miembro del Grupo de Tecnologa Unicote (autor del diseo de muchas de las libreras Java para soporte I18N), los usuarios esperarn que los productos que utilizan trabajen para ellos en su lenguaje nativo. Se pueden obtener experiencias negativas si los usuarios no estn satisfechos cuando las asunciones que se realizan son incorrectas. Se debe iniciar planificando, en forma temprana, el soporte para I18N en las aplicaciones.

1.1.4.1. Ejercicio 1: Funcionalidad Registra imagen con i18N Se agregar nueva funcionalidad al registro de imgenes implementado. La aplicacin web soportar el uso de tres idiomas distintos.

a) Paso 1: Importar el proyecto FuncionalidadRegistraImagenI18N_Inicial.war

web

Notas: 1) Note que, dentro del proyecto, cuenta con el paquete aprendamos.java.recursos y dentro de l cuenta con tres archivos de recursos (archivos .properties) que soportan los

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

45

idiomas italiano (it), portugus (pt) y espaol. El primero est configurado en el archivo sin indicador de idioma. Note que los prefijos it y pt o cualquier otro que se desea usar deben ser cdigos ISO 639-1.

b) Paso 2: Editar los archivos .properties. Se crearn, como ejemplos, las keys que sern utilizadas en la pgina bienvenida.jsp.

Defina las keys para el idioma portugus en el archivo MisRecursos_pt.properties

#keys para la pagina de bienvenida key.usuario = Usurio: key.nombre = Nome: key.fecnac = data de nascimento: key.sexo = sexo: key.saludo = Bem-vindo Caro usurio, seus dados so:

#keys para el menu menu.bienvenida = Ir pgina inicial menu.logueo = V para a entrada menu.listado = Ir para a lista

CIBERTEC

CARRERAS PROFESIONALES

46

Defina las keys para el idioma italiano en el archivo MisRecursos_it.properties

#keys para la pagina de bienvenida key.usuario = Utente: key.nombre = Nome: key.fecnac = Data di Nascito: key.sexo = sesso: key.saludo = Benvenuto Caro utente, i dati sono:

#keys para el menu menu.bienvenida = Vai alla pagina di benvenuto menu.logueo = Ir al logueini menu.listado = Ir al listadini

Defina las keys para el idioma espaol en el archivo MisRecursos.properties (archivo de recursos por defecto).

#keys para la pagina de bienvenida key.usuario = Usuario: key.nombre = Nombre: key.fecnac = Fecha de Nacimiento: key.sexo = Sexo: key.saludo= Bienvenido estimado usuario, sus datos son:

#keys para el menu menu.bienvenida = Ir a la pgina de Bienvenida menu.logueo = Ir al logueo menu.listado = Ir al listado

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

47

Notas: 1) El archivo de recursos por defecto es aquel que no tiene cdigo ISO asociado a un idioma en particular. Cuando se seleccione en la aplicacin web un idioma que no haya sido configurado en ningn archivo de recursos, automticamente, struts 2 recupera las keys del archivo de recursos por defecto.

c) Paso 3: Modificar el archivo cabecera.jsp

<body class="titulo" > <img alt="" src="imagenes/logo.png" border="0" > <table> <tr><td> <a href="${pageContext.request.contextPath}/a_bienvenida?request_loc ale=it"> <img src="imagenes/banderaItalia.png" alt="Italiana" border="0"> </a> </td> <td><a href="${pageContext.request.contextPath}/a_bienvenida?request_loc ale=pt"> <img src="imagenes/BanderaBrasil.png" alt="Portugues" border="0"> </a> 2 </td> <td><a href="${pageContext.request.contextPath}/a_bienvenida?request_loc ale=es"> <img src="imagenes/banderaPeru.png" alt="Espaol" border="0"> </a> </td> </tr> </table> </body>

Notas: 1) Struts 2 soporta cuenta con un parmetro especial llamado request_locale. Cuando se utiliza ste, de manera automtica, se configura sul valor como el idioma actual de la aplicacin web. 2) Es recomendable utilizar variables al referenciar cualquier recurso dentro de una aplicacin web. En el ejemplo, en

CIBERTEC

CARRERAS PROFESIONALES

48

lugar de colocar el nombre de la aplicacin web, se realiza lo siguiente: FuncionalidadRegistraImagenI18N_Inicial Se coloca un expression language equivalente:

${pageContext.request.contextPath}

d) Paso 4: Registrar el action a_bienvenida en el archivo struts.xml

. . . <package name="default" namespace="/" extends="strutsdefault">


1

<action name="a_bienvenida" > <result > /bienvenida.jsp </result> </action> <action name="a_logueo" > <result > /logueo.jsp </action> . . .
Notas: 1 </result>

1) Note que el action a_bienvenida es solo un action de atajo que invoca automticamente a la pgina bienvenida.jsp. Se puede crear dentro de la aplicacin mltiples actions de atajo para invocar a travs de links a las pginas JSP.

e) Paso 5: Recuperar las keys del men y de la pgina de bienvenida, utilizando la etiqueta <s:text> de struts 2.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

49

Modifique el archivo menu.jsp

. . . <tr> <td class="control" > <s:a action="a_bienvenida"

>
1

<s:text name="menu.bienvenida" /> </s:a> </td> </tr> <tr> <td class="control" > <s:a action="a_logueo"

>

<s:text name="menu.logueo" /> </s:a> </td> </tr> <tr> <td class="control" > <s:a action="a_listado" > <s:text name="menu.listado" /> </s:a> </td> </tr> . . .

Notas: 1) Debe usar la etiqueta <s:text> para referenciar a las keys del archivo de recursos. Es importante recordar que para utilizar las etiquetas de struts 2 se debe referenciar la librera, utilizando la siguiente directiva: <%@ taglib prefix="s" uri="/struts-tags" %>

CIBERTEC

CARRERAS PROFESIONALES

50

Modifique el archivo bienvenida.jsp

. . .

<table class="control" > <tr> <td colspan="2" > <s:text name="key.saludo" /> </td> </tr> <!-recuperamos los atributos del usuario logueado utilizando EL (Expression Language) --> 1 <tr> <td><s:text name="key.usuario" /> </td> <td>${sessionScope.b_usuario.usuario}</td> </tr> <tr> <td> <s:text name="key.nombre" /> </td> <td>${sessionScope.b_usuario.nombre}</td> </tr> <tr> <td> <s:text name="key.fecnac" /> </td> <td>${sessionScope.b_usuario.fecnac}</td> </tr> <tr> <td> <s:text name="key.sexo" /> </td> <td>${sessionScope.b_usuario.sexo}</td> </tr> </table> . . .

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

51

f)

Paso 6: Ejecutar la aplicacin web

Ingrese a la intranet a travs de la pgina de logueo.

Se debe visualizar la pantalla de bienvenida y los enlaces a los idiomas definidos en la pgina cabecera.jsp. Seleccione la bandera italiana.

CIBERTEC

CARRERAS PROFESIONALES

52

Visualizar la siguiente pantalla con el men y la bienvenida en idioma italiano. Seleccione la bandera de Brasil.

Se visualizar la siguiente pantalla con el men y la bienvenida en idioma portugus. Finalmente, seleccione la bandera del Per.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

53

Se visualizar la siguiente pantalla con el men y la bienvenida en idioma castellano.

g) Paso 7: Bien!, ha culminado la funcionalidad registra imagen con I18n exitosamente.

CIBERTEC

CARRERAS PROFESIONALES

54

1.2 Acceso optimizado a base de datos y otras caractersticas Struts 2

1.2.1. Uso de un Pool de conexiones para acceso a base de datos


Un Pool de Conexiones (jdbc) es un conjunto de conexiones preinstanciadas que sern "prestadas" a los threads (hilos) de ejecucin a medida que estos lo requieran para que la usen y luego la devuelvan al pool. En el caso de las aplicaciones abiertas en Internet o con gran cantidad de usuarios potenciales, el anlisis es el mismo. El recurso es la conexin a la base de datos. Se tendr un conjunto de n conexiones para asignarlas (o prestarlas) a los hilos que lo requieran. Lo recomendable al usar un Pool de Conexiones es que se optimice las consultas a la base de datos para tener mayor rapidez.

1.2.1.1. Ejercicio 1: Funcionalidad Registra Imagen Pool Se implementa la funcionalidad indicada haciendo uso de un pool de conexiones de MySql para optimizar el acceso a base de datos.

a) Paso 1: Importar el proyecto FuncionalidadRegistraImagenPool_Inicial.war

web

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

55

Notas: 1) Observe que, dentro del proyecto, cuenta en la carpeta META-INF con el archivo context.xml. En l, se debe crear la configuracin del pool de conexiones que utilizar para acceder a una base de datos.

CIBERTEC

CARRERAS PROFESIONALES

56

b) Paso 2: Editar el archivo context.xml y configurar el pool de conexiones.

<?xml version="1.0" encoding="UTF-8"?> <!-- Este es un comentario --> <!-- la etiqueta Context representa una zona de memoria que se crea cuando levantamos la aplicacion web. Esta zona de memoria estara "viva" mientras no reiniciemos la aplicacion web -->

<Context path="/jee-web"

>

<!-- registramos un recurso en esta zona de memoria. En este caso un pool de conexiones --> <Resource name="jdbc/sisepuede" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="root" password="" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/facilito"/>

1 2

</Context>

Notas: 1) jdbc/sisepuede es el nombre del pool de conexiones que utilizar para referenciar a la base de datos. 2) El nmero mximo de conexiones activas es 100 en el ejemplo. Este valor debe ser calculado para cada aplicacin web sobre la base de la experiencia y el trfico que normalmente se soporte. En algunos casos, se tendr la necesidad de incrementar o redecir este valor por defecto. 3) El mximo tiempo de espera, 10000, est expresado en milisegundos. En este ejemplo, se esperar, como mximo, 10 segundos para obtener una conexin disponible (de las 100 existentes). De no conseguirla, se producira un error.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

57

c) Paso 3: Modificar el archivo MySqlDbConn.java

package aprendamos.java.util; // Esta clase nos retornara una conexion a base de datos import java.sql.*; import javax.naming.*; import javax.sql.*; public class MySqlDBConn { // Utilizaremos mas bien un pool de conexiones // creamos el metodo que nos permite obtener una conexion . . .

1 2

Notas: 3) Debe importar el paquete javax.naming.*, ya que en l se encuentran las clases para utilizar JNDI y acceder al pool de conexiones. 4) Debe importar el pauete javax.sql.* debido a que dentro de l se encuentra la clase DataSource. sta representa un pool de conexiones en java.

CIBERTEC

CARRERAS PROFESIONALES

58

. . .
public static Connection obtenerConexion(){ // 1. Para referenciar al pool creamos un contexto JNDI // Java Naming and Directory Interface Connection cn=null; try { // creamos el contexto JNDI Inicial, JDNI valida los nombres , utiliza la infor de META INF para hacer un pool de conexiones., JNDI maneja nombres y objetos Context ctx = new InitialContext(); // ahora vamos a ubicar un nombre dentro // de este contexto, para ello usamos el // famoso metodo lookup. //Base standar JND String raizContexto ="java:comp/env/"; // obtenemos a traves de su nombre a nuestro // pool de conexiones DataSource ds= (DataSource)ctx.lookup(raizContexto+"jdbc/sisepuede"); // le pedimos al pool que nos de una conexion cn = ds.getConnection(); System.out.println( "Mision cumplida, hemos obtenido la conexion del pool");

} catch (NamingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return cn; }

Notas: 1) El nombre del contexto JNDI por default es java:comp/env. Todas las denominaciones de objetos JNDI (como nuestro pool), se crean debajo de este nombre raz. Por lo tanto, para referenciar al pool, se pasar primero por el nombre raz. 2) A travs del mtodo lookup y utilizando el nombre raz del contexto, se referencia al pool de conexiones: jdbc/sisepuede.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

59

Se obtiene un objeto de tipo DataSource que representa el pool almacenado en memoria.

d) Paso 4: Copiar el conector de mysql dentro de la carpeta lib del servidor de aplicaciones TomCat

Notas: 1) Este paso es necesario debido a que es el servidor Tomcat y no la aplicacin web, quien solicita al servidor de base de datos las conexiones (en el ejemplo cien), que sern almacenadas en la memoria del servidor y que juntas constituyen el pool de conexiones.

CIBERTEC

CARRERAS PROFESIONALES

60

e) Paso 5: Ejecutar la aplicacin web

Ingrese a la intranet a travs de la pgina de logueo.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

61

Debe visualizar la pantalla de bienvenida con los datos del usuario logueado.

Tambin, se visualizar en la consola de Eclipse los mensajes del Logueo y el que se coloc en la clase MySqlDbConn: misin cumplida, se ha obtenido la conexin del pool.

CIBERTEC

CARRERAS PROFESIONALES

62

f)

Paso 6: Bien!, ha culminado la funcionalidad registra imagen pool exitosamente.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

63

1.2.2. Libreras de etiquetas de Struts 2. Principales componentes


Dentro de la familia de nuevas etiquetas de Struts 2, es importante destacar que, en esta versin, todas las etiquetas bsicas del framework se encuentran en una sola librera, la cual es referenciada en un JSP de la siguiente manera: <%@ taglib prefix="s" uri="/struts-tags" %> Se detalla, a continuacin, ejercicios de aplicacin en los que se utilizan las principales etiquetas de Interface de usuario y datos de Struts 2: <s:url> <s:action> <s:form>

1.2.2.1. Ejercicio 2: Funcionalidad carga datos del Cliente Se implementa la funcionalidad indicada haciendo uso de las utilidades incluidas en el Framework para procesar archivos (en el ejemplo la imagen del cliente) a travs de un formulario HTML y el uso de un Action de Struts 2 que utiliza un nuevo tipo de Result: stream.

a) Paso 1: Importar el proyecto proyecto web FuncionalidadCargaDatosCliente_Inicial.war

CIBERTEC

CARRERAS PROFESIONALES

64

Notas: 1) Debe modificar la pgina listado.jsp para agregar un enlace que permita visualizar los datos de un cliente en particular.

b) Paso 2: Modificar el archivo listado.jsp Dentro de la pgina listado.jsp, debe crear un nuevo enlace para visualizar los datos del cliente seleccionado. Complete el cdigo con la lgica mostrada a continuacin:

. . .
<td align="center" > <s:url id="carga" action="cargaModificaCliente" > <s:param name="usuario" > ${elcli.usuario} </s:param> </s:url> <a </td> href="${carga}" > M </a>

. . .

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

65

Notas: 1) Utilizando la etiqueta <s:url > defina un enlace que permitir invocar al alias cargaModificaCliente. Adicionalmente, determine el parmetro usuario utilizando la etiqueta <s:param>. Su valor es asignado usando el siguiente expression language (EL): ${elcli.usuario}

2) Culminado el cambio en listado.jsp, visualizar el enlace, tal como se muestra en la pantalla previa.

CIBERTEC

CARRERAS PROFESIONALES

66

c) Paso 3: Registrar el alias cargaModificaCliente en el archivo struts.xml

<action name="cargaModificaCliente" class="aprendamos.java.action.ClienteAction" method="cargaModifica" > <result name="exito" >/modificaCliente.jsp </result> </action>

Notas: 1) El alias cargaModificaCliente fue referenciado en el enlace definido para modificar (M) de la pgina listado.jsp. Note que al invocar este alias se ejecutar dentro de la clase ClienteAction el mtodo cargaModifica.

d) Paso 4: Crear el mtodo cargaModifica en la clase ClienteAction

La clase ClienteAction debe contar con la siguiente lgica:

package aprendamos.java.action; import java.util.List; import aprendamos.java.bean.ClienteDTO; import aprendamos.java.service.ClienteService_I; import aprendamos.java.service.PaqueteBusinessDelegate; public class ClienteAction { // creamos un atributo de tipo Lista de Clientes ClienteDTO cliente; List<ClienteDTO> clientes; String usuario;

...

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

67

...
public String cargaModifica(){ String vista="exito"; try { cliente= servicioCliente.buscaClientePorUsuario( this.getUsuario());

} catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }

return vista; }

...

Notas: 1) Se ha definido la variable usuario de tipo String. Se definen tambin los mtodos setUsuario() y getUsuario(), respectivamente. De manera automtica, el Framework instancia el objeto y almacena en ste el parmetro usuario, que llega desde la pgina listado.jsp. . 2) Note que el mtodo buscaClientePorUsuario recibe como parmetro la variable usuario y retorna un objeto de tipo ClienteDTO que es asignada a la variable cliente. 3) Luego, se retorna a la vista respectiva, es decir, se invocar a la pgina modificaCliente.jsp

CIBERTEC

CARRERAS PROFESIONALES

68

e) Paso 5: Verificar la clase MySqlClienteDAO La clase MySqlClienteDAO debe implementar la siguiente lgica en el mtodo buscaPorUsuario:

public ClienteDTO buscaPorUsuario(String usuario) throws Exception{ ClienteDTO objClienteDTO=null; Connection cn = MySqlDBConn.obtenerConexion(); //definimos la sentencia String sql="select usuario,clave,nombre,sueldo,sexo,fecnac,foto " + " " + "from tbcliente where usuario = ?"; //la preparamos PreparedStatement pst=cn.prepareStatement(sql); //asignamos valores a las interrogantes pst.setString(1,usuario);

//ejecutamos ResultSet rs=pst.executeQuery(); //si hay datos, recuperamos un regsitro if(rs.next()){ objClienteDTO = new ClienteDTO(); objClienteDTO.setUsuario(rs.getString(1)); objClienteDTO.setClave(rs.getString(2)); objClienteDTO.setNombre(rs.getString(3)); objClienteDTO.setSueldo(rs.getDouble(4)); objClienteDTO.setSexo(rs.getString(5)); objClienteDTO.setFecnac(rs.getDate(6)); objClienteDTO.setIsFoto(rs.getBinaryStream(7)); } cn.close(); return objClienteDTO; }

Notas: 1) Note que se obtiene el campo de tipo longblob foto. 2) El campo foto es asignado al atributo isFoto del objeto objClienteDTO. Este atributo es de tipo InputStream, por ello, debe ser recuperado con el mtodo getBinaryStream del objeto ResultSet rs: rs.getBinaryStream(7)

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

69

f)

Paso 6: Ejecutar la aplicacin web

Seleccione del listado de Clientes el enlace M asociado a cualquiera de los clientes listados:

Notas: 1) Enlace para visualizar los datos del cliente y, opcionalmente, modificarlos.

CIBERTEC

CARRERAS PROFESIONALES

70

En la pantalla mostrada, se visualizarn los datos asociados al cliente seleccionado. Sin embargo, no reconoce an la fotografa.

g) Paso 7: Bien!, ha culminado la primera parte de la funcionalidad carga imagen

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

71

h) Paso 8: Modificar la pgina modificaCliente.jsp

Dentro de la pgina modificaCliente.jsp debe utilizar la etiqueta HTML <img> para visualizar la fotografa asociada al cliente mostrado:

. . .
<tr class="control" > <td> Fotografa: </td> <td> <s:file name="cliente.foto" /> <td> <img alt="Fotografia del Cliente:) " </td>

src="cargaImagenCliente?usuario=${cliente.usuario}" /> </td> </tr>

. . .

Notas: 1) Note cmo en el atributo src de la etiqueta <img> se hace referencia al alias cargaImagenCliente. Se enva adicionalmente el parmetro usuario con el valor ${cliente.usuario}.

CIBERTEC

CARRERAS PROFESIONALES

72

i)

Paso 9: Registrar el alias cargaImagenCliente en el archivo struts.xml

<action name="cargaImagenCliente" class="aprendamos.java.action.ImagenAction" method="recuperaImagenCliente" > <result name="exito" type="stream" > <!-- en inputName colocamos el nombre del atributo del action que permitira generar el flujo (stream) --> <param name="inputName">imagenClienteRecuperada</param> </result> </action>

Notas: 1) El alias cargaImagenCliente fue referenciado en la etiqueta <img> de la pgina modificaCliente.jsp. Note que al invocarlo se ejecutar dentro de la clase ImagenAction el mtodo recuperaImagenCliente. 2) Se utiliza un nuevo tipo de result: stream. A travs de l, la etiqueta <img> de la pgina modificaCliente.jsp visualizar la imagen a partir de un campo de tipo InputStream.

3) El campo imagenClienteRecuperada es el valor asociado al parmetro del result: inputName. ste debe ser de tipo InputStream y estar definido en el action ImagenAction.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

73

j)

Paso 10: Crear el mtodo recuperaImagenCliente en la clase ImagenAction

La clase ImagenAction debe contar con la siguiente lgica:

package aprendamos.java.action; import java.io.*; import aprendamos.java.bean.ClienteDTO; import aprendamos.java.service.ClienteService_I; import aprendamos.java.service.PaqueteBusinessDelegate; public class ImagenAction { String usuario; InputStream imagenClienteRecuperada;

...

...
public String recuperaImagenCliente(){ String vista="exito"; try { ClienteDTO cli= servicioCliente.buscaClientePorUsuario(usuario); // del objeto cli solo nos importa la foto como InputStream // recuperamos ese atributo y lo asignamos al campo // imagenClienteRecuperada this.imagenClienteRecuperada = cli.getIsFoto(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return vista; }

...

CIBERTEC

CARRERAS PROFESIONALES

74

Notas: 1) Se ha definido la variable imagenClienteRecuperada de tipo InputStream. sta es referenciada en el archivo struts.xml, en el registro del action ImagenAction. 2) El mtodo buscaClientePorUsuario retorna un objeto de tipo ClienteDTO que es asignado a la variable cli. 3) Se invoca el mtodo getIsFoto() de la variable cli para obtener la imagen recuperada de base de datos y asignarla a la imagenClienteRecuperada.

k) Paso 11: Ejecutar la aplicacin web Seleccione, nuevamente, del listado de Clientes el enlace M asociado a cualquiera de los clientes listados:

Notas: 1) Enlace para visualizar los datos del cliente y, opcionalmente, modificarlos.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

75

En la pantalla mostrada, se visualizarn los datos asociados al cliente seleccionado. En esta oportunidad, s visualizar la fotografa asociada al cliente.

l)

Paso 12: Muy Bien!, ha culminado exitosamente la funcionalidad completa carga imagen.

CIBERTEC

CARRERAS PROFESIONALES

76

1.2.3. Patrn Composite View Struts 2 Tiles


Al momento de crear el diseo de un sitio web tpico, ste puede sufrir muchos cambios durante su ciclo de vida. Utilizar diseos y gestores de diseo puede ayudar a organizar las diferentes partes de un JSP de modo que stos se puedan alterar con un mnimo impacto para el resto de la aplicacin. Surge, de esta manera, el patrn de diseo Composite View, el cual permite, de manera eficiente y escalable, gestionar diversos diseos para un sitio web. Desafortunadamente, la tecnologa JSP no proporciona ningn soporte directo para diseos o gestores de diseo, es por ello que surgen libreras en el mercado que pueden ser utilizadas para mejorar la estructura de nuestras aplicaciones web. Se muestra, a continuacin, a travs de un ejercicio, la configuracin y uso de la librera Tiles. sta es de cdigo abierto e implementa el patrn Composite View.

1.2.3.1. Ejercicio 1: Mantenimiento Completo con Tiles Sobre un mantenimiento completo e implementado con Struts 2, se harn las modificaciones necesarias para implementar el patrn Composite View. Para ello, se utilizar el framework Tiles y se integrar a la aplicacin web construida sobre Struts 2.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

77

a) Paso 1: Importar el proyecto web MantenimientoTiles_Inicial.war

Notas: 1) En general, las pginas JSP de la aplicacin se encontrarn dentro de carpetas especficas. En este ejemplo, se cuenta con dos tipos: Pginas. Para todas aquellas de la aplicacin web.

CIBERTEC

CARRERAS PROFESIONALES

78

Plantillas. Para las diferentes plantillas tiles sobre las cuales se distribuirn las pginas de la aplicacin web.

2) Para utilizar Tiles e integrarlo a struts 2, es necesario contar con las libreras de Tiles y el plug in de Struts 2 para sta. 3) El archivo de configuracin de tiles es tiles.xml y debe copiarse por defecto en la carpeta WEB-INF de la aplicacin web. 4) No todos los archivos JSP deben, necesariamente, estar dentro de una carpeta. En el ejemplo, la pgina logueo.jsp mantiene su ubicacin original: dentro de la carpeta WebContent.

b) Paso 2: Modificar el archivo web.xml Se deben agregar en el archivo web.xml las siguientes etiquetas:

<!-- registramos e l listener de strtus 2 titles --> <listener> <listener-class> org.apache.struts2.tiles.StrutsTilesListener </listener-class> </listener> ...

Notas: 1) Debe agregar el listener de Tiles para struts 2.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

79

c) Paso 3: Modificar el archivo struts.xml

<?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.0//EN" "http://tiles.apache.org/dtds/tiles-config_2_0.dtd"> <tiles-definitions> <definition name="d_bienvenida" template="/plantillas/diseno01.jsp"> <put-attribute <put-attribute <put-attribute <put-attribute
1 name="menu" value="/paginas/menu.jsp" /> name="pie" value="/paginas/pie.jsp" /> name="cabecera" value="/paginas/cabecera.jsp" /> name="body" value="/paginas/bienvenida.jsp" />

</definition> <definition name="d_listado" extends="d_bienvenida"> <put-attribute name="body" value="/paginas/listado.jsp" /> </definition> <definition name="d_nuevoCliente" extends="d_bienvenida"> <put-attribute name="body" value="/paginas/nuevoCliente.jsp" /> </definition> ...
3 2

Notas: 1) Debe crear definiciones de Tiles. sta determina qu componentes (JSPs normalmente) se despliegan sobre una plantilla en particular. En el ejemplo, el definition d_bienvenida referencia a la plantilla diseno01.jsp, 2) Un definition puede ser heredado. De esta manera, solo es necesario sobre escribir los puts que queramos modificar. En el ejemplo, el definition d_listado hereda del definition d_bienvenida. 3) Note que los puts dentro de los definitions estn referenciando a pginas JSP dentro de la carpeta pginas. sta debe existir y ah deben encontrarse las pginas referenciadas.

CIBERTEC

CARRERAS PROFESIONALES

80

d) Paso 4: Modificar el archivo struts.xml

... <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="false" /> <package name="default" namespace="/" extends="tiles-default"> <!-- creamos un action de atajo --> <action name="a_nuevoCliente" > <result type="tiles"> d_nuevoCliente </action> <action name="a_bienvenida" > <result type="tiles"> d_bienvenida </action> <action name="a_logueo" > <result > /logueo.jsp </action>
1

</result>
2

</result>
3

</result>

<action name="a_listado" > <result type="tiles"> d_listado </action>

</result>

<!-- registramos nuestro primer action --> <action name="logueo" class="aprendamos.java.action.LogueoAction" > <result name="error" >/logueo.jsp </result> <result name="exito" type="tiles"> d_bienvenida </action> ...

</result>

Notas: 1) Para trabajar con Tiles y struts 2, es obligatorio heredar del paquete tiles-default. 2) Cada <result> de un action, ya no invoca directamente a una pgina JSP, sino, ms bien, a un definition de tiles. 3) Para que un <result> pueda invocar a un definition de tiles es necesario indicar en su atributo type el valor tiles.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

81

e) Paso 5: Crear el archivo diseno01.jsp

Notas: 1) El archivo debe ser creado tal como se referenci en el archivo tiles.xml, es decir, dentro de una carpeta llada plantillas.

CIBERTEC

CARRERAS PROFESIONALES

82

f)

Paso 6: Modificar el archivo diseno01.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="tiles" uri="http://tiles.apache.org/tags-tiles"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 1 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-88591"> <title>Insert title here</title> </head> <body> <!-- en esta plantilla definimos el orden de distribucion de los puts del definition --> <table> <tr> <td colspan="2"><tiles:insertAttribute name="cabecera" /></td> </tr> <tr> <td><tiles:insertAttribute name="menu" /></td> <td><tiles:insertAttribute name="body" /></td> </tr> <tr> <td colspan="2"><tiles:insertAttribute name="pie" /></td> </tr> </table> </body> ...

Notas: 1) Para poder utilizar las etiquetas de tiles dentro de la pgina JSP, es necesario referenciar a la librera de etiquetas tags-tiles. 2) Note cmo se ha creado una tabla con filas y columnas, dentro de las cuales, haciendo uso de la etiqueta <tiles:insertAttribute>, se insertan los diferentes puts definidos en el archivo tiles.xml.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

83

g) Paso 7: Copiar las pginas JSP dentro de la carpeta pginas

Notas: 1) Tal como se indic en el archivo tiles.xml, las pginas JSP deben estar dentro de una carpeta denominada pginas.

CIBERTEC

CARRERAS PROFESIONALES

84

h) Paso 8: Eliminar las directivas <include> de todas las pginas JSP.

<table> <tr> <td colspan="2" align="center" > <!-- aqui va la cabecera --> <jsp:include page="cabecera.jsp" </td> </tr> <tr> />
1

<td > <!-- aqui va el menu --> <jsp:include page="menu.jsp" </td> <!-- aqui va el cuerpo --> <td > ... />

Notas: 1) Dado que ahora se trabajar con Tiles, ya no es necesario tener directivas include dentro de los JSPs. Importante: De dejarlas, se duplicara la implementacin del patrn de diseo Composite View.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

85

i)

Paso 9: Ejecutar la aplicacin web

Ingrese a la intranet a travs de la pgina de logueo.

CIBERTEC

CARRERAS PROFESIONALES

86

Visualizar la pantalla de bienvenida de la aplicacin

j)

Paso 10: Bien!, ha culminado Mantenimiento con Tiles exitosamente.

la

funcionalidad

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

87

Resumen
Las etiquetas de struts 2 se encuentran agrupadas dentro de una sola librera: <%@ taglib prefix="s" uri="/struts-tags" %>

Las etiquetas de struts 2 son parte de la capa de presentacin dentro de una arquitectura MVC. Con Tiles, se puede, fcilmente, cambiar de una estructura de aplicacin a otra. A travs de ste, nicamente de plantillas, permite tener mayor flexibilidad al momento de una posible migracin.

Si desea saber ms acerca de estos temas, puede consultar las siguientes pginas: http://struts.apache.org/2.x/index.html Aqu encontrar importante documentacin oficial y ejemplos de uso del framework Struts 2 http://struts.apache.org/1.x/struts-tiles/ Aqu encontrar documentacin oficial sobre el uso de plantillas Tiles dentro de una aplicacin implementada con el framework Struts. Tambin, encontrar referencias para utilizar Tiles independientemente de Struts: Tiles 2.

CIBERTEC

CARRERAS PROFESIONALES

88

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

89

UNIDAD DE APRENDIZAJE

PERSISTENCIA DE DATOS FRAMEWORK IBATIS


LOGRO DE LA UNIDAD DE APRENDIZAJE
Al finalizar la unidad, los alumnos, utilizando el frameworks IBATIS, implementan la capa de persistencia de datos y la integran con el framework Struts 2.

TEMARIO 2.1 Tema 3 : Introduccin a IBATIS 2.1.1. 2.1.2. : IBATIS Introduccin : Operaciones bsicas de acceso a base de datos con IBATIS

2.2 Tema 4 : Otras operaciones con IBATIS 2.2.1. 2.2.2. : Otras operaciones y caractersticas de IBATIS : Tpicos avanzados de IBATIS e Integracin con Struts 2

ACTIVIDADES PROPUESTAS
Los alumnos implementan una aplicacin web bsica, utilizando las principales caractersticas del framework MVC Struts 2 y el framework IBATIS.

CIBERTEC

CARRERAS PROFESIONALES

90

2.1 Introduccin a IBATIS


2.1.1. IBATIS - Introduccin
Ibatis es un framework (marco de trabajo) de cdigo abierto basado en capas desarrollado por Apache Software Foundation, que se ocupa de la capa de Persistencia (se sita entre la lgica de Negocio y la capa de la Base de Datos). Puede ser implementado en Java y .NET (tambin existe un port para Ruby on Rails llamado RBatis). Ibatis asocia objetos de modelo (JavaBeans) con sentencias SQL o procedimientos almacenados mediante archivos XML, simplificando la utilizacin de bases de datos. Dentro de sus principales caractersticas se destacan: A. Es posible subdividir la capa de persistencia en tres subcapas: La capa de abstraccin ser la interfaz con la de la lgica de negocio, haciendo las veces de fachada (Patrn Facade) entre la aplicacin y la persistencia. Se implementa de forma general, mediante el patrn Data Access Object (DAO) y, particularmente en Ibatis, se implementa utilizando su framework DAO (ibatis-dao.jar). La capa de framework de persistencia ser el interfaz con el gestor de Base de Datos, ocupndose de la gestin de los datos mediante un API. Normalmente, en Java, se utiliza JDBC. Ibatis utiliza su framework SQL-MAP (ibatis-sqlmap.jar). La capa de driver se ocupa de la comunicacin con la propia base de datos, utilizando uno especfico para la misma.

B. Toda implementacin de Ibatis incluye los siguientes componentes: Data Mapper proporciona una forma sencilla de interaccin de datos entre los objetos Java y .NET y bases de datos relacionales. Data Access Object es una abstraccin que oculta la persistencia de objetos en la aplicacin y proporciona un API de acceso a datos al resto.

El marco de trabajo SQL Maps es muy tolerante, tanto con las malas implementaciones de los modelos de datos como con los modelos de objetos.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

91

A pesar de ello, es muy recomendable que se usen las mejores prcticas, tanto cuando se disee la base de datos (normalizacin apropiada, etc.) como el modelo de objetos. Al hacer esto, se garantizar un mejor rendimiento y un diseo ms claro.

2.1.1.1. Ejercicio 1: Funcionalidad IBATIS - Introduccin Se implementar una aplicacin web con los componentes bsicos para el correcto funcionamiento del framework IBATIS. a) Paso 1: Importar el archivo FuncionalidadIbatisIntro_Inicial.war

Notas: 1) Observe que debe contar con las libreras bsicas de IBATIS para integrar el framework a su aplicacin web.

CIBERTEC

CARRERAS PROFESIONALES

92

b) Paso 2: Copiar los archivos de configuracin y la clase UtilSqlConfig

Notas: 1) SqlMapConfig.xml es el archivo de configuracin por excelencia de IBATIS. En l, se define, por ejemplo, el pool de conexiones a utilizar y otros archivos XML (llamados SqlMaps), que sern referenciados en la aplicacin web. En el ejemplo, se muestran dos archivos SqlMaps: Cliente.xml y Producto.xml. (Por cada entidad del modelo de datos, normalmente se tendr un SqlMap).

2) UtilSqlConfig permite tener una representacin en java como objeto del archivo SqlMapConfig.xml.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

93

c) Paso 3: Modificar el archivo SqlMapConfig.xml

<sqlMapConfig> <!-- referenciamos a nuestro pool de conexiones, archivo de confiracion por excelncia de IBatis --> <transactionManager type="JDBC"> <dataSource type="JNDI"> <property name="DataSource" value="java:comp/env/nomerindo" /> </dataSource> </transactionManager> <!-- registramos nuestros SqlMaps. Normalmente por cada entidad tendremos un SqlMap, tener cuidado estos archivos como cualquierr refrerncia de xml de be existir --> <sqlMap resource="aprendamos/java/ibatis/Cliente.xml" /> <sqlMap resource="aprendamos/java/ibatis/Producto.xml"/> <!-- podemos registrar muchos mas sqlmaps --> </sqlMapConfig> ...
2

Notas: 1) A travs de la etiqueta <transactionManager>, se define, en IBATIS, el pool de conexiones, que se utilizar para acceder a un origen de datos. En el ejemplo, el pool se llama: nomerindo. 2) A travs de la etiqueta <sqlMap>, se referencia a los archivos XML, que contienen las sentencias SQL para operar sobre las entidades que referencian. En el ejemplo, se referencian los archivos XML Cliente y Producto.

CIBERTEC

CARRERAS PROFESIONALES

94

d) Paso 4: Modificar la clase UtilSqlConfig

import java.io.Reader; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; // Esta clase retorna un objeto que representa el archivo // SqlMapConfig.xml. Este es el principal archivo de // cofiguracion de ibatis //Permite representa sqlMapConfig como un objeto public class UtilSqlConfig { private static final SqlMapClient sqlMap; static { try { String resource = "aprendamos/java/ibatis/SqlMapConfig.xml"; Reader reader = Resources.getResourceAsReader(resource); //Este objeto presenta al SQLmApConfig.xml estos es lo que se trata de hacer sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException( "Error inicializando la clase UtilSqlConfig class. Cause: " + e); } } public static SqlMapClient getSqlMapInstance() { return sqlMap; } } ...

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

95

e) Paso 5: Modificar el archivo Cliente.xml

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd"> <sqlMap namespace="Cliente"> <!-- Referencia al DTO --> <typeAlias alias="cli" type="aprendamos.java.bean.ClienteDTO" /> <resultMap class="cli" id="clienteRes"
2

>

<result <result <result <result <result <result <result </resultMap>

property="nombre" column="nombre" /> property="sueldo" column="sueldo" /> property="sexo" column="sexo" /> property="fecnac" column="fecnac" /> property="usuario" column="usuario" /> property="clave" column="clave" /> property="laFoto" column="foto" />

<!-- Definimos un operacion , el dao llamara a las operaciones por su ID --> <select id="ibatis_logueo" parameterClass="java.lang.String" resultMap="clienteRes"> select usuario,clave,nombre,sueldo,sexo,fecnac,foto from tbcliente where usuario = #value#; </select> ...

Notas: 1) A travs de la etiqueta <typeAlias>, es posible crear diversos alias de clases java para ser usados dentro del archivo XML. 2) La etiqueta <resultMap> es utilizada cuando los nombres de las columnas de una tabla no coinciden con los atributos de la clase que recibir los datos de una consulta. En el ejemplo, la columna foto es mapeada al atributo laFoto. 3) A travs de la etiqueta <select>, se puede utilizar SQL estndar para realizar consultas. Los parmetros simples que llegan a la consulta son referenciados, utilizando la sintaxis #value#

CIBERTEC

CARRERAS PROFESIONALES

96

f) Paso 6: Modificar el archivo MySqlClienteDAO

public ClienteDTO buscaPorUsuario(String usuario) throws Exception{ //Metodo modificado para Ibatis ClienteDTO objClienteDTO=null; System.out.println("Validamos con ibatis"); SqlMapClient sqlMap=UtilSqlConfig.getSqlMapInstance();

objClienteDTO=(ClienteDTO)sqlMap.queryForObject("ibatis_logueo ", usuario);


2

System.out.println("busca por usuario usando Ibatis"); return objClienteDTO; } ...

Notas: 1) A travs de la clase UtilSqlConfig, se crea una instancia de la clase SqlMapClient. En el ejemplo, el objeto sqlMap es la representacin en java del archivo SqlMapConfig. 2) Se invoca al mtodo queryForObject del objeto sqlMap. Se enva como parmetros lo siguiente: El nombre de la operacin que se desea ejecutar (definida en el archivo Cliente.xml) El cdigo de usuario a travs del cual se validar el logueo.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

97

g) Paso 7: Ejecutar la aplicacin web

Ingrese a la intranet a travs de la pgina de logueo.

CIBERTEC

CARRERAS PROFESIONALES

98

Se visualizar la pantalla de bienvenida de la aplicacin.

Se visualizar en consola el mensaje generado por la clase MySqlClienteDAO

h)

Paso 8:

Bien!, ha culminado la funcionalidad

Introduccin IBATIS exitosamente.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

99

2.1.2. Operaciones bsicas de Acceso a base de datos con IBATIS


Para implementar las operaciones bsicas con IBATIS, es necesario conocer las principales etiquetas del Framework. stas se muestran a continuacin: Sentencias Atributos
id parameterClass resultClass parameterMap <statement> resultMap cacheModel xmlResultName (Java only) id parameterClass parameterMap id parameterClass parameterMap id parameterClass parameterMap id parameterClass resultClass parameterMap resultMap cacheModel

Elementos Hijos

Mtodos

insert update All dynamic elements delete All query methods

<insert>

All dynamic elements insert <selectKey> update <generate> (.NET delete only) All dynamic elements insert <generate> (.NET update only) delete All dynamic elements insert <generate> (.NET update only) delete

<update>

<delete>

<select>

All dynamic elements All query <generate> (.NET methods only)

id parameterClass resultClass <procedure> parameterMap resultMap xmlResultName (Java only)

insert update All dynamic elements delete All query methods

Se desarrollan, a continuacin, diversos ejercicios en los que se utilizarn y describirn las principales etiquetas del Framework.

CIBERTEC

CARRERAS PROFESIONALES

100

2.1.2.1. Ejercicio 1: Funcionalidad IBATIS - Mantenimiento

Se implementar una aplicacin que permita ejecutar las operaciones bsicas de un mantenimiento, utilizando el framework IBATIS. a) Paso 1: Modificar el archivo Cliente.xml

. . . <resultMap

class="cli" id="clienteRes"

>

<result <result <result <result <result <result <result

property="nombre" column="nombre" /> property="sueldo" column="sueldo" /> property="sexo" column="sexo" /> property="fecnac" column="fecnac" /> property="usuario" column="usuario" /> property="clave" column="clave" /> property="laFoto" column="foto" />

</resultMap>
1

<parameterMap class="java.util.Map" id="clienteMap" <parameter <parameter <parameter <parameter <parameter <parameter <parameter </parameterMap>

>

property="nombre" jdbcType="VARCHAR" /> property="sueldo" jdbcType="DOUBLE" /> property="sexo" jdbcType="CHAR" /> property="fecnac" jdbcType="DATETIME" /> property="usuario" jdbcType="VARCHAR" /> property="clave" jdbcType="VARCHAR" /> property="foto" jdbcType="BLOB" />

Notas: 1) Al utilizar la etiqueta <parameterMap>, se ha creado un prametro especial llamado clienteMap. ste ser enviado desde la clase DAO y estar representado por la clase java.util.Map. Note cmo se identifica cada campo de la clase Map con el tipo de dato al que se referir en la base de datos.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

101

Se crean las operaciones para insertar y listar clientes por nombre.

<select id="ibatis_clienteLista" parameterClass="java.lang.String" resultClass="cli"> <!-- Para poner wildcards aqui en value seria '%$value$%'--> select usuario,clave,nombre,sueldo,sexo,fecnac from tbcliente where nombre like #value# </select> <!-- cuando utilizamos parameterMap o resultMap nuestras sentencias pueden utilizar las interrogantes de un prepareStatement tipico --> <insert id="ibatis_insertaCliente" parameterMap="clienteMap" insert into tbcliente(nombre,sueldo,sexo,fecnac, usuario,clave,foto) values (?,?,?,?,?,?,?) </insert> ... >
1

Notas: 1) Observe cmo la operacin ibatis_insertaCliente recibe como parmetro clienteMap definido en lneas previas. Los campos son automticamente asociados a las interrogantes de la sentencia SQL.

CIBERTEC

CARRERAS PROFESIONALES

102

b) Paso 2: Modificar la clase MySqlClienteDAO Se prepara la invocacin a las operaciones IBATIS definidas en el archivo Cliente.xml.

public int registraCliente(ClienteDTO objCliente) throws Exception{ System.out.println("Insertando con ibatis :) "); int resultado =0; SqlMapClient cliente = UtilSqlConfig.getSqlMapInstance(); // En vez de enviar objCliente, enviaremos una estructura // preparada para soportar un tipo LongBloB y registrar // el cliente con IBATIS HashMap<String, Object> map = new HashMap<String, Object>(); map.put("nombre", objCliente.getNombre()); map.put("sueldo", objCliente.getSueldo()); map.put("sexo", objCliente.getSexo()); map.put("fecnac", objCliente.getFecnac()); map.put("usuario", objCliente.getUsuario()); map.put("clave", objCliente.getClave()); // intento 01: asumimos que ibatis soporta como parametro // un arreglo de bytes // Asumimos que esta llegando la foto InputStream is = objCliente.getIsFoto(); byte[] losbytes = new byte[is.available()]; // a partir del inputStream cargamos el arreglo los bytes is.read(losbytes); map.put("foto", losbytes); cliente.insert("ibatis_insertaCliente",map); System.out.println("registro exitoso con IBATIS :) "); return resultado; } ...
Notas: 1) A partir del campo isFoto (de tipo InputStream), se prepara un arreglo de bytes, el cual se carga en el objeto map con el nombre foto. 2) Se invoca a la sentencia insert de IBATIS, pasndole como parmetros el nombre de la operacin a ejecutar y el objeto map. 2 1

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

103

public List<ClienteDTO> listaPorNombre(String vnombre) throws Exception{ ArrayList<ClienteDTO> clientes= new ArrayList<ClienteDTO>(); /** Para manejar transacciones usar las clasese de Ibatis de sqlMapClient**/ System.out.println("Validamos con ibatis"); SqlMapClient sqlMap=UtilSqlConfig.getSqlMapInstance(); clientes=(ArrayList<ClienteDTO>)sqlMap.queryForList("ibatis_cl ienteLista", "%"+vnombre+"%"); System.out.println("listado por nombre usando Ibatis");

return clientes; } ...

Notas: 1) Se invoca al mtodo queryForList para ejecutar operaciones que retornen ms de un registro como resultado. Note que se enva la variable vnombre junto con los caracteres % a ser utilizados en la consulta definida en el archivo Cliente.xml (como parte del parmetro like).

c) Paso 3: Ejecutar la aplicacin

Ingrese a la intranet y ejecute la funcionalidad de Listado. Se visualizar la siguiente pantalla:

CIBERTEC

CARRERAS PROFESIONALES

104

En la consola, se visualizar el mensaje definido en la clase MySqlClienteDAO.

Ahora, seleccione el enlace Nuevo Cliente y registre uno nuevo con el botn Registrar.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

105

Se visualizar la siguiente ventana con el nuevo registro ingresado. En el ejemplo, se ha registrado al cliente Don Ramn.

CIBERTEC

CARRERAS PROFESIONALES

106

Tambin, se visualizar, en consola, el mensaje definido en la clase MySqlClienteDAO.

d) Paso 4: Bien!, ha culminado la funcionalidad Mantenimiento IBATIS exitosamente.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

107

2.2 Otras operaciones con IBATIS


2.2.1. Otras operaciones y caractersticas de IBATIS
Los procedimientos almacenados se crean con la declaracin <procedure>. El siguiente ejemplo muestra un procedimiento almacenado con parmetros de salida.
procedure.xml

<parameterMap id= "swapParameters" class= "map"> <parameter property= "email1" jdbcType= "VARCHAR" javaType= "java.lang.String "mode= "INOUT" /> <parameter property= "email2" jdbcType= "VARCHAR" javaType= "java.lang.String "mode= "INOUT" /> </ parameterMap> <procedure id= "swapEmailAddresses" parameterMap= "swapParameters"> (call swap_email_address (?,?)) </ procedimiento>

Se implementan, a almacenados IBATIS.

continuacin,

ejercicios

con

procedimientos

2.2.1.1. Ejercicio 1: Registro de Clientes utilizando Stored Procedures Se implementar una aplicacin web que permita registrar los datos de un cliente (incluida su fotografa), utilizando IBATIS y Stored Procedures. a) Paso 1: Importar FuncionalidadIbatisProcedure_Inicial.war el archivo

CIBERTEC

CARRERAS PROFESIONALES

108

Notas: 1) Cuenta, en esta oportunidad, dentro de la carpeta bd con archivos adicionales dentro de los cuales destaca ps_nuevoCliente.sql. Este archivo contiene el stored procedure que deber crear en mysql. b) Paso 2: Ejecute el archivo sp_nuevoCliente.sql dentro de mysql

CREATE PROCEDURE `sp_nuevoCliente`( in vnombre varchar(100), in vsueldo double, in vsexo varchar(1), in vfecnac date, in vusuario varchar(15), in vclave varchar(15), in vfoto BLOB, inout resultado int ) BEGIN declare variable int; select count(*) into variable from tbcliente where usuario = vusuario; if variable = 0 then set resultado = 777; insert into tbcliente(nombre,sueldo,sexo,fecnac,usuario,clave,foto) values( vnombre, vsueldo, vsexo, vfecnac, vusuario, vclave, vfoto); else set resultado = 666; end if; END $$ ...

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

109

Ejecute el stored procedure, utilizando la herramienta Mysql Query Browser (u otra equivalente)

Notas: 1) Se recibe como parmetro un campo de tipo BLOB. ste debe haber sido cargado previamente en la clase MySqlClienteDAO y reconocido por el archivo Cliente.xml. 2) Una vez ejecutado el script del stored procedure se debe visualizar su base de datos (en el ejemplo facilito) y el nombre del procedimiento creado.

CIBERTEC

CARRERAS PROFESIONALES

110

c) Paso 3: Modifique el mtodo registraCliente dentro de la clase MySqlClienteDAO

byte[] losbytes = new byte[is.available()]; // a partir del inputStream cargamos el arreglo los bytes is.read(losbytes); map.put("foto", losbytes); map.put("resultado", 0); System.out.println("resultado antes de insertar: " + map.get("resultado")); cliente.insert("ibatis_spInsertaCliente", map); System.out.println("resultado despues de insertar: " + map.get("resultado")); System.out.println("invocacion exitosa a SP IBATIS :) "); return resultado; ...
2 1

Notas: 1) Se carga en el objeto map un atributo adicional: el campo resultado. ste permitir recuperar el resultado retornado por el stored procedure. 2) Se debe invocar a una nueva operacin definida en el archivo Cliente.xml: ibatis_spInsertaCliente. 3) Se recupera el resultado retornado por el stored procedure: En el ejemplo, en caso de ser exitosa la operacin, retornar el valor 777, de lo contrario regresar a 666.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

111

d) Paso 4: Modifique el archivo Cliente.xml

<parameterMap class="java.util.Map" id="clienteMap" <parameter <parameter <parameter <parameter <parameter <parameter <parameter <parameter />

>

property="nombre" jdbcType="VARCHAR" mode="IN" /> property="sueldo" jdbcType="DOUBLE" mode="IN" /> property="sexo" jdbcType="CHAR" mode="IN" /> property="fecnac" jdbcType="DATETIME" mode="IN" /> property="usuario" jdbcType="VARCHAR" mode="IN" /> property="clave" jdbcType="VARCHAR" mode="IN" /> property="foto" jdbcType="BLOB" mode="IN" /> property="resultado" jdbcType="INT" mode="INOUT"

</parameterMap> ... <procedure id="ibatis_spInsertaCliente" parameterMap="clienteMap" call sp_nuevoCliente(?,?,?,?,?,?,?,?) </procedure>


Notas: 1) Se debe modificar cada una de las etiquetas <parameter> para indicar, a travs del atributo mode, si el parmetro es de entrada o entrada/salida. 2) Note cmo el arreglo de bytes cargado con el nombre foto en el objeto java.util.map es mapeado a una columna en la tabla de tipo BLOB: jdbcType=BLOB 3) Note qu resultado es la nica propiedad de tipo INOUT. A travs de ella, se retornar al MySqlClienteDAO el resultado de la ejecucin del stored procedure. 4) Debe invocar al stored procedure creado en base de datos a travs de la sentencia call. Note que usa la etiqueta IBATIS <prodecure> para definir la operacin ibatis_spInsertaCliente.

>

CIBERTEC

CARRERAS PROFESIONALES

112

e) Paso 5: Ejecute la aplicacin Seleccione la opcin Nuevo Cliente una vez realizado el listado de Clientes. Visualizar la siguiente pantalla:

Luego de ingresar datos y seleccionar el botn Registrar, se visualizar la siguiente pantalla:

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

113

Se visualizar tambin, en la consola de Eclipse, los siguientes mensajes:

Insertando con ibatis :) resultado antes de insertar: 0 resultado despues de insertar: 777 invocacion exitosa a SP IBATIS :) dentro del listaCliente del Service Validamos con ibatis listado por nombre usando Ibatis 23/01/2011 05:38:41 PM com.opensymphony.xwork2.util.logging.commons.CommonsLogger INFO: Removing file cliente.foto C:\Users\plgarcia\workspace\.metadata\.plugins\org.eclipse.wst .server.core\tmp0\work\Catalina\localhost\FuncionalidadIBatisP rocedure_Final\upload__2a3c5961_12db5077826__8000_00000006.tmp 23/01/2011 05:38:41 PM com.opensymphony.xwork2.util.logging.commons.CommonsLogger warn
f) Paso 6: Muy Bien!, ha culminado exitosamente la

funcionalidad Registro de Clientes con Stored Procedures e IBATIS.

CIBERTEC

CARRERAS PROFESIONALES

114

2.1.2. Tpicos Avanzandos de IBATIS e integracin Struts 2


Es cada vez ms comn utilizar estructuras de base de datos capaces de almacenar grandes cantidades de informacin. IBATIS es capaz de gestionar objetos grandes (LOB), tales como los campos BLOB (Binary) o CLOB (de caracteres). A partir de la versin de IBATIS 2.0.9, este framework cuenta, por defecto, los campos BLOB y CLOB. Se implementa, a continuacin, un ejemplo con Stored Procedures que utiliza este tipo de estructuras.

2.1.2.1. Ejercicio 1: Actualizacin de Clientes utilizando Stored Procedures

a) Paso 1: Ubique los Stored Procedures relacionados con la actualizacin de datos de un cliente almacenados en la carpeta bd de su proyecto.

Notas: 1) Observe que debe ejecutar los archivos sp_modificaCliente.sql y sp_modificaClienteConFoto.sql

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

115

b) Paso 2: Ejecute los archivos sp_modificaCliente.sql y sp_modificaClienteConFoto.sql dentro del entorno MySql

CREATE PROCEDURE `sp_modificaCliente`( in vnombre varchar(100), in vsueldo double, in vsexo varchar(1), in vfecnac date, in vusuario varchar(15), in vclave varchar(15), inout resultado int ) BEGIN declare variable int; select count(*) into variable from tbcliente where usuario = vusuario; if variable != 0 then set resultado = 777; update tbcliente set nombre=vnombre, sueldo=vsueldo, sexo=vsexo, fecnac=vfecnac, clave=vclave where usuario=vusuario; else set resultado = 666; end if; END $$ ...
1

CIBERTEC

CARRERAS PROFESIONALES

116

CREATE PROCEDURE `sp_modificaClienteConFoto`( in vnombre varchar(100), in vsueldo double, in vsexo varchar(1), in vfecnac date, in vusuario varchar(15), in vclave varchar(15), in vfoto BLOB, inout resultado int ) BEGIN declare variable int; select count(*) into variable from tbcliente where usuario = vusuario; if variable != 0 then set resultado = 777; update tbcliente set nombre=vnombre, sueldo=vsueldo, sexo=vsexo, fecnac=vfecnac, clave=vclave, foto=vfoto where usuario=vusuario; else set resultado = 666; end if;

END $$ ...

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

117

En el ejemplo, se ha utilizado la herramienta MySql WorkBench para ejecutar los Stored Procedures.

Notas: 1) La sentencia update no considera en su ejecucin la actualizacin de la columna foto. Este procedure ser invocado cuando el usuario del sistema no desee actualizar la fotografa del cliente. 2) Este procedure s recibe como parmetro un campo denominado vfoto, de modo que se pueda actualizar la imagen del cliente. 3) Una vez ejecutados los procedures dentro de la herramienta grfica de Mysql stos se visualizan en la ventana de edicin. En el ejemplo, en la ventana Object Browser.

CIBERTEC

CARRERAS PROFESIONALES

118

c) Paso 3: Modifique el mtodo registraCliente dentro de la clase MySqlClienteDAO

HashMap<String, Object> map = new HashMap<String, Object>(); map.put("nombre", objCliente.getNombre()); map.put("sueldo", objCliente.getSueldo()); map.put("sexo", objCliente.getSexo()); map.put("fecnac", objCliente.getFecnac()); map.put("usuario", objCliente.getUsuario()); map.put("clave", objCliente.getClave()); if (objCliente.getFoto() != null) { InputStream is = objCliente.getIsFoto(); byte[] losbytes = new byte[is.available()]; // a partir del inputStream cargamos el arreglo los bytes is.read(losbytes); map.put("foto", losbytes); } map.put("resultado", 0); System.out.println("resultado antes de actualizar: " + map.get("resultado")); SqlMapClient cliente = UtilSqlConfig.getSqlMapInstance(); if (objCliente.getFoto() != null) { cliente.update("ibatis_spModificaClienteConFoto", map); }else{ cliente.update("ibatis_spModificaCliente", map); } System.out.println("resultado despues de actualizar: " + map.get("resultado")); System.out.println("invocacion exitosa a SP MOD IBATIS :) "); } ...
Notas: 1) Solo se carga en el objeto map el atributo foto, si ste es diferente de null. En el ejemplo, se controla esta situacin a travs de la condicin: 3

if (objCliente.getFoto() != null)

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

119

2) Se invocar a una nueva operacin: ibatis_spModificaClienteConFoto o ibatis_spModificaCliente. 3) Se recupera el resultado retornado por el stored procedure: En el ejemplo, en caso de ser exitosa la operacin, retornar el valor 777, de lo contrario regresar a 666. d) Paso 4: Modifique el archivo Cliente.xml

<parameterMap class="java.util.Map" id="clienteMapBasico" > <parameter property="nombre" jdbcType="VARCHAR" mode="IN" /> <parameter property="sueldo" jdbcType="DOUBLE" mode="IN" /> <parameter property="sexo" jdbcType="CHAR" mode="IN" /> <parameter property="fecnac" jdbcType="DATETIME" mode="IN" /> <parameter property="usuario" jdbcType="VARCHAR" mode="IN" /> <parameter property="clave" jdbcType="VARCHAR" mode="IN" /> <parameter property="resultado" jdbcType="INT" mode="INOUT" /> </parameterMap> <parameterMap class="java.util.Map" id="clienteMap" > <parameter property="nombre" jdbcType="VARCHAR" mode="IN" /> <parameter property="sueldo" jdbcType="DOUBLE" mode="IN" /> <parameter property="sexo" jdbcType="CHAR" mode="IN" /> <parameter property="fecnac" jdbcType="DATETIME" mode="IN" /> <parameter property="usuario" jdbcType="VARCHAR" mode="IN" /> <parameter property="clave" jdbcType="VARCHAR" mode="IN" /> <parameter property="foto" jdbcType="BLOB" mode="IN" /> <parameter property="resultado" jdbcType="INT" mode="INOUT" /> </parameterMap> ... <procedure id="ibatis_spModificaClienteConFoto" parameterMap="clienteMap" > call sp_modificaClienteConFoto(?,?,?,?,?,?,?,?) </procedure> <procedure id="ibatis_spModificaCliente" parameterMap="clienteMapBasico" > call sp_modificaCliente(?,?,?,?,?,?,?) </procedure>
Notas: 1) Se ha creado un nuevo parameterMap: clienteMapBasico, que ser utilizado para actualizar la informacin del cliente sin modificar su fotografa.

CIBERTEC

CARRERAS PROFESIONALES

120

2) Se mantiene el parameterMap clienteMap para actualizar la informacin del cliente modificando su fotografa.

3) Se han creado dos nuevas operaciones en el archivo Cliente.xml que sern invocadas por la clase MySqlClienteDAO para modificar la informacin del cliente modificando o no su fotografa, respectivamente.

e) Paso 5: Ejecute la aplicacin Una vez realizado el listado de clientes, seleccione el enlace M para modificar uno de los clientes. En el ejemplo, se cambian los datos de Don Ramn. Se visualizar la siguiente pantalla:

Luego de modificar los datos y seleccionar el botn Actualizar, se visualizar la siguiente pantalla:

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

121

Nota: 1) Puede seleccionar nuevamente el enlace M para verificar los cambios realizados. Visualizar que se logr modificar exitosamente la fotografa de Don Ramn.

CIBERTEC

CARRERAS PROFESIONALES

122

f)

Paso

6:

Muy Bien!,

ha

culminado

exitosamente la

funcionalidad Actualizacin Procedures e IBATIS.

de Clientes con Stored

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

123

Resumen
Para recoger un conjunto de elementos con la clase List, puede hacer lo siguiente:
List<Coche> coches = sqlMap.queryForList("getCoches", null)

Para recoger un conjunto de elementos con la clase Map, puede hacer lo siguiente:
Map hashCoche = (Map) sqlMap.queryForObject("getHashCoche", 3);

Para el manejo del campo BLOB, se tiene que realizar lo siguiente en el archivo de Ibatis:

<resultMap class= <result <result <result <result /> </ resultMap>

"Report" id= "ReportResult"> column= "id" property= "id" /> column= "name" property= "name" /> column= "description" property= "description" /> column= "data" property= "data" jdbcType= "BLOB"

Si desea saber ms acerca de estos temas, puede consultar la siguiente pgina. http://www.nabble.com/iBATIS-f360.html Aqu encontrar un foro donde se ventilan varios puntos del manejo de Ibatis http://www.javaworld.com/javaworld/jw-07-2008/jw-07-orm-comparison.html Aqu hallar comparaciones entre los frameworks de persistencia ms utilizados.

CIBERTEC

CARRERAS PROFESIONALES

124

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

125

UNIDAD DE APRENDIZAJE

REPORTES EN SISTEMAS EMPRESARIALES


LOGRO DE LA UNIDAD DE APRENDIZAJE
Al finalizar la unidad, los alumnos, utilizando el framework STRUTS 2, la librera JasperReport y la herramienta IReport, implementan una aplicacin web que genera reportes con criterios de bsqueda dinmicos y acceso a base de datos.

TEMARIO 3.1 Tema 5 3.1.1. : Reportes con JasperReport : Diseo e implementacin de reportes con la herramienta IReport : Struts 2 y JasperReport : Integracin de Struts 2 y JasperReport Reportes Estndar

3.2 Tema 6 3.2.1.

ACTIVIDADES PROPUESTAS Los alumnos implementan una aplicacin web bsica utilizando las principales caractersticas del framework MVC Struts 2 y la librera jasperReport.

CIBERTEC

CARRERAS PROFESIONALES

126

3.1 Reportes con JasperReport


3.1.1. Diseo e implementacin de Reportes con la herramienta IReport
La herramienta iReport es un constructor y/o diseador de reportes visual, fcil de usar para JasperReport, un lenguaje para generacin de reportes escrito en Java. Esta herramienta permite que los usuarios corrijan visualmente reportes complejos con cartas, imgenes, subreportes, etc. iReport est, adems, integrado con la biblioteca grfica JFreeChart, una de las ms grficas OpenSource y difundida para Java. Los datos para imprimir pueden ser recuperados por varios tipos de archivos, incluso mltiples uniones JDBC, TableModels, JavaBeans, archivos XML, etc. A continuacin, se enumeran las principales caractersticas de esta herramienta: 100% escrito en JAVA y, adems, de uso libre y gratuito Maneja el 99% de las etiquetas de JasperReports Permite disear con sus propias herramientas: rectngulos, lneas, elipses, campos de los textfields, cartas, subreports (subreportes) Soporta internacionalizacin nativamente Recopila y exporta integrados Soporta JDBC Soporta JavaBeans como orgenes de datos Incluye asistentes para crear automticamente informes.

3.1.1.1. Funcionamiento de JasperReport JasperReports trabaja en forma similar a un compilador y a un intrprete. El usuario disea el reporte codificndolo en XML de acuerdo con las etiquetas y atributos definidos en un archivo llamado jasperreports.dtd (parte de JasperReports). Usando XML, el usuario define completamente el reporte, describiendo dnde colocar texto, imgenes, lneas, rectngulos, cmo adquirir los datos, cmo realizar ciertos clculos para mostrar totales, etc. Este archivo fuente XML debe ser compilado para obtener un reporte real. La versin compilada del fuente es nombrada "archivo jasper" (este termina con .jasper). Un Archivo jasper es el compilado de un cdigo fuente. Cuando se tiene ste, se necesita de datos para visualizar el resultado. Para generar reportes en Java, se necesita considerar la aplicacin del archivo compilado (.jasper), que recibir los datos a visualizar de la aplicacin. El archivo generado por la herramienta iReport es de tipo jrxml, en el cual se encontrar el diseo y estilo del reporte, y podr ser modificado en la herramienta iReport.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

127

3.2 Struts 2 y JasperReport


3.2.1. Integracin de Struts 2 y JasperReport Reportes Estndar
Struts 2 permite implementar una integracin natural con JasperReport a travs del uso de una librera (plug in): struts2-jasperreports-plugin-2.1.8.1.jar Esta librera viene por defecto con la versin estndar de Struts 2 y permite crear en el archivo struts.xml un nuevo tipo de <result>: jasper Se implementar, a continuacin, un ejercicio de aplicacin, en el que se integra un reporte generado con la herramienta IReport (archivo compilado .jasper) y Struts 2. 3.2.1.1. Ejercicio 01: Funcionalidad Reporte de clientes con JasperReport Se implementar una aplicacin web que permita listar los clientes por Pas, haciendo uso de la librera JasperReport e integrndola a Struts 2. a) Paso 1: Importar el archivo FuncionalidadIbatisReportes_Inicial.war

CIBERTEC

CARRERAS PROFESIONALES

128

Notas: 1) Existe un nuevo archivo en la carpeta bd denominado FacilitoBaseDatosv2.sql. En l, se encontrarn nuevas tablas, a partir de las cuales se generar el reporte. 2) Existen nuevas libreras en la carpeta lib que permitirn integrar Struts 2 y JasperReport.

b) Paso 2: Ejecute el archivo FacilitoBaseDatosv2.sql dentro de mysql

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

129

create table pais ( `cod_pais` varchar(2) not null, `nom_pais` varchar(90) not null, primary key (`cod_pais`) ) ENGINE=InnoDB default CHARSET=latin1;
1

create table cliente ( `usuario` varchar(15) not null, `password` varchar(15) not null, `nombres` varchar(90) null, `apellidos` varchar(90) null, `sexo` varchar(1) not null, `fecha_nacimiento` datetime null, `dni` varchar(8) null, `cod_pais` varchar(2) null, `fecha_ingreso` datetime null, `email` varchar(80) null, `vip` varchar(1) not null, `flag_admin` varchar(1) not null default 'N', primary key (`usuario`)

Notas: 1) Debe crear las tablas cliente y pas en MySql. Sobre la base de estas tablas, se generar el nuevo reporte. b) Paso 3: Modificar el archivo struts.xml

CIBERTEC

CARRERAS PROFESIONALES

130

. . . <result-types> <result-type name="jasper"

class="org.apache.struts2.views.jasperreports.JasperReportsR esult"/> </result-types>


2

<!-- creamos los actions del menu --> <action name="a_reporte" > <result type="tiles" >d_reporte</result> </action> . . . <action name="reporteFacilito" class="aprendamos.java.action.ReporteAction" method="listaClientesPorPais" > <result name="exito" type="jasper"> <param name="location">/reportes/reporte01.jasper</param> <param name="dataSource">listaClientes</param> <param name="contentDisposition"> attachment;filename="contacts.pdf" </param> <param name="format">PDF</param> <!--<param name="connection">cnListaClientes</param> -> d_reporte </result>
Notas: 1) Debe crear un nuevo result type para poder integrar jasperReport y Struts 2. 2) Cree el action a_reporte para invocar a un nuevo definition: d_reporte. ste invocar a una pgina JSP para generar el reporte, usando JasperReport. 3) Cree un nuevo action: reporteFacilito. Este componente define un <result> de tipo jasper en donde se configuran los principales parmetros del reporte como por ejemplo: Formato del archivo a generar: PDF Ubicacin de archivos compilado ejecutar: /reportes/reporte01.jasper Origen de datos para generar (dataSource): atributo listaClientes. .jasper a

el

listado

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

131

d) Paso 4: Modificar el archivo tiles.xml

<definition name="d_reporte" extends="d_bienvenida"> <put-attribute name="body" value="/paginas/reportes.jsp" /> </definition> ...

Notas: 1) Cree el definition d_reporte. Se invocar al JSP reportes.jsp

e) Paso 5: Cree el archivo reportes.jsp

<s:form method="post" action="reporteFacilito"> <table class="control" > <tr> <td> <s:text name="reporte.nombre" /> </td> <td> <s:textfield name="nombre" /> </td> <td align="right" > <input type="submit" name="boton01" value="Listar" > </td> </tr> </table> </s:form>su ID -->

...

Notas: 1) Debe invocar al action reporteFacilito, el cual ya ha sido registrado en el archivo struts.xm. Asimismo, debe generar el listado con jasperreport. f) Paso 6: Cree el action ReporteAction

CIBERTEC

CARRERAS PROFESIONALES

132

public class ReporteAction { private String nombre; private List<ReporteDTO> listaClientes;

public List<ReporteDTO> getListaClientes() { return listaClientes; } public void setListaClientes(List<ReporteDTO> listaClientes) { this.listaClientes = listaClientes; } public String getNombre() { return nombre; } public void setNombre(String nombre) { this.nombre = nombre; } public String listaClientesPorPais(){ String vista="exito"; //JasperReportConstants.FORMAT_HTML //JasperReportConstants.FORMAT_PDF //JasperReportConstants.FORMAT_XLS System.out.println("dentro de listaClientesPorPais :)"); try { this.setListaClientes( PaqueteBusinessDelegate.getClienteService(). listaClientesReporte(nombre)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("nombre del cliente"+this.getNombre()); System.out.println("redireccionamos a la vista exito!"); return vista; } } ...
Notas: 1) El atributo listaClientes es referenciado en el archivo struts.xml como origen de datos para el Reporte. Note que es una lista de objetos de tipo ReporteDTO. Esta clase tiene como atributos los campos que sern mostrados en el reporte. 2) Se define la lista de clientes a obtener, considerando la seleccin del usuario (el atributo nombre).

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

133

g) Paso 7: Modifica la clase ClienteService

public List<ReporteDTO> listaClientesReporte(String nombre) throws Exception{ System.out.println("dentro del listaCliente del Service"); // Aqui podemos colocar logica adicional antes de invocar al metodo // del DAO return objClienteDAO.listaPorNombreReporte(nombre); ...

Notas: 1) Debe crear el mtodo listaClientesReporte para que la clase ReporteAction pueda invocarlo y generar el reporte.

CIBERTEC

CARRERAS PROFESIONALES

134

h) Paso 8: Modificar el archivo MySqlClienteDAO

public List<ReporteDTO> listaPorNombreReporte(String nombre) throws Exception { ArrayList<ReporteDTO> clientes= new ArrayList<ReporteDTO>(); Connection cn = MySqlDBConn.obtenerConexion(); //definimos la sentencia String sql="SELECT usuario,password,nombres,apellidos,sexo,fecha_nacimiento,dni, c.cod_pais,p.nom_pais" + " FROM cliente c,pais p WHERE c.nombres like and c.cod_pais = p.cod_pais order by c.cod_pais"; //la preparamos PreparedStatement pst=cn.prepareStatement(sql); //asignamos valores a las interrogantes pst.setString(1,"%"+nombre+"%"); //ejecutamos ResultSet rs=pst.executeQuery(); while(rs.next()){ //hay dayos, recuperamos un ergsitro ReporteDTO cliente = new ReporteDTO(); cliente.setUsuario(rs.getString(1)); cliente.setPassword(rs.getString(2)); cliente.setNombres(rs.getString(3)); cliente.setApellidos(rs.getString(4)); cliente.setSexo(rs.getString(5)); cliente.setFecha_nacimiento(rs.getString(6)); cliente.setDni(rs.getString(7)); cliente.setCod_pais(rs.getString(8)); cliente.setNom_pais(rs.getString(9)); clientes.add(cliente); } cn.close(); return clientes; } ...
1

Notas: 1) Note cmo, de manera clsica, se obtiene una conexin para hacer la consulta respectiva. Debe transformar este cdigo a su equivalente en ibatis. i) Paso 9: Modifique el archivo menu.jsp

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

135

<tr> <td class="control" > <s:a action="a_reporte" > />


1

<s:text name="menu.reporte" </s:a> </td> </tr> ...

Notas: 1) Debe invocar al action a_reporte para cargar la pgina JSP a partir de la cual se generar el reporte.

i)

Paso 10: Ejecutar la aplicacin web

Ingrese a la intranet a travs de la pgina de logueo. Se visualizar la siguiente pantalla:

Seleccione la opcin reporte utilizando JasperReport

CIBERTEC

CARRERAS PROFESIONALES

136

Se visualizar la siguiente pantalla. Luego, ingrese un criterio de bsqueda. Finalmente, seleccione el botn Listar.

Visualizar una pantalla a travs de la que se le consultar si desea abrir o guardar el archivo. Seleccione abrir el archivo.

Visualizar el reporte en una pantalla similar a la siguiente:

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

137

j)

Paso 11:

Muy Bien!, ha culminado la funcionalidad

reportes con JasperReport y Struts 2 de manera exitosa!

CIBERTEC

CARRERAS PROFESIONALES

138

Resumen
Se pueden construir reportes visualmente en Java, utilizando la herramienta iReport. sta usa como estructura base jasperReport, un lenguaje basado en etiquetas xml y especialmente creado para generar reportes. IReport genera archivos fuente con extensin .jrxml. Los archivos compilados tienen extensin .jasper y pueden ser ejecutados desde una aplicacin java web.

Si desea saber ms acerca de estos temas, puede consultar la siguiente pgina. http://jasperforge.org/website/ireportwebsite/IR%20Website/iReport_documentati on.html?group_id=243&header=project&leftnav=yes&target=ireport

Aqu, encontrar tutoriales que le permitirn crear reportes utilizando IReport.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

139

ANEXOS

ANEXO 1: SOFTWARE REQUERIDO

Este curso requiere las siguientes herramientas de software: Java JDK Entorno integrado de desarrollo o IDE Servidor de Aplicaciones Base de datos Framework Struts 2 Framework MyIbatis MyIbatis Generator

CIBERTEC

CARRERAS PROFESIONALES

140

HERRAMIENTA #1: Java Development Kit


Desde la pgina de Oracle, descargue la ltima versin del JDK (Java Development Kit). Se debe considerar que los updates de las versiones son peridicos. Se puede navegar por http://java.sun.com, el cual redirecciona a http://www.oracle.com/technetwork/java/javase/downloads/index.html

Para entornos de programacin, se requiere el JDK, pero para los de produccin basta con el JRE. Por ltimo, ejecute el instalador y siga los pasos indicados en el wizard.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

141

HERRAMIENTA #2: Entorno Integrado de Desarrollo


En un entorno de desarrollo Java, el IDE ( Integrated Development Environment ) es la herramienta de software que permite obtener mayor productividad al programar las aplicaciones. En el mercado, existen varias opciones disponibles, pero las ms utilizadas y conocidas son las siguientes: Eclipse IDE : Sitio web http://www.eclipse.org NetBeans : Sitio web http://www.netbeans.org JDeveloper : Informacin disponible en http://www.oracle.com Rational Application Developer: Informacin disponible en http://www.ibm.com

Eclipse IDE:
Primero, descargue Eclipse Helios desde la pgina de la fundacin Eclipse ( http://www.eclipse.org ). Luego, busque la zona de descarga. Por ltimo, seleccione la versin Java EE:

Al terminar la descarga, el .ZIP generado se puede extraer en una carpeta cualquiera (normalmente en la raz de uno de los discos de la PC). Se puede crear un acceso directo desde el Escritorio apuntando al archivo eclipse.exe

CIBERTEC

CARRERAS PROFESIONALES

142

Rational Application Developer IDE :


Descargue el software IBM Rational Application Developer for WebSphere Software desde la pgina web de IBM: http://www.ibm.com/developerworks/downloads/r/rad/?S_CMP=TRIALS

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

143

HERRAMIENTA #3: Servidor de aplicaciones


Apache Tomcat
Desde la pgina de la Fundacin Apache ( http://tomcat.apache.org ), se debe obtener el servidor de aplicaciones Tomcat. La ltima versin probada en otros tutoriales ha sido la 6.0.20. Actualmente se encuentra disponible la versin 7 en beta.

Slo es necesario el Core. Descargar el .ZIP y extraerlo en una carpeta.

WebSphere Application Server


Desde la pgina web de IBM, se puede descargar el software del servidor de aplicaciones: http://www-01.ibm.com/software/webservers/appserv/was/

CIBERTEC

CARRERAS PROFESIONALES

144

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

145

HERRAMIENTA #4: Motor de Base de Datos


Se necesita un motor de base de datos: En http://www.mysql.com, se puede decargar la Base de Datos MySQL (versin Community Server )

Es preferible descargar la versin NO-INSTALL para que no afecte el registry de la PC:

Basta con descargar el .ZIP y extraerlo en cualquier carpeta. El servicio de base de datos se activa por lnea de comandos de la manera siguiente:

CIBERTEC

CARRERAS PROFESIONALES

146

Tambin, se requiere el Connector o driver JDBC:

Las herramientas de Query Browser y MySQL Administrator han sido reemplazadas por MySQL WorkBench:

De igual forma, seleccionar el .ZIP ( que sea del tipo No Install ) y extraerlo en alguna carpeta de la PC.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

147

HERRAMIENTA #5: Libreras de Struts 2


Del sitio web de la Fundacin Apache, se obtienen las libreras del framework Struts 2 La ltima versin liberada es la 2.2.1

Se debe escoger una de las opciones de los archivos .ZIP. Con la alternativa de Full Distribution, es ms que suficiente.

Extraer el contenido del .ZIP en una carpeta de la PC.

CIBERTEC

CARRERAS PROFESIONALES

148

HERRAMIENTA #6: MyIbatis


La pgina principal se encuentra en http://www.mybatis.org/

En la zona de downloads, la direccin es http://code.google.com/p/mybatis/

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

149

HERRAMIENTA #7: MyIbatis Generator


La pgina principal se encuentra: http://code.google.com/p/mybatis/downloads/detail?name=mybatis-generator-core1.3.1-bundle.zip&can=3&q=Product%3DGenerator

CIBERTEC

CARRERAS PROFESIONALES

150

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

151

ANEXOS

ANEXO 2: MANEJO DE MYIBATIS


Ejemplo de una aplicacin con MyIbatis

CIBERTEC

CARRERAS PROFESIONALES

152

La Clase entidad

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

153

El Data Access Object para Vendedor

CIBERTEC

CARRERAS PROFESIONALES

154

El Mapper de MyIbatis para el mantenimiento de vendedor es el siguiente:

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

155

El Archivo de Configuracin de MyIbatis los datos de la cadena de conexin los tipos de datos de los mappers la ubicacin de los mappers

Se configura Se configura Se configura

CIBERTEC

CARRERAS PROFESIONALES

156

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

157

ANEXOS

ANEXO 3: MYIBATIS
DynamicSQL
Una de las caractersticas ms potentes de MyBatis siempre ha sido su capacidad de SQL dinmico. MyBatis, sin duda, mejora la situacin en el lenguaje SQL, que se pueden utilizar dentro de cualquier mapa instruccinSQL. Los elementos de SQL dinmico debe ser familiar para cualquiera que haya usado JSTL o cualquier XML, similares a base procesadores de texto. En versiones anteriores de MyBatis, haba una gran cantidad de elementos para conocer y comprender. M ejora en gran medida en esto y ahora hay menos de la mitad de esos elementos para trabajar. Asimismo, emplea potentes expresiones OGNL base para eliminar la mayora de los dems elementos.

If choose (when, otherwise) trim (where, set) foreach


Ejemplo de if:
<select id=findActiveBlogWithTitleLike parameterType=Blog resultType=Blog> SELECT * FROM BLOG WHERE state = ACTIVE <if test=title != null> AND title like #{title} </if> </select> <select id=findActiveBlogLike parameterType=Blog resultType=Blog> SELECT * FROM BLOG WHERE state = ACTIVE <if test=title != null> AND title like #{title} </if> <if test=author != null and author.name != null> AND title like #{author.name} </if> </select>

CIBERTEC

CARRERAS PROFESIONALES

158

choose, when, otherwise


<select id=findActiveBlogLike parameterType=Blog resultType=Blog> SELECT * FROM BLOG WHERE state = ACTIVE <choose> <when test=title != null> AND title like #{title} </when> <when test=author != null and author.name != null> AND title like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select>

trim, where, set


<select id=findActiveBlogLike parameterType=Blog resultType=Blog> SELECT * FROM BLOG WHERE <if test=state != null> state = #{state} </if> <if test=title != null> AND title like #{title} </if> <if test=author != null and author.name != null> AND title like #{author.name} </if> </select> <select id=findActiveBlogLike parameterType=Blog resultType=Blog> SELECT * FROM BLOG <where> <if test=state != null> state = #{state} </if> <if test=title != null> AND title like #{title} </if> <if test=author != null and author.name != null> AND title like #{author.name} </if> </where> </select>

Foreach
<select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select>

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

159

ANEXOS

ANEXO 3: DE IBATIS 2.X HACIA MYIBATIS


En el sqlMapConfig.xml DTD:

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

En los mappers sqlMap (*.map.xml) DTD:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

Configuracin:

La raz era <sqlMapConfig>, ahora es <configuration>

Settings Ibatis 2.0:

<settings x="y" foo="bar"/>

MyIbatis 3.0:

<settings> <setting name="x" value="y"/> <setting name="foo" value="bar"/> </settings>

CIBERTEC

CARRERAS PROFESIONALES

160

<settings useStatementNamespaces="true"/>

<typeAlias>
<typeAlias>

deberia ser movido fuera de <sqlMap> hacia

<configuration> <typeAliases></typeAliases> </configuration>

<configuration> <settings> ... </settings> <typeAliases> <typeAlias ... /> </typeAliases> </configuration>

<transactionManager> <dataSource> Ibatis 2.0:

<transactionManager type="JDBC" commitRequired="false"> <dataSource type="your.package.CustomDataSourceFactory" /> </transactionManager>

MyIbatis 3.0:

<environments default="env"> <environment id="env"> <transactionManager type="JDBC"> <property name="commitRequired" value="false"/> </transactionManager> <dataSource type="your.package.CustomDataSourceFactory" /> </environment> </environments>

<sqlMap>

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

161

Ibatis 2.0:

<sqlMap resource=... /> <sqlMap resource=... /> <sqlMap resource=... />

MyIbatis 3.0:

<mappers> <mapper resource=... /> </mappers>

Mapping

La raiz del elemento <sqlMap> es ahora <mapper> El atributo parameterClass debera ser cambiado por parameterType El atributo resultClass debera ser cambiado por resultType El atributo class debera ser cambiado por type El columnIndex atributo no existe algun resultado en la etiqueta <result> El groupBy atributo debera ser eliminado.

Ibatis 2.0:

<resultMap id="productRM" class="product" groupBy="id"> <result property="id" column="product_id"/> <result property="name" column="product_name"/> <result property="category" column="product_category"/> <result property="subProducts" resultMap="Products.subProductsRM"/> </resultMap>

MyIbatis 3.0:

<resultMap id="productRM" type="product" > <id property="id" column="product "/> <result property="name " column="product_name "/> <result property="category " column="product_category "/> <collection property="subProducts" resultMap="Products.subProductsRM"/> </resultMap>

CIBERTEC

CARRERAS PROFESIONALES

162

Nested resultMaps
debera especificarse mediante <association> tag.

Ibatis 2.0:

<resultMap ...> <result property="client" resultMap="Client.clientRM"/> ... </resultMap>

MyIbatis 3.0:

<resultMap ...> <association property="client" resultMap="Client.clientRM"/> ... </resultMap>

Inline parameters Ibatis 2.0:

#value#

MyIbatis 3.0:

#{value}

jdbcType changes Ibatis 2.0:

jdbcType="ORACLECURSOR"

MyIbatis 3.0:

jdbcType="CURSOR"

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

163

Ibatis 2.0:

jdbcType="NUMBER"

MyIbatis 3.0:

jdbcType="NUMERIC"

Stored procedures

La etiqueta <procedure> no existe en MyIbatis. Use <select>, <insert> o <update>.

Ibatis 2.0:

<procedure id="getValues" parameterMap="getValuesPM"> { ? = call pkgExample.getValues(p_id => ?) } </procedure>

MyIbatis 3.0:

<select id="getValues" parameterMap="getValuesPM" statementType="CALLABLE"> { ? = call pkgExample.getValues(p_id => ?)} </select>

Caching Ibatis 2.0:

<cacheModel id="myCache" type="LRU"> <flushInterval hours="24"/> <property name="size" value="100" /> </cacheModel>

MyIbatis 3.0:

<cache flushInterval="86400000" eviction="LRU"/>

CIBERTEC

CARRERAS PROFESIONALES

164

Dynamic SQL Ibatis 2.0:

<isNotNull.*?property=\"(.*?)\"> </isNotNull>

MyIbatis 3.0:

<if test="$1 != null"> </if>

CARRERAS PROFESIONALES

CIBERTEC