Está en la página 1de 164

Desarrollo de

Aplicaciones Web I

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

NDICE

Pgina

Presentacin

Red de contenidos

Unidad de aprendizaje 1: Modelo Vista Controlador Patrn MVC


1.1 Tema 1

: Fundamentos de Struts 2

1.1.1. : Arquitectura y Configuracin de aplicaciones

1.1.2. : La clase Action

13

1.1.3. : Libreras de etiquetas de Struts 2

29

1.1.4. : Internacionalizacin I18N

51

1.2 Tema 2

: Acceso optimizado a base de datos y otras

63

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

2.1.1. : IBATIS Introduccin

101

2.1.2. : Operaciones bsicas de acceso a base de datos con

110

IBATIS
2.2 Tema 4

: Otras operaciones con IBATIS

119

2.2.1. : Otras operaciones y caractersticas de IBATIS

119

2.2.2. : Tpicos avanzados de IBATIS e Integracin con

128

Struts 2

Unidad de aprendizaje 3: Reportes en Sistemas empresariales


3.1 Tema 5

CIBERTEC

: Reportes con JasperReport

139

CARRERAS PROFESIONALES

3.1.1. : Diseo e implementacin de reportes con la

141

herramienta Ireport
3.2 Tema 6

: Struts 2 y JasperReport

3.2.1. : Integracin de Struts 2 y JasperReport

142
142

Anexo 1

157

Anexo 2

167

Anexo 3

172

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

Fundame
ntos de
Struts 2

Otras
Caractersticas
Struts 2

CARRERAS PROFESIONALES

Persistencia de
datos
Framework
IBATIS

Introduccin
a IBATIS

Otras
operaciones
IBATIS

Reportes en
sistemas
empresariales

Tema 5
JasperReport

CIBERTEC

Tema 6
Struts 2 y
Jasper

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.

1.1 Fundamentos de Struts 2

CIBERTEC

CARRERAS PROFESIONALES

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:
9 Services (Lgica pura de negocio)
9 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
encuentra registrado en el archivo de configuracin XML de Struts 2. ste
tiene por defecto el nombre struts.xml.

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

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:
1) El principal archivo de configuracin del Framework es el
archivo struts.xml. En l, se registrarn sus principales

CIBERTEC

CARRERAS PROFESIONALES

10

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 /*.

c) Paso 3: Ejecutar la aplicacin

CARRERAS PROFESIONALES

CIBERTEC

DESARROLLO DE APLICACIONES WEB I

11

d) Paso 4: Excelente!, ha culminado el proceso de probar


exitosamente la aplicacin web struts2-blank-2.1.8.1

1.1.2. La clase Action

CIBERTEC

CARRERAS PROFESIONALES

12

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


de
configuracin al proyecto web funcionalidadLogueov1_Inicial

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();

9 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.
9 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

9 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>
<tr>

<td class="error general">


<!-- podemos visualizar el mensaje de error usando EL -->
${requestScope.mensaje}
</td>

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
logueo.titulo =
Pagina de Inicio - Que facil es JEE :):)
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

9 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"

>/listado.jsp</result>

</action>

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

...
2

ClienteService_I servicioCliente =
PaqueteBusinessDelegate.getClienteService();

// creamos el metodo registra


public String registra(){
String vista="exito";

3
4

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;
}

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

f)

35

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;

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).

9 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());

9 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

i)

39

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>

1
</result>

. . .
Notas:
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

f)

51

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

CARRERAS PROFESIONALES

web

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.*;

1
2

public class MySqlDBConn {


// Utilizaremos mas bien un pool de conexiones
// creamos el metodo que nos permite obtener una conexion
. . .

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)

CARRERAS PROFESIONALES

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

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:
9 <s:url>
9 <s:action>
9 <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:

. . .
1

<td align="center" >


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

href="${carga}" >

M </a>

</td>

. . .

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

f)

69

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

j)

73

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)

CIBERTEC

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

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:

CIBERTEC

Pginas. Para todas aquellas de la aplicacin web.

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>
...

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>

</result>
2

<action name="a_bienvenida"
>
<result type="tiles"> d_bienvenida
</action>

</result>
3

<action name="a_logueo"
>
<result > /logueo.jsp
</action>

</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

</result>

</action>
...

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
/></td>
</tr>
<tr>
<td><tiles:insertAttribute name="menu"
<td><tiles:insertAttribute name="body"
</tr>
<tr>
<td colspan="2"><tiles:insertAttribute
</tr>
</table>

name="cabecera"

/></td>
/></td>

name="pie" /></td>

</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>

<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

i)

85

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)

CARRERAS PROFESIONALES

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

la

funcionalidad

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.

: IBATIS Introduccin

2.1.2.

: Operaciones bsicas de acceso a base de datos con IBATIS

2.2 Tema 4 : Otras operaciones con IBATIS


2.2.1.

: Otras operaciones y caractersticas de IBATIS

2.2.2.

: Tpicos avanzados de IBATIS e Integracin con Struts 2

ACTIVIDADES PROPUESTAS

CIBERTEC

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

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>
...

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

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

class="cli"
id="clienteRes"

>

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

Elementos Hijos

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

insert
update
All dynamic elements delete
All query
methods

Mtodos

<insert>

id
parameterClass
parameterMap

All dynamic elements


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

<update>

id
parameterClass
parameterMap

All dynamic elements insert


<generate> (.NET
update
only)
delete

<delete>

id
parameterClass
parameterMap

All dynamic elements insert


<generate> (.NET
update
only)
delete

<select>

id
parameterClass
resultClass
parameterMap
resultMap
cacheModel

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

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

class="cli"
id="clienteRes"

>

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>

<parameterMap class="java.util.Map" id="clienteMap"


<parameter
<parameter
<parameter
<parameter
<parameter
<parameter
<parameter

>

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" />

</parameterMap>

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>
...

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

>
1

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);
1

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.

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);
1

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;
...

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;
1

update tbcliente
set nombre=vnombre,
sueldo=vsueldo,
sexo=vsexo,
fecnac=vfecnac,
clave=vclave
where usuario=vusuario;
else
set resultado = 666;
end if;
END $$
...

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:

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

funcionalidad Actualizacin

culminado

exitosamente

la

de Clientes con Stored

Procedures e IBATIS.

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

: Reportes con JasperReport

3.1.1.

: Diseo e implementacin de reportes con la herramienta IReport

3.2 Tema 6

: Struts 2 y JasperReport

3.2.1.

: Integracin de Struts 2 y JasperReport Reportes Estndar

ACTIVIDADES PROPUESTAS

CIBERTEC

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

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:
9 100% escrito en JAVA y, adems, de uso libre y gratuito
9 Maneja el 99% de las etiquetas de JasperReports
9 Permite disear con sus propias herramientas: rectngulos, lneas,
elipses, campos de los textfields, cartas, subreports (subreportes)
9 Soporta internacionalizacin nativamente
9 Recopila y exporta integrados
9 Soporta JDBC
9 Soporta JavaBeans como orgenes de datos
9 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)

CIBERTEC

Paso 1: Importar el archivo


FuncionalidadIbatisReportes_Inicial.war

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;

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:

CARRERAS PROFESIONALES

Formato del archivo a generar: PDF

Ubicacin de archivos compilado


ejecutar: /reportes/reporte01.jasper

.jasper

Origen de datos para generar


(dataSource): atributo listaClientes.

el

listado

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>();
1

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;
}
...

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"

>

<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

j)

Paso 11:

137

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:

CIBERTEC

Java JDK
Entorno integrado de desarrollo o IDE
Servidor de Aplicaciones
Base de datos
Framework Struts 2
Framework MyIbatis
MyIbatis Generator

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

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

CIBERTEC

155

Se configura
Se configura
Se configura

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

También podría gustarte