5to ciclo desarrollo de aplicaciones web i

2,226 views

Published on

0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,226
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
170
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

5to ciclo desarrollo de aplicaciones web i

  1. 1. Desarrollo deAplicaciones Web I
  2. 2. 2CARRERAS PROFESIONALES CIBERTEC
  3. 3. DESARROLLO DE APLICACIONES WEB I 3ÍNDICE PáginaPresentación 5Red de contenidos 6Unidad de aprendizaje 1: Modelo Vista Controlador – Patrón MVC1.1 Tema 1 : Fundamentos de Struts 2 9 1.1.1. : Arquitectura y Configuración de aplicaciones 9 1.1.2. : La clase Action 13 1.1.3. : Librerías de etiquetas de Struts 2 29 1.1.4. : Internacionalización – I18N 511.2 Tema 2 : Acceso optimizado a base de datos y otras 63 características Struts 2 1.2.1. : Uso de un pool de conexiones para acceso a la fuente 63 de datos 1.2.2. : Librería de Etiquetas de Struts 2 – Principales 72 componentes 1.2.3. : Patrón Composite View – Struts 2 Tiles 87Unidad de aprendizaje 2: Persistencia de datos – Framework IBATIS2.1 Tema 3 : Introducción a IBATIS 101 2.1.1. : IBATIS – Introducción 101 2.1.2. : Operaciones básicas de acceso a base de datos con 110 IBATIS2.2 Tema 4 : Otras operaciones con IBATIS 119 2.2.1. : Otras operaciones y características de IBATIS 119 2.2.2. : Tópicos avanzados de IBATIS e Integración con 128 Struts 2Unidad de aprendizaje 3: Reportes en Sistemas empresariales3.1 Tema 5 : Reportes con JasperReport 139CIBERTEC CARRERAS PROFESIONALES
  4. 4. 4 3.1.1. : Diseño e implementación de reportes con la 141 herramienta Ireport3.2 Tema 6 : Struts 2 y JasperReport 142 3.2.1. : Integración de Struts 2 y JasperReport 142Anexo 1 157Anexo 2 167Anexo 3 172CARRERAS PROFESIONALES CIBERTEC
  5. 5. DESARROLLO DE APLICACIONES WEB I 5PRESENTACIÓNDesarrollo de Aplicaciones Web I pertenece a la línea de Programación yDesarrollo de Aplicaciones. Es un curso de especialidad sólo en la carrera deComputación e Informática. Permite al estudiante concretizar proyectosinformáticos web, aplicando conocimientos previos aprendidos en diferentescursos y poniendo en práctica la teoría adquirida. De esta manera, consolidaconocimientos de diversos cursos de especialidad. Es práctico y desarrollado enlaboratorio. Se implementarán soluciones web que utilizarán los FrameworksStruts 2 e IBATIS en forma combinada.El manual para el curso ha sido diseñado bajo la modalidad de unidades deaprendizaje, las que se desarrollan durante semanas determinadas. En cada unade ellas, hallará los logros, que debe alcanzar al final de la unidad; el tematratado, el cual será ampliamente desarrollado; y los contenidos, que debedesarrollar, es decir, los subtemas. Por último, encontrará las actividades quedeberá desarrollar en cada sesión, que le permitirán reforzar lo aprendido en laclase.El curso es eminentemente práctico y se desarrolla íntegramente en laboratorio.En primer lugar, se inicia con el reconocimiento de los principales patrones dearquitectura de software, destacándose el patrón Model View Controller (MVC).Luego, continúa con la presentación del Framework MVC Struts 2. Se profundizaen sus principales características y componentes. Después, se desarrollanconceptos de persistencia de datos utilizando para ello el Framework IBATIS.Por último, se concluye con la elaboración de reportes empresariales, utilizandola herramienta IReport, el lenguaje jasperReport e integrándolos a aplicacionesweb creadas con Struts 2.CIBERTEC CARRERAS PROFESIONALES
  6. 6. 6 RED DE CONTENIDOS Desarrollo de Aplicaciones Web 1 Modelo Vista Persistencia de Reportes en Controlador – datos – sistemas Patrón MVC Framework empresariales IBATISFundame Otras Introducción Otras Tema 5 Tema 6 ntos de Características a IBATIS operaciones JasperReport Struts 2 y Struts 2 Struts 2 IBATIS Jasper CARRERAS PROFESIONALES CIBERTEC
  7. 7. DESARROLLO DE APLICACIONES WEB I 7 UNIDAD DE APRENDIZAJE 1MODELO VISTA CONTROLADOR – PATRÓN MVCLOGRO DE LA UNIDAD DE APRENDIZAJE • Al finalizar la unidad, el alumno, utilizando el framework MVC STRUTS 2, implementa una aplicación web que contenga, en su estructura, el componente Action, las principales etiquetas del framework y acceso a base de datos a través 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.TEMARIO1.1 Tema 1 : Fundamentos de Struts 2 1.1.1. : Arquitectura y Configuración de aplicaciones 1.1.2. : La clase Action 1.1.3. : Librerías de etiquetas de Struts 2 1.1.4. : Internacionalización – I18N1.2 Tema 2 : Acceso optimizado a base de datos y otras características de Struts 2 1.2.1. : Uso de un Pool de conexiones para acceso a la fuente de datos 1.2.2. : Librería de Etiquetas de Struts 2 – Principales componentes. 1.2.3. : Patrón Composite View – Struts 2 TilesACTIVIDADES PROPUESTAS • Los alumnos implementan una aplicación web básica, utilizando las principales características del framework MVC Struts 2.1.1 Fundamentos de Struts 2CIBERTEC CARRERAS PROFESIONALES
  8. 8. 8 Struts 2 es un framework que implementa el patrón 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 aplicación. Se muestra, a continuación, el esquema básico de funcionamiento de esta arquitectura. La capa Model en Struts 2 inicia con los componentes Action. Debajo de éstos, se tendrán diversos componentes: Services (Lógica pura de negocio) DAOs (objetos de persistencia de datos), entre otros. Se muestra, a continuación, el esquema básico de la arquitectura MVC implementado por el framework Struts 2. Figura 1.1 Una característica típica de la capa View de Struts 2 es el uso de unos componentes especiales denominados Results. Éstos normalmente son representados por una página JSP; sin embargo, puede constituir, también, flujos de bytes, objetos del framework Tiles, etc. 1.1.1. Arquitectura y configuración de aplicaciones La arquitectura MVC funciona en Struts 2 básicamente de la siguiente manera: a través 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 configuración XML de Struts 2. Éste tiene por defecto el nombre struts.xml.CARRERAS PROFESIONALES CIBERTEC
  9. 9. DESARROLLO DE APLICACIONES WEB I 9 El componente invocado, normalmente un Action de Struts 2, instanciará y/o utilizará diversos objetos de negocio para concretar la tarea solicitada. Según el resultado que retorne el componente Action, la capa Controller derivará la respuesta generada a un objeto Result (normalmente una página JSP). 1.1.1.1. Ejercicio 1: Aplicación web básica de Struts 2 Se probará una aplicación web con los componentes mínimos 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 aplicación web de prueba, que cuenta con las características mínimas para que pueda ser ejecutada. Esta aplicación 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 continuación: 1 2 Notas: 1) El principal archivo de configuración del Framework es el archivo struts.xml. En él, se registrarán sus principalesCIBERTEC CARRERAS PROFESIONALES
  10. 10. 10 componentes. Se inicia esta sesión con el registro de la clase Action. 2) Puede observar las librerías mínimas con las que todo proyecto basado en Struts 2 debería 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/j2eehttp://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 1 </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 aplicaciónCARRERAS PROFESIONALES CIBERTEC
  11. 11. DESARROLLO DE APLICACIONES WEB I 11 d) Paso 4: ¡Excelente!, ha culminado el proceso de probar exitosamente la aplicación web struts2-blank-2.1.8.1 1.1.2. La clase ActionCIBERTEC CARRERAS PROFESIONALES
  12. 12. 12 Un action es, en Struts 2, el primer componente de la capa Model dentro de la arquitectura MVC. Un actions realiza básicamente tres pasos dentro de una aplicación web. En primer lugar, recibe las solicitudes (request) enviadas por un cliente y realiza el trabajo inicial para atenderla. Es el componente que interactúa con la capa controladora y la capa view. En segundo lugar, actúa como un transportador natural de datos entre el objeto request y los componentes de la capa view, esto gracias a las características de transferencia automática 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 continuación, un ejercicio, en el cual se apreciarán los principales componentes de la arquitectura MVC utilizando Struts 2. 1.1.2.1. Ejercicio 1: Funcionalidad de Logueo Versión 1 Se simulará la funcionalidad de logueo con los componentes básicos del framework Struts 2 y sin acceso a base de datos. a) Paso 1: Copiar las principales librerías y archivos de configuración al proyecto web funcionalidadLogueov1_Inicial 1 2CARRERAS PROFESIONALES CIBERTEC
  13. 13. 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 librerías y archivos de configuración en las ubicaciones correctas: librerías en la carpeta lib y archivo de configuración 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 aplicación, la clase LogueoAction 1 Notas: 1) Agregue el paquete aprendamos.java.action y, dentro de él, genere la clase LogueoAction. La clase LogueoAction debe contar con la siguiente lógica: CIBERTEC CARRERAS PROFESIONALES
  14. 14. 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" >/logueo.jsp </result> <result name="exito" >/bienvenida.jsp </result> </action> </package> 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
  15. 15. DESARROLLO DE APLICACIONES WEB I 15 e) Paso 5: Ejecutar la aplicación 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 versión 1 1.1.2.2. Ejercicio 2: Funcionalidad de Logueo Versión 2 Se efectúa la funcionalidad de logueo con los componentes básicos del framework e implementando los patrones de diseño DAO (Data Access Object), Service y Business Delegate. a) Paso 1: Modificar la clase MySqlClienteDAO y verificar su correcta relación con las clases que implementan el patrón de diseño DAO.CIBERTEC CARRERAS PROFESIONALES
  16. 16. 16 Dentro de la clase MySqlClienteDAO, debe modificar el método buscaPorUsuario. Complete el código con la lógica mostrada a continuación: //ejecutamos ResultSet rs=pst.executeQuery(); //si hay datos, recuperamos un regsitro if(rs.next()){ objClienteDTO = new ClienteDTO(); objClienteDTO.setUsuario(rs.getString(1)); objClienteDTO.setClave(rs.getString(2)); objClienteDTO.setNombre(rs.getString(3)); objClienteDTO.setSueldo(rs.getDouble(4)); objClienteDTO.setSexo(rs.getString(5)); objClienteDTO.setFecnac(rs.getDate(6)); } cn.close(); El patrón de diseño DAO (Data Access Object) permite que un componente pueda acceder a diferentes orígenes 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 podrían contar con DAOs para acceder a otros orígenes de datos, tales como Oracle, Microsoft SQL Server, archivos XML, etc. Por cada entidad dentro del modelo de datos, se debe crear un componente DAO. Verifique si existe la interface ClienteDAO. Ésta debe ser implementada por la clase MySqlClienteDAO: public interface ClienteDAO { public int registraCliente(ClienteDTO objCliente) throws Exception; public ClienteDTO buscaPorUsuario(String usuario) throws Exception; . . . }CARRERAS PROFESIONALES CIBERTEC
  17. 17. DESARROLLO DE APLICACIONES WEB I 17 Una interface permite exponer “al mundo” las operaciones de la clase que la implementa. Verifique si MySqlClienteDAO es retornado por la fábrica 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 “fábrica de fábricas” DAOFactory:  public abstract class DAOFactory { public static final int MYSQL = 1; public static final int ORACLE = 2; public static final int DB2 = 3; public static final int SQLSERVER = 4; public static final int XML = 5; 1 // Existirá un método 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. 18. 18 Notas: 1) El registro de la clase MySqlClienteDAO es la creación de un método 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 1 2public 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
  19. 19. 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 patrón de diseño MVC. Representa, en la programación, el inicio de la lógica de negocio. Por cada caso de uso de sistema identificado en la aplicación, se debe implementar un servicio. Éste puede invocar a uno o más 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 1CIBERTEC CARRERAS PROFESIONALES
  20. 20. 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 análisis, 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 lógica de negocio, desde la clase LogueoService, y crear la sesión web. Genere, dentro de la clase LogueoAction, el atributo mensaje para poder visualizar posibles “mensajes de error” en la capa de presentación. No debe olvidar crear los métodos 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
  21. 21. DESARROLLO DE APLICACIONES WEB I 21 Agregue la lógica que permitirá validar los datos ingresados y almacenarlos en la sesión 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 esincorrecta"); } }else{ vista="error"; this.setMensaje("Es una pena, el usuario no existe!"); } return vista; } CIBERTEC CARRERAS PROFESIONALES
  22. 22. 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 sesión web.  <tr>   <td class="error general">   <!-- podemos visualizar el mensaje de error usando EL -->   ${requestScope.mensaje}   </td>  </tr>   e) Paso 5: Ejecutar la aplicación Primero, ingrese un usuario inválido.CARRERAS PROFESIONALES CIBERTEC
  23. 23. 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 versión 2CIBERTEC CARRERAS PROFESIONALES
  24. 24. 24 1.1.3. Librerías de etiquetas de Struts 2 1.1.3.1. Ejercicio 1: Funcionalidad de Logueo Versión 3 Agregue una nueva funcionalidad al logueo implementado, a través del uso de archivos de recursos y nuevas características 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 través de la key struts.custom.i18n.resources, se define la ubicación 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
  25. 25. 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 método 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. 26. 26 d) Paso 4: Modificar el JSP logueo.jsp Debe referenciar a la librería 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
  27. 27. DESARROLLO DE APLICACIONES WEB I 27 Note que se han modificado los nombres de los campos usuario y clave por cliente.usuario y cliente.clave. e) Paso 5: Referenciar a los campos cliente.usuario y cliente.clave dentro de la clase LogueoAction Agregue el atributo cliente en la clase LogueoAction. public class LogueoAction extends ActionSupport { private ClienteDTO cliente=null; public ClienteDTO getCliente() { return cliente; } public void setCliente(ClienteDTO cliente) { this.cliente = cliente; } Modifique el método execute. public String execute(){ String vista="exito"; System.out.println("dentro de nuestro primer action"); 1 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 = 2 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. 28. 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 método getCliente(). f) Paso 6: Ejecutar la aplicación Primero, ingrese un usuario inválido. Luego, ingrese el usuario correcto, pero la clave equivocada. Por último, ingrese los datos correctamente.CARRERAS PROFESIONALES CIBERTEC
  29. 29. DESARROLLO DE APLICACIONES WEB I 29 g) Paso 7: ¡Muy buen trabajo!CIBERTEC CARRERAS PROFESIONALES
  30. 30. 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 través de un formulario HTML y gestionarlos dentro de la aplicación web implementada. a) Paso 1: Importar el proyecto web FuncionalidadRegistraImagen_Inicial.war 1 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
  31. 31. DESARROLLO DE APLICACIONES WEB I 31 b) Paso 2: Verificar que la tabla tbcliente cuente con un campo de tipo longblogCREATE DATABASE IF NOT EXISTS facilito;USE facilito;---- Definition of table `tbcliente`--DROP TABLE IF EXISTS `tbcliente`; 1CREATE 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 DEFAULTCHARSET=latin1; Notas: 1) Observe que, en el campo “foto”, se almacenará la imagen asociada al cliente que registrará en su aplicación web. CIBERTEC CARRERAS PROFESIONALES
  32. 32. 32 c) Paso 3: Modificar el archivo nuevoCliente.jsp Dentro de la página nuevoCliente.jsp, se debe modificar el formulario HTML. Complete el código con la lógica mostrada a continuación:<s:form action="ingresaCliente" 1 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> Fotografía: </td> 2 <td> <s:file name="cliente.foto" /> </td> </tr> <tr class="control" > <td align="right" > <input type="submit" name="boton01" value="Registrar" > </td> </tr> </table></s:form> 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
  33. 33. DESARROLLO DE APLICACIONES WEB I 33 d) Paso 4: Registrar el alias ingresaCliente en el archivo struts.xml<action name="ingresaCliente" 1 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 página nuevoCliente.jsp. Note que al invocar este alias se ejecutará dentro de la clase ClienteAction el método registrar. e) Paso 5: Crear el método registrar en la clase ClienteAction La clase ClienteAction debe contar con la siguiente lógica: package aprendamos.java.action; import java.util.List; import aprendamos.java.bean.ClienteDTO; import aprendamos.java.service.ClienteService_I; 1 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. 34. 34...ClienteService_I servicioCliente = 2 PaqueteBusinessDelegate.getClienteService(); // creamos el metodo registra public String registra(){ 3 String vista="exito"; try { 4 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 automática, el Framework instancia el objeto y almacena en él los datos que llegan desde la página nuevoCliente.jsp. Note que en la página 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 lógica de negocio y expone las operaciones que puede realizar la clase ClienteAction. 3) Note que el método registraCliente recibe como parámetro el objeto cliente. Dentro de él, deben existir los campos necesarios para poder gestionar la imagen del cliente seleccionada en la página 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
  35. 35. DESARROLLO DE APLICACIONES WEB I 35 f) Paso 6: Modificar la clase ClienteDTO La clase ClienteDTO debe contar con la siguiente lógica: public class ClienteDTO implements Serializable { private static final long serialVersionUID = 1L; private String nombre; 1 private Date fecnac; private String sexo; private double sueldo; 2 private String usuario; private 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 página 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, también, por requerimiento del Framework, definir los campos fotoContentType y fotoFileName. Ambos se “cargarán” de manera automática y proporcionarán importante información 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. 36. 36 g) Paso 7: Modificar la clase ClienteService La clase ClienteService debe contar con la siguiente lógica en el método 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){ 1 InputStream tempo = new FileInputStream(objCliente.getFoto()); objCliente.setIsFoto(tempo); } return objClienteDAO.registraCliente(objCliente); } Notas: 1) Si el cliente seleccionó en la página nuevoCliente.jsp una imagen, el atributo foto debe ser diferente del valor null. De ser el caso, se crea un objeto temporal de tipo InputStream en base al atributo foto. Luego, se asigna el objeto tempo al atributo isFoto (utilizado en la clase MySqlClienteDAO para grabar la imagen en la tabla tbcliente). Recuerde que el método registraElCliente debe ser “expuesto” registrándolo en la interface ClienteService_I. La clase ClienteService implementa la interface ClienteService_I. CARRERAS PROFESIONALES CIBERTEC
  37. 37. DESARROLLO DE APLICACIONES WEB I 37 h) Paso 8: Modificar la clase MySqlClienteDAO La clase MySqlClienteDAO debe implementar la siguiente lógica en el método 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); 1 // asignamos valores a las interrogantes pst.setString(1, objCliente.getNombre()); pst.setDouble(2, objCliente.getSueldo()); pst.setString(3, objCliente.getSexo()); 2 // 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. 38. 38 pst.setBinaryStream(7, null,0); Sin embargo, si el valor del atributo es diferente de null, registra la imagen, tomando como base al atributo de tipo InputStream isFoto: pst.setBinaryStream(7, objCliente.getIsFoto(), objCliente.getIsFoto().available()); El método available() de un objeto de tipo InputStream retorna la cantidad de bytes (el tamaño), en este caso, de la imagen a insertar en la tabla. De esta manera, se envía como tercer parámetro del método setBinaryStream().CARRERAS PROFESIONALES CIBERTEC
  39. 39. DESARROLLO DE APLICACIONES WEB I 39 i) Paso 9: Ejecutar la aplicación web Seleccione del listado de Clientes el enlace Nuevo Cliente:CIBERTEC CARRERAS PROFESIONALES
  40. 40. 40 En la pantalla mostrada, ingrese los campos solicitados.CARRERAS PROFESIONALES CIBERTEC
  41. 41. DESARROLLO DE APLICACIONES WEB I 41 Al hacer clic sobre el botón Registrar, se grabará un nuevo registro en la base de datos y se visualizará nuevamente el listado de Clientes.CIBERTEC CARRERAS PROFESIONALES
  42. 42. 42 Se puede verificar el correcto registro de la imagen, utilizando la herramienta MySql Query Browser: 1 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
  43. 43. DESARROLLO DE APLICACIONES WEB I 43 1.1.4. Internacionalización – I18n Tradicionalmente, los desarrolladores de software se centran en construir aplicaciones que resuelvan en forma inmediata problemas de negocio. Mientras hacen eso es fácil y a veces necesario realizar asunciones acerca del lenguaje o lugar de residencia de los usuarios. En muchos casos, estas asunciones son válidas y no hay preguntas sobre quién será la audiencia. Sin embargo, es probable, alguna vez, que se deba reconstruir una aplicación, porque estas asunciones fueron incorrectas. Internacionalización (I18N) es el proceso de diseñar su software con soporte en tiempo real de múltiples lenguajes y regiones. Dada esta característica, no será necesario rediseñar nuestras aplicaciones cada vez que se necesite soporte para un nuevo lenguaje. Una aplicación que dice tener soporte para internacionalización debe contar con las siguientes características: • Puede soportar lenguajes adicionales sin requerir cambios adicionales de código. • Los elementos de texto, mensajes e imágenes son almacenados externamente al código fuente. • Dependencia culturales de datos, tales como fecha y hora, y valores decimales son correctamente formateados para el lenguaje del usuario y localización geográfica. • Caracteres no estándares son soportados. • La aplicación puede ser fácilmente adaptada a nuevos lenguajes y regiones. Cuando se internacionaliza una aplicación, 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, imágenes y botones están en el lenguaje correcto, pero los números y fechas no son formateados correctamente, ésta será una experiencia desagradable para el usuario. Asegurar que una aplicación puede soportar múltiples lenguajes y regiones solo es el primer paso. Se deben crear versiones localizadas de la aplicación para cada lenguaje específico y región que debe soportar. Afortunadamente, aquí es donde los beneficios de I18N en la plataforma java se ejecutan. Para aplicaciones que están siendo apropiadamente internacionalizadas, todo el trabajo para soportar nuevos lenguajes o naciones, son externas al código fuente. Una clase locale es una región (usualmente geográfica, pero no necesariamente) que comparte personalizaciones, cultura y lenguaje. Aplicaciones que son escritas para una sola localización son comúnmente referenciadas como miopes. Localización (L10N) es el proceso de adaptar su aplicación, la cual ha sido internacionalizada apropiadamente con la específica. Para aplicaciones donde el soporte I18N no ha sido planeado o incorporado, esto usualmente significa cambios de texto, imágenes y mensajes que son incluidos dentroCIBERTEC CARRERAS PROFESIONALES
  44. 44. 44 del código fuente. Después de los cambios aplicados, éste debe de ser recopilado. Imagine hacer eso cada vez para una nueva localización soportada. De acuerdo con Richard Gillam, miembro del Grupo de Tecnología Unicote (autor del diseño de muchas de las librerías Java para soporte I18N), los usuarios esperarán que los productos que utilizan trabajen para ellos en su lenguaje nativo. Se pueden obtener experiencias negativas si los usuarios no están 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 imágenes implementado. La aplicación web soportará el uso de tres idiomas distintos. a) Paso 1: Importar el proyecto web FuncionalidadRegistraImagenI18N_Inicial.war 1 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 losCARRERAS PROFESIONALES CIBERTEC
  45. 45. DESARROLLO DE APLICACIONES WEB I 45 idiomas italiano (it), portugués (pt) y español. 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 códigos ISO 639-1. b) Paso 2: Editar los archivos .properties. Se crearán, como ejemplos, las keys que serán utilizadas en la página bienvenida.jsp. Defina las keys para el idioma portugués en el archivo MisRecursos_pt.properties#keys para la pagina de bienvenidakey.usuario = Usuário:key.nombre = Nome:key.fecnac = data de nascimento:key.sexo = sexo:key.saludo = Bem-vindo Caro usuário, seus dados são:#keys para el menumenu.bienvenida = Ir à página inicialmenu.logueo = Vá para a entradamenu.listado = Ir para a lista CIBERTEC CARRERAS PROFESIONALES
  46. 46. 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 español en el archivo MisRecursos.properties (archivo de recursos por defecto). 1 #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 página de Bienvenida menu.logueo = Ir al logueo menu.listado = Ir al listadoCARRERAS PROFESIONALES CIBERTEC
  47. 47. DESARROLLO DE APLICACIONES WEB I 47 Notas: 1) El archivo de recursos por defecto es aquel que no tiene código ISO asociado a un idioma en particular. Cuando se seleccione en la aplicación web un idioma que no haya sido configurado en ningún archivo de recursos, automáticamente, 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> <ahref="${pageContext.request.contextPath}/a_bienvenida?request_locale=it"> <imgsrc="imagenes/banderaItalia.png" alt="Italiana" border="0"> </a> 1 </td> <td><ahref="${pageContext.request.contextPath}/a_bienvenida?request_locale=pt"> <imgsrc="imagenes/BanderaBrasil.png" alt="Portugues" border="0"> </a> 2 </td> <td><ahref="${pageContext.request.contextPath}/a_bienvenida?request_locale=es"> <img src="imagenes/banderaPeru.png"alt="Español" border="0"> </a> </td> </tr> </table></body> Notas: 1) Struts 2 soporta cuenta con un parámetro especial llamado request_locale. Cuando se utiliza éste, de manera automática, se configura sul valor como el idioma actual de la aplicación web. 2) Es recomendable utilizar variables al referenciar cualquier recurso dentro de una aplicación web. En el ejemplo, en CIBERTEC CARRERAS PROFESIONALES
  48. 48. 48 lugar de colocar el nombre de la aplicación 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="struts- default"> 1 <action name="a_bienvenida" > <result > /bienvenida.jsp </result> </action> <action name="a_logueo" > <result > /logueo.jsp 1 </result> </action> . . . Notas: 1) Note que el action a_bienvenida es solo un action de atajo que invoca automáticamente a la página bienvenida.jsp. Se puede crear dentro de la aplicación múltiples actions de atajo para invocar a través de links a las páginas JSP. e) Paso 5: Recuperar las keys del menú y de la página de bienvenida, utilizando la etiqueta <s:text> de struts 2.CARRERAS PROFESIONALES CIBERTEC
  49. 49. 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" > 1 <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 librería, utilizando la siguiente directiva: <%@ taglib prefix="s" uri="/struts-tags" %>CIBERTEC CARRERAS PROFESIONALES
  50. 50. 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
  51. 51. DESARROLLO DE APLICACIONES WEB I 51 f) Paso 6: Ejecutar la aplicación web Ingrese a la intranet a través de la página de logueo. Se debe visualizar la pantalla de bienvenida y los enlaces a los idiomas definidos en la página cabecera.jsp. Seleccione la bandera italiana.CIBERTEC CARRERAS PROFESIONALES
  52. 52. 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 portugués. Finalmente, seleccione la bandera del Perú.CARRERAS PROFESIONALES CIBERTEC
  53. 53. 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. 54. 541.2 Acceso optimizado a base de datos y otras característicasStruts 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 serán "prestadas" a los threads (hilos) de ejecución 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 análisis es el mismo. El recurso es la conexión 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 web FuncionalidadRegistraImagenPool_Inicial.warCARRERAS PROFESIONALES CIBERTEC
  55. 55. DESARROLLO DE APLICACIONES WEB I 55 1 Notas: 1) Observe que, dentro del proyecto, cuenta en la carpeta META-INF con el archivo context.xml. En él, se debe crear la configuración del pool de conexiones que utilizará para acceder a una base de datos.CIBERTEC CARRERAS PROFESIONALES
  56. 56. 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 creacuando 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 estecaso un pool de conexiones --> 1 <Resource name="jdbc/sisepuede" 2 auth="Container" type="javax.sql.DataSource" maxActive="100" 3 maxIdle="30" maxWait="10000" username="root" password="" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/facilito"/></Context> Notas: 1) jdbc/sisepuede es el nombre del pool de conexiones que utilizará para referenciar a la base de datos. 2) El número máximo de conexiones activas es 100 en el ejemplo. Este valor debe ser calculado para cada aplicación web sobre la base de la “experiencia” y el tráfico que normalmente se soporte. En algunos casos, se tendrá la necesidad de incrementar o redecir este valor por defecto. 3) El máximo tiempo de espera, 10000, está expresado en milisegundos. En este ejemplo, se esperará, como máximo, 10 segundos para obtener una conexión disponible (de las 100 existentes). De no conseguirla, se produciría un error.CARRERAS PROFESIONALES CIBERTEC
  57. 57. DESARROLLO DE APLICACIONES WEB I 57 c) Paso 3: Modificar el archivo MySqlDbConn.javapackage aprendamos.java.util;// Esta clase nos retornara una conexion a base de datosimport java.sql.*; 1import javax.naming.*;import javax.sql.*; 2public 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. 58. 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 , utilizala infor de META INF para hacer un pool de conexiones., JNDI manejanombres 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/"; 1 // obtenemos a traves de su nombre a nuestro // pool de conexiones DataSource ds= (DataSource)ctx.lookup(raizContexto+"jdbc/sisepuede"); 2 // le pedimos al pool que nos de una conexion cn = ds.getConnection(); System.out.println( "Mision cumplida, hemos obtenido la conexion delpool"); } 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 raíz. Por lo tanto, para referenciar al pool, se pasar primero por el nombre raíz. 2) A través del método lookup y utilizando el nombre raíz del contexto, se referencia al pool de conexiones: jdbc/sisepuede. CARRERAS PROFESIONALES CIBERTEC
  59. 59. 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 1 Notas: 1) Este paso es necesario debido a que es el servidor Tomcat y no la aplicación web, quien solicita al servidor de base de datos las conexiones (en el ejemplo cien), que serán almacenadas en la memoria del servidor y que juntas constituyen el pool de conexiones.CIBERTEC CARRERAS PROFESIONALES
  60. 60. 60 e) Paso 5: Ejecutar la aplicación web Ingrese a la intranet a través de la página de logueo.CARRERAS PROFESIONALES CIBERTEC
  61. 61. DESARROLLO DE APLICACIONES WEB I 61 Debe visualizar la pantalla de bienvenida con los datos del usuario logueado. También, se visualizará en la consola de Eclipse los mensajes del Logueo y el que se colocó en la clase MySqlDbConn: misión cumplida, se ha obtenido la conexión del pool.CIBERTEC CARRERAS PROFESIONALES
  62. 62. 62 f) Paso 6: ¡Bien!, ha culminado la funcionalidad “registra imagen pool” exitosamente.CARRERAS PROFESIONALES CIBERTEC
  63. 63. DESARROLLO DE APLICACIONES WEB I 63 1.2.2. Librerías de etiquetas de Struts 2. Principales componentes Dentro de la familia de nuevas etiquetas de Struts 2, es importante destacar que, en esta versión, todas las etiquetas básicas del framework se encuentran en una sola librería, la cual es referenciada en un JSP de la siguiente manera: <%@ taglib prefix="s" uri="/struts-tags" %> Se detalla, a continuación, ejercicios de aplicación en los que se utilizan las principales etiquetas de Interface de usuario y datos de Struts 2: <s:url> <s:action> <s:form> 1.2.2.1. Ejercicio 2: Funcionalidad carga datos del Cliente Se implementa la funcionalidad indicada haciendo uso de las utilidades incluidas en el Framework para procesar archivos (en el ejemplo la imagen del cliente) a través 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 1CIBERTEC CARRERAS PROFESIONALES
  64. 64. 64 Notas: 1) Debe modificar la página 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 página listado.jsp, debe crear un nuevo enlace para visualizar los datos del cliente seleccionado. Complete el código con la lógica mostrada a continuación:. . . <td align="center" > 1 <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
  65. 65. DESARROLLO DE APLICACIONES WEB I 65 2 Notas: 1) Utilizando la etiqueta <s:url > defina un enlace que permitirá invocar al alias cargaModificaCliente. Adicionalmente, determine el parámetro 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. 66. 66 c) Paso 3: Registrar el alias cargaModificaCliente en el archivo struts.xml<action name="cargaModificaCliente" 1 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 página listado.jsp. Note que al invocar este alias se ejecutará dentro de la clase ClienteAction el método cargaModifica. d) Paso 4: Crear el método cargaModifica en la clase ClienteAction La clase ClienteAction debe contar con la siguiente lógica: package aprendamos.java.action; import java.util.List; import aprendamos.java.bean.ClienteDTO; import aprendamos.java.service.ClienteService_I; import aprendamos.java.service.PaqueteBusinessDelegate; 1 public class ClienteAction { // creamos un atributo de tipo Lista de Clientes ClienteDTO cliente; List<ClienteDTO> clientes; String usuario; ... CARRERAS PROFESIONALES CIBERTEC
  67. 67. DESARROLLO DE APLICACIONES WEB I 67... public String cargaModifica(){ String vista="exito"; try { 2 cliente= servicioCliente.buscaClientePorUsuario( this.getUsuario()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return vista; } 3... Notas: 1) Se ha definido la variable usuario de tipo String. Se definen también los métodos setUsuario() y getUsuario(), respectivamente. De manera automática, el Framework instancia el objeto y almacena en éste el parámetro usuario, que llega desde la página listado.jsp. . 2) Note que el método buscaClientePorUsuario recibe como parámetro 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 página modificaCliente.jsp CIBERTEC CARRERAS PROFESIONALES
  68. 68. 68 e) Paso 5: Verificar la clase MySqlClienteDAO La clase MySqlClienteDAO debe implementar la siguiente lógica en el método buscaPorUsuario:public ClienteDTO buscaPorUsuario(String usuario) throws Exception{ ClienteDTO objClienteDTO=null; 1 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 2 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 método getBinaryStream del objeto ResultSet rs: rs.getBinaryStream(7) CARRERAS PROFESIONALES CIBERTEC
  69. 69. DESARROLLO DE APLICACIONES WEB I 69 f) Paso 6: Ejecutar la aplicación web Seleccione del listado de Clientes el enlace M asociado a cualquiera de los clientes listados: 1 Notas: 1) Enlace para visualizar los datos del cliente y, opcionalmente, modificarlos.CIBERTEC CARRERAS PROFESIONALES
  70. 70. 70 En la pantalla mostrada, se visualizarán los datos asociados al cliente seleccionado. Sin embargo, no reconoce aún la fotografía. g) Paso 7: ¡Bien!, ha culminado la primera parte de la funcionalidad “carga imagen”CARRERAS PROFESIONALES CIBERTEC
  71. 71. DESARROLLO DE APLICACIONES WEB I 71 h) Paso 8: Modificar la página modificaCliente.jsp Dentro de la página modificaCliente.jsp debe utilizar la etiqueta HTML <img> para visualizar la fotografía asociada al cliente mostrado:. . .<tr class="control" > <td> Fotografía: </td> <td> <s:file name="cliente.foto" /> </td> <td> <img alt="Fotografia del Cliente:) " 1 src="cargaImagenCliente?usuario=${cliente.usuario}" /> </td></tr>. . . Notas: 1) Note cómo en el atributo src de la etiqueta <img> se hace referencia al alias cargaImagenCliente. Se envía adicionalmente el parámetro usuario con el valor ${cliente.usuario}. CIBERTEC CARRERAS PROFESIONALES

×