Aplicaciones Web I
DESARROLLO DE APLICACIONES WEB I 2
Índice Página
Presentación 5
Red de contenidos 7
Unidad de aprendizaje 1
FRAMEWORK MVC - STRUTS 2
Unidad de aprendizaje 2
FRAMEWORK DE PERSISTENCIA – MYBATIS
2.1 Tema 3 : Fundamentos 127
2.1.1. : Arquitectura y Configuración 128
2.1.2. : Mappers 148
2.1.3. : XML Mapped Statements 150
2.1.4. : Annotated Mapped Statements 161
2.1.5. : Otras configuraciones 167
2.2 Tema 4 : Proyecto Plantilla 176
2.2.1. : Aplicación Web 176
Unidad de aprendizaje 3
REPORTES CON JASPER
3.1 Tema 5 : Jasper Reports 189
Presentación
Red de contenidos
UNIDAD
1
FRAMEWORK MVC – STRUTS 2
LOGRO 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, así como las principales etiquetas, librerías y plugins del Framework.
TEMARIO
1.1 Tema 1 : Fundamentos
1.1.1. : Arquitectura
1.1.2. : Configuración básica
1.1.3. : Actions
1.1.4. : Tag Libraries
1.1.5. : Result Types
1.1.6. : Interceptores
1.1.7. : Internacionalización – I18N
1.1.8. : Validaciones
1.1.9. : Otros elementos de configuración
1.1.10 : Tiles
1.2 Tema 2 : Proyecto Plantilla
1.2.1 : Aplicación Web de 3 capas
ACTIVIDADES PROPUESTAS
1.1 FUNDAMENTOS
Framework open source, desarrollado por Apache Software Foundation, permite a los
desarrolladores crear Aplicaciones Web basadas en MVC. Éste organiza de manera
independiente las capas: Model (Objetos del Modelo de la Aplicación), View (interfaz
con el usuario u otro sistema) y la capa Controller (controlador del flujo de la
aplicación).
PÁGINA OFICIAL
http://struts.apache.org
PRE-REQUISITOS
http://struts.apache.org/primer.html
Versiones
Struts 1 (2001)
Struts 1 fue el Framework MVC estándar en la construcción de
aplicaciones Java Web por muchos años.
Struts 2
Struts 2 es un Framework que combina las mejores características de
Struts 1 y WebWork (xWork) simplificando aún más la tarea de los
desarrolladores. Uno de sus objetivos es definir las características base del
Framework en struts-core y todos los demás complementos en plugins
reduciendo, así, las dependencias con terceros.
RELEASE 2.3.X
http://struts.apache.org/release/2.3.x/index.html
1.1.1 Arquitectura
FUENTE DE IMAGEN:
http://struts.apache.org/release/2.3.x/docs/big-picture.html
LABORATORIO 1
a. Filtros
o FilterDispatcher
Ejecuta métodos de preparación (de estar implementado) y
procesamiento en Action.
Limpia Action Context.
Asegura disponibilidad de contenido estático (css, js)
Este filtro tiene estado Deprecated y fue utilizado hasta la
versión 2.1.2
o StrutsPrepareAndExecuteFilter
Prepara y ejecuta el procesamiento solicitado.
Se utilizar cuando no se requieren filtros adicionales para
uso de plugins que requieran acceder al Action Context, por
ejemplo Sitemesh.
Se utiliza a partir de la versión 2.1.3, en reemplazo del
FilterDispatcher.
o StrutsPrepareFilter
Prepara el procesamiento solicitado.
Usa interceptor “prepare” que ejecuta método prepare() de
Action en caso se implemente interfaz Preparable.
Se utiliza a partir de la versión 2.1.3.
o StrutsExecuteFilter
Ejecuta el procesamiento solicitado invocando un método del
Action.
Requiere que, previamente, se haya ejecutado el filtro
StrutsPrepareFilter.
b. Interceptores
Los interceptores son Clases que actúan de manera similar a los ServletFilters, pues
se encargan de interceptar los request enviados a un Action ejecutando lógica común
en las aplicaciones, por ejemplo validaciones de campos, i18n, manejo de
excepciones, carga de archivos, uso de token, logging, etc.
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/interceptors.html
c. Action
Action es una Clase de Java que tiene implementado uno o más métodos de
procesamiento (típicamente uno por cada request), para lo cual recibe parámetros y/o
devuelve datos del modelo, e invoca componentes de negocio. Al finalizar la ejecución,
retorna un String que representa un objeto Result.
d. Results
Results indica qué recurso debe invocarse, por ejemplo JSP, Freemarker, Velocity,
etc; de modo que se genere la vista con la respuesta al cliente.
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/result-types.html
e. Tags y Templates
Struts tiene definidos Tags que permiten generar contenido estático/dinámico, así
como manipular/evaluar objetos en memoria.
Los templates pueden hacer uso de uno o más Tags siempre que lo soporte.
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/tag-developers-guide.html
f. Action Proxy
Action Proxy obtiene instancia del Action y la información del método a ejecutar. Al
utilizar el ActionInvocation, se encapsula la ejecución de un request.
g. Action Invocation
REFERENCIA
http://struts.apache.org/release/2.3.x/xwork-core/apidocs/
http://struts.apache.org/release/2.3.x/struts2-core/apidocs/
a. Action Context
Dicho contexto es representado por una Clase del mismo nombre “ActionContext”
que se instancia ante cada request. El ActionContext es ThreadSafe, pues utiliza la
Clase ThreadLocal, es decir, su instancia es única por cada hilo de ejecución.
El acceso a dicho objeto se puede dar en Clases Action con la siguiente instrucción:
ActionContext.getContext()
b. Value Stack
Value Stack es parte del ActionContext y, dentro de él, reside la instancia del Action
que está en ejecución. Se le conoce como pila, pues puede almacenar objetos en el
siguiente orden:
ActionContext.getContext().getValueStack()
Al invocar un objeto del Value Stack, Struts tomará la primera ocurrencia que
encuentre, por lo cual, si hay dos objetos con el mismo nombre en diferentes niveles,
el Framework puede tomar un objeto incorrecto. Por ello, es importante conocer y
tener en cuenta la profundidad en que están colocados los objetos en la pila para, de
ser necesario, acceder directamente a ellos indicando en la expresión dicha
profundidad.
c. OGNL
- #session.username
- #application.estados
- #attr.indice
Filtros
TLD (no es requerido)
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/webxml.html
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/struts-defaultxml.html
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/strutsproperties.html
Elementos
a. Bean
Para manejo de IoC de objetos principales del marco de trabajo
Struts 2, por ejemplo ActionMappers.
b. Constante
Para personalizar la configuración base del Framework.
c. Package
Agrupa elementos que gestionan el Request, que son los siguientes:
Interceptors
Actions
Result Types
Global Exceptions
Global Results
Default Action
Default Interceptor stack
Principales ventajas:
Reutilización de configuración
Modularización de la aplicación
d. Include
Permite incluir archivos de configuración adicionales que cumplan
con el mismo formato de Strust.xml. Se manejan varios archivos de
configuración para organizar diferentes módulos de una aplicación.
LABORATORIO 2
a. Prototipos:
b. Pasos a seguir:
Siga los pasos del Wizard considerando los valores mostrados en las imágenes:
<struts>
</package>
</struts>
Formulario.jsp
Resultado.jsp
Entonces:
Dado que son variables que recibirán valores desde el formulario, se debe definir
método setter por cada una de ellas.
Dado que son variables cuyos valores se utilizarán en la vista, se debe definir método
getter por cada una de ellas.
Strust.xml
Para que el formulario invoque al Action, debe especificar, en el atributo action del
form, el nombre del ActionMapping:
Formulario.jsp
Para que se muestre la página Resultado.jsp, debe indicarlo en uno de los results del
Action Mapping:
Strust.xml
En la página Resultado.jsp, debe mostrar los valores de las variables de salida del
Action.
Para poder acceder a dichas variables desde el JSP, debe utilizar el tag <s:property>,
según lo subrayado:
Resultado.jsp
12. Finalmente, para poder realizar la prueba, no olvide definir el welcome file
en web.xml.
VendedorAction
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.logger.com.opensymphony.xwork2=INFO
log4j.logger.org.apache.struts2=INFO
1.1.3 Actions
Por defecto, el Framework ejecutará un método con nombre execute. Sin embargo,
puede personalizar ello al indicar, en el ActionMapping, el nombre del método a
ejecutar.
Cada método ejecutará lógica para atender el request apoyándose, para ellos, en
servicios de negocio u otro tipo de componentes. Luego, sobre la base del resultado
del proceso, deberá retornar un String que referencie a uno de los Results
configurados en el ActionMapping.
Por ejemplo:
Los Action que hereden ActionSupport pueden hacer uso de los métodos
addActionMessage() y addActionError() para definir mensajes informativos y de
error respectivamente. Dichos mensajes podrán ser mostrados en las páginas
haciendo uso de tags del mismo nombre (ver punto 1.1.4)
Al mostrar resultado del request con valores obtenidos desde variables del
Action:
Implementación
Se tienen 3 alternativas:
a. Clase POJO
No hereda Clases ni implementa Interfaz. No soporta toda la funcionalidad
brindada por el Framework Struts.
Configuración
Ejemplo:
b. Anotaciones
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/annotations.html
Ejecución
Struts provee Tag Libraries que permiten generar contenido estático/dinámico, así
como manipular/evaluar objetos en memoria. Su uso se da en el View, ya sea en
tecnologías JSP, Velocity o Freemarker.
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/tag-developers-guide.html.
b. Haga uso del prefijo “s” para seleccionar los tags que se requieran, por
ejemplo para generar un formulario con una caja de texto y un botón se
tiene lo siguiente:
<s:form action="vendedorAction">
<s:textfield name="dni" label="DNI" />
<s:submit />
</s:form>
Observe, en el atributo name del textfield, el uso de OGNL para acceder a una variable
de un Action.
Struts 2 cuenta con temas de diseño preconfigurados que son los siguientes:
Simple
Xhtml (default)
Ajax
Dado que por default está configurado el tema Xhtml, el formulario creado con tags de
struts en el punto anterior se renderizará de la siguiente manera:
Cada Result definido en un Action tendrá asociado una implementación que puede
ser Dispatcher, Redirect, Stream, Velocity, entre otras. Dicha implementación viene a
ser lo que se conoce como Result Type. En el ejemplo, el Result Type asociado es
el Dispatcher por ser el default. Si se quiere generar otro tipo de resultado, deberá
indicarlo con el atributo type, según:
Notas:
En caso ninguno de los Result Types predefinidos sea suficiente para generar la
vista, también, tiene la opción de crear ResultTypes personalizados. Para ello,
deberá crear una Clase que implemente la interfaz
com.opensymphony.xwork2.Result y registrarlo en los packages de Strust.xml que
lo requieran con el elemento <result-types>
Por ejemplo:
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/result-types.html
LABORATORIO 3
a. Prototipos:
b. Pasos a seguir:
Principal.jsp
Nuevo.jsp
Resultado.jsp
En este ejemplo, las variables de entrada y/o salida están encapsuladas dentro del
objeto Empleado, es por ello que se declara dicho objeto en la línea 14.
En el método que procesa el request, observe que no se llama execute sino registrar,
lo cual es válido. Sin embargo, se debe indicar el nombre de dicho método en el
Action Mapping para que el Framework lo ejecute ante un request.
Strust.xml
Nótese que los results, en general, no tienen name, eso quiere decir que por defecto
su name=success,
Principal.jsp
Para que el formulario invoque al Action, debe especificar, en el atributo action del
form, el nombre del ActionMapping:
Nuevo.jsp
Asimismo, en cada campo, debe especificar, en el atributo name, en que variable del
Action se guardará el valor ingresado por el usuario.
7. Pruebe la aplicación.
8. Ejemplo complementario:
Uso de Constantes
EmpleadoAction
Nuevo.jsp
En el caso de géneros y estados civiles, dado que son Maps, basta con
indicarlos en el atributo list de cada campo.
En el caso de cargos, dado que es un java bean, además del atributo list,
se debe utilizar los atributos listKey y listValue para especificar la variable
desde donde se obtendrá el valor del código y descripción a mostrar en la
lista.
LABORATORIO 4
a. Prototipos:
b. Pasos a seguir:
Login.jsp
Principal.jsp
Se han añadido las líneas 12 y 13 para contenido dinámico, así como enlace para
cerrar sesión en la línea 21.
En este ejemplo, las variables de entrada y/o salida están encapsuladas dentro del
objeto Usuario, es por ello que se declara dicho objeto en la línea 21.
Strust.xml
Login.jsp
Para que el formulario invoque al Action, debe especificar, en el atributo action del
form, el nombre del ActionMapping:
Principal.jsp
7. Pruebe la aplicación.
8. Ejemplo complementario:
Interfaces Aware
Estas son utilizadas para acceder, a través de un objeto Map, a los scopes
que maneja la aplicación:
Scope Interface
request ServletRequestAware
response ServletResponseAware
sesión SessionAware
contexto ServletContextAware
Strust.xml
LABORATORIO 5
a. Prototipos:
b. Pasos a seguir:
Principal.jsp
Listado.jsp
Edicion.jsp
Detalle.jsp
En este ejemplo, las variables de entrada y/o salida de formulario están encapsuladas
dentro del objeto Vendedor, es por ello que se declara dicho objeto en la línea 24.
Strust.xml
Principal.jsp
Listado.jsp
En la línea 28, se añada el tag de estructura de control if, el cual evalúa si el listado de
vendedores tiene registros o no. Si es así, procede a ejecutar su contenido.
En la línea 40, se hace uso del tag iterator, el cual permite recorrer el listado y
acceder a los objetos.
En las líneas 42 a 44 se hace uso del tag property para acceder a las propiedades
del objeto Vendedor, esto por cada iteración.
Edicion.jsp
Se ha declarado un campo oculto, para poder identificar, según valor del código, si se
trata de una actualización o nuevo registro.
Detalle.jsp
7. Pruebe la aplicación.
1.1.6 Interceptores
Interceptores son la base del Framework Struts 2 y consiste en Clases Java que
actúan de manera similar a los ServletFilters, pues se encargan de interceptar los
request enviadas a un Action ejecutando cierta lógica común en las aplicaciones, por
ejemplo validaciones, i18n, manejo de excepciones, etc;.
Por ejemplo:
Dicho Interceptor-Stack está configurado como default, por lo cual se ejecutará en los
demás packages:
Por ejemplo:
(*)Para ello, primero, se debe crear una Clase Java que implemente métodos de la
Interfaz com.opensymphony.xwork2.interceptor.Interceptor.
Por ejemplo:
Por ejemplo:
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/interceptors.html
LABORATORIO 6
a. Prototipos:
b. Pasos a seguir:
Para evitar que el método prepare se ejecute siempre que se invoca al Action, puede
configurar los métodos que deben ser excluídos del PrepareInterceptor.
VendedorAction
Buscar
Eliminar
editar
EmpleadoAction
registrar
Ahora que los tiene identificado, proceda a reconfigurar el defaultStack dentro del
package demo, según:
Strust.xml
Para que todos los ActionMapping hagan uso del nuevo stack, debe añadir lo
siguiente:
Esto es muy útil, por ejemplo, cuando se requieren cargar objetos a mostrar en un
formulario de edición para actualizar los datos.
Strust.xml
También, añadirá, en el método prepare del Action, una estructura de control if para
que efectué la carga del vendedor si y solo si el código del mismo fue enviado desde el
cliente y almacenado en el atributo vendedor.codigo antes de ejecutar este método.
VendedorAction
Asimismo, puede borrar el método cargar del mismo Action, debido a que ya no será
utilizado por la aplicación.
Strust.xml
Si analiza un poco, se dará cuenta que no requiere aplicar todos los interceptores del
pitStack, por lo cual puede definir un interceptor-stack más básico, por ejemplo el
i18nStack, que también viene predefinido en struts-default:
5. Ejemplo complementario:
Durante request
- Línea 23: se obtiene tiempo de inicio.
- Línea 25 y 26: se obtiene nombre de ActionMapping y
Action
Durante response
- Línea 31: se obtiene tiempo en que finaliza ejecución.
- Línea 32: se obtiene tiempo transcurrido
- Línea 33: se genera log.
Strust.xml
Strust.xml
d. Pruebe la aplicación.
f. Pruebe la aplicación.
Dada esta característica, no será necesario rediseñar las 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:
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.
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
Por ejemplo:
textos.properties
textos_en.properties
textos_it.properties
textos_en_US.properties
En el ejemplo, nótese que el primero no tiene códigos ISO en su nombre, lo cual indica
será el archivo principal a utilizar por defecto.
LABORATORIO 7
a. Prototipos:
b. Pasos a seguir:
timeout=20
scope.default=request
registro.ok= Se realizó un registro en la tabla {0}
login.horaInicio= Usted accedió desde las #{session.login.horaInicio}
textos.properties
Los recursos dinámicos pueden definirse con parámetros {indice} (líneas 61,62,64 y
65) ó con OGNL (línea 60).
Strust.xml
Cada vez que requiera utilizarse un recurso del properties, se le debe referenciar a
través de su key, por ejemplo:
En JSPs
Login.jsp
En la línea 12, se definió texto estático con el tag text que apunta al property con
clave=”parrafo.login”.
Principal.jsp
En esta página, se han definido todos los textos con el tag text.
En código Java
UsuarioAction
6. Pruebe la aplicación.
textos_en.properties
Login.jsp
Se requiere enviar a Struts el código ISO del idioma. Para ello se debe sobreescribir el
parámetro “request_locale”.
Strust.xml
9. Pruebe la aplicación.
1.1.8 Validaciones
Struts 2, también, brinda un Framework de Validación que permite validar los valores
de entrada de una página (típicamente de un formulario) antes de ejecutar un método
de procesamiento del Action.
a. Validateable:
• Contiene un único método void validate().
• El método puede ser sobreescrito en Clases Action para definir
validaciones.
b. ValidationAware:
• Verifica si hay errores asociados a la validación. De ser así detiene
la secuencia de ejecución y solicita retorno a la vista con Result con
name=input.
Las dos interfaces colaboran dentro del workflow de Struts2 si se ejecutan los
Interceptors “ValidationInterceptor” y “DefaultWorkflowInterceptor”.
Validators
VALIDATORS
RequiredFieldValidator
RequiredStringValidator
IntRangeFieldValidator
LongRangeFieldValidator
ShortRangeFieldValidator
DoubleRangeFieldValidator
DateRangeFieldValidator
ExpressionValidator
FieldExpressionValidator
EmailValidator
URLValidator
VisitorFieldValidator
ConversionErrorFieldValidator
StringLengthFieldValidator
RegexFieldValidator
ConditionalVisitorFieldValidator
.
El Framework, también, permite implementar Validators personalizados que se ajusten
a la necesidad de la aplicación.
Configuración de Validaciones
Se sabe que, en las Clases Action, están declaradas las variables donde se
almacenan los valores de entrada. Si a dichas variables se quiere aplicar validaciones,
entonces el Action debe implementar ambas interfaces o heredar la Clase
ActionSupport.
• Programática
Por ejemplo:
• Declarativa
NombreAction-validation.xml
NombreAction-NombreActionMapping-validation.xml
Por ejemplo:
REFERENCIA
http://struts.apache.org/release/2.3.x/docs/validation.html
LABORATORIO 8
Se va a configurar validaciones.
a. Prototipos:
b. Pasos a seguir:
a. Código Java
UsuarioAction
En este método, puede realizar todas las validaciones necesarias a cada campos del
formulario. Por cada error encontrado, se añade un FieldError específico al
ValueStack, es por ello que cada fieldError se asocia a un campo en particular con el
respectivo mensaje de error.
Strust.xml
Pruebe la aplicación.
b. XML
En un archivo XML, se definirán los validators específicos por cada campo del
formulario.
UsuarioAction-loginUsuario-validation.xml
UsuarioAction-loginUsuario-validation.xml
Strust.xml
Pruebe la aplicación.
textos.properties
textos_en.properties
UsuarioAction-loginUsuario-validation.xml
En un archivo XML, se definirán los validators específicos por cada campo del
formulario.
EmpleadoAction-registrarEmpleado-validation.xml
Primero validará que el campo no tenga valor vacío, e inmediatamente después que
cumpla con la longitud máxima requerida.
Strust.xml
textos.properties
textos_en.properties
Pruebe la aplicación.
Strust.xml
VendedorAction-buscarVendedor-validation.xml
VendedorAction-editarVendedor-validation.xml
Strust.xml
Strust.xml
Pruebe nuevamente.
VALIDATORS
IntRangeFieldValidator
DoubleRangeFieldValidator
DateRangeFieldValidator
ExpressionValidator
FieldExpressionValidator
EmailValidator
URLValidator
VisitorFieldValidator
ConversionErrorFieldValidator
RegexFieldValidator
ConditionalVisitorFieldValidator
LABORATORIO 9
a. Prototipos:
b. Pasos a seguir:
Strust.xml
El archivo principal seguirá siendo Struts.xml, el cual incluirá los demás archivos de
configuración haciendo uso del elemento include, según:
Strust.xml
Strust.xml
Los results mencionados son los configurados entre las líneas 36 y 39. Como se
observa, son results de tipo global, es decir que no pertenecen a ningun
ActionMapping. Dichas páginas las pueden encontrar en la carpeta paginas/error:
NullPointerException
Ejecute el siguiente comando en mysql: drop database bd_daw1;
Pruebe la aplicación
UsuarioDAOMySql
Pruebe la aplicación.
Struts-empleado.xml
Struts-seguridad.xml
Struts-vendedor.xml
Ahora, cada botón o enlace que invoque a alguno de los ActionMappings de los
paquetes con namespace personalizado deberá, también, indicar el namespace que
corresponda.
Por ejemplo:
Login.jsp
Struts-seguridad.xml
Listado.jsp
LABORATORIO 10
a. Pasos a seguir:
1.1.10 Tiles
Al momento de crear el diseño de un sitio web típico, éste puede sufrir muchos
cambios durante su ciclo de vida. Utilizar diseños y gestores de diseño puede ayudar a
organizar las diferentes partes de un JSP de modo que éstos se puedan alterar con un
mínimo impacto para el resto de la aplicación.
REFERENCIAS
https://tiles.apache.org/
https://tiles.apache.org/framework/tutorial/index.html
LABORATORIO 11
a. Prototipos:
b. Pasos a seguir:
Plantilla.jsp
Cabecera.jsp
Menu.jsp
Pie.jsp
4. Configure Tiles
a. Template
Plantilla donde se definen las secciones que mostrarán las páginas de la aplicación.
En el ejemplo, es la página Plantilla.jsp, la cual consta de 4 secciones: cabecera,
menú, contenido y pie de página.
Para poder hacer uso de los tags de Tiles, primero, debe referenciar su tag library:
Plantilla.jsp
Plantilla.jsp
b. Definitions
Tiles trabaja en base a definitions, lo cual consiste en definir los contenidos que se
incluirán en las secciones del template.
Tiles.xml
Tiles.xml
Observe que hace referencia al template Plantilla.jsp, por lo cual con el elemento put-
attribute se configura el contenido a incluir en cada una de las 4 secciones definidas
allí
Web.xml
6. Ahora que Tiles está configurado, debe aplicarlo a las páginas que
requieran el diseño de la plantilla.
Tiles.xml
Nota importante:
Las páginas que serán utilizadas como secciones de un template deben tener
únicamente el código que corresponda justamente a dicha sección, por ejemplo:
Dado que Principal.jsp, ahora, representa una sección, es conveniente que solo
tenga el código que le corresponde, por tanto debería quedar así:
Principal.jsp
Menu.jsp
Struts.xml
Struts-seguridad.xml
7. Pruebe la aplicación.
8. Ahora que ya sabe cómo configurar templates con Tiles, puede aplicar la
plantilla de diseño a las demás páginas del proyecto.
LABORATORIO 12
a. Prototipos:
b. Pasos a seguir:
Edicion.jsp
En el Action, declare una variable global de tipo File con sus getter/setter.
VendedorAction
En este ejemplo, la imagen se guardará en base de datos, por ello en el método editar
se debe obtener el InputStream de la imagen para guardarlo en el campo foto del
bean Vendedor, el cual será enviado al servicio respectivo. Se añadió las líneas 68 a
70
VendedorAction
3. Mostrar Imagen
En la capa de persistencia, ya se tiene la consulta SQL que obtiene los datos del
Vendedor incluyendo la foto (InputStream).
Aquí, tiene varias opciones para llevar la foto hasta la pantalla del usuario, por ejemplo
generar un File almacenándolo en un ruta del servidor para luego acceder desde el
JSP o enviar el InputStream directamente al Result. En el ejemplo, va a implementar la
segunda opción.
VendedorAction
Este Action solo servirá para obtener el objeto InputStream de la sesión de modo que
lo exponga a un ResultType=stream.
Struts.xml
Observe que dada la casuística, el result es de tipo stream y está configurado para
obtener el objeto foto del Action.
Ahora, solo falta que la página donde se desea mostrar la foto invoque a este Action:
Detalle.jsp
Pruebe la aplicación.
UNIDAD
2
FRAMEWORK DE PERSISTENCIA
MYBATIS
LOGRO DE LA UNIDAD DE APRENDIZAJE
Al finalizar la unidad el alumno utilizando el Framework MyBatis implementa la
capa de persistencia de datos con Java.
TEMARIO
2.1 Tema 3 : Fundamentos
2.1.1. : Arquitectura y Configuración
2.1.2. : Mappers
2.1.3. : XML Mapped Statements
2.1.4. : Annotated Mapped Statements
2.1.5. : Otras configuraciones
2.2 Tema 4 : Proyecto Plantilla
2.2.1. : Aplicación Web
ACTIVIDADES PROPUESTAS
2.1 FUNDAMENTOS
MyBatis es un Framework Open Source utilizado en aplicaciones orientadas a Objetos
para implementar la capa de Persistencia que opere con Bases de Datos Relacionales
Versiones
IBATIS 1.0 (2001) - Clinton Begin.
IBATIS 2.0 (2004) - Apache Software Foundation
MYBATIS 3 (2010) - Github
PÁGINA OFICIAL
http://mybatis.github.io/mybatis-3/
http://blog.mybatis.org/
RELEASES
http://blog.mybatis.org/p/products.html
API DOCUMENTATION
http://mybatis.github.io/mybatis-3/apidocs/reference/packages.html
SOURCE REFERENCE
http://mybatis.github.io/mybatis-3/xref/index.html
FUENTE DE IMAGEN
https://code.google.com/p/mybatis/
Componentes
Mapped Statements
a. XML
b. Anotaciones
Mapper
Son interfaces que se enlazan con los Mapped Statements definiendo un método por
cada sentencia SQL.
Para obtener una instancia del Mapper se utiliza la interfaz SqlSession y debe
realizarse dentro de un método.
SqlSessionFactory
Una aplicación que usa MyBatis debe utilizar una instancia de SqlSessionFactory que
utilizará una única base de datos. Dicha instancia se obtiene a partir de un archivo de
configuración XML.
SqlSession
Es una interfaz Java que permite manejar transacciones, obtener Mappers y ejecutar
Mapped Statements.
Para poder utilizarlo se requiere que esté declarado en un método, así por ejemplo:
En la línea 18, se obtiene instancia del SqlSession utilizando uno de los métodos de
la interfaz SqlSessionFactory.
La creación del SqlSession se debe dar por cada request a procesar, ya que no es
Thread Safe y no debe ser compartida, es por ello que por cada hilo de ejecución se
debe tener una única instancia.
LABORATORIO 13
a. Script:
drop database if exists bd_mybatis;
create database bd_mybatis;
use bd_mybatis;
b. Pasos a seguir:
Ir a opción
Dé clic en Next.
Mybatis-config.xml
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>
b. Defina el Environment.
Mybatis-config.xml
ClienteMapper.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="">
</mapper>
ClienteMapper.xml
ClienteMapper.java
ClienteMapper.xml
El método main simula ser un cliente que solicita la ejecución de la funcionalidad del
caso, cuyo resultado se muestra en consola:
Consola
Configuración
mybatis-config.xml
REFERENCIAS
http://mybatis.github.io/mybatis-3/es/configuration.html
a. properties
Por ejemplo:
b. settings
Por ejemplo:
c. environments
Permite definir un entorno de trabajo por cada base de datos que utilizará la
aplicación. Cada entorno define el Gestor de Transacciones y un DataSource para
conectarse a Base de Datos.
En una aplicación, puede definir uno o más environments según el número de base de
datos con los que trabajará. Por ejemplo, si tiene dos environments, al generar el
SqlSessionFactory, se debe indicar el id del Environment que referenciará.
transactionManager
dataSource
d. mappers
Elemento utilizado para indicar la ruta completa de cada uno de los mappers a utilizar
en la aplicación o para indicar cuál es el paquete donde se encuentran todos los
mappers.
Por ejemplo:
e. typeAliases
Sirve para definir un alias a objetos, normalmente del modelo. Se puede asociar un
alias a cada objeto individualmente o indicar el paquete donde se encuentran dichos
objetos.
LABORATORIO 14
a. Script:
use bd_mybatis;
b. Pasos a seguir:
Mybatis-config.xml
Cambios:
MyBatisUtil
2.1.2 Mappers
Los Mappers son interfaces que se enlazan con los Mapped Statements definiendo
un método por cada sentencia SQL. No requiere extender o implementar ninguna
Clase y permiten reducir en casi 100% el uso de JDBC en la programación.
El uso del atributo namespace permite asociar el archivo XML con la interfaz
indicando la ruta completa de paquetes y nombre de Interfaz, tal como se observa en
la imagen. Considere que el uso de namespace es obligatorio en Mybatis.
En una aplicación típica, se debe definir un Mapper por cada archivo XML de Mapped
Statements.
Como alternativa al uso de archivos XML, los Mapped Statements también pueden
definirse con Anotaciones directamente en cada método del Mapper, por ejemplo:
En una aplicación típica, se definen tantos Mappers como tablas existan en la base de
datos permitiendo agrupar por afinidad los Mapped Statements.
Típicamente se crea un archivo XML por cada tabla existente en la base de datos, con
el objetivo de agrupar por afinidad los Mapped Statements.
Contenido base
Elementos
REFERENCIAS
http://mybatis.github.io/mybatis-3/es/sqlmap-xml.html
a. Para definir sentencias SQL del CRUD, tiene los elementos insert, select,
update y delete respectivamente.
En cada uno de ellos, se puede definir el comportamiento con los siguientes atributos:
b. El elemento sql sirve para definir porciones de código sql reutilizables que
se pueden incluir dentro de las sentencias SQL con el subelemento
<include>
IMPORTANTE
Por ejemplo:
LABORATORIO 15
a. Script:
use bd_mybatis;
b. Pasos a seguir:
ClienteMapper.xml
Registre un cliente.
Elimine un cliente.
En los tres últimos XML Mapped Statement, se define un parámetro de entrada de tipo
Cliente (registrar y modificar) o de tipo Integer (eliminar).
En el caso del tipo Cliente, el Mapped Statement recibe un bean que encapsula los
datos del cliente, los cuales son accedidos directamente en los SQL utilizando la
expresión #{atributo del bean}. En el caso del tipo simple, se utiliza la misma
expresión #{alias} cuyo contenido puede ser cualquier texto ya que es un único dato
de entrada.
Liste datos básicos de todos los clientes.
Dado que la sentencia SQL no devuelve todos los datos del cliente, es recomendable
definir ello en un elemento resultMap, de modo que se especifíque cuales seran los
campos del type a poblar.
Adicional a ello, con el elemento id, indique cuál es el campos a indexar para optimizar
el rendimiento al recorrer el List.
Esta consulta SQL devuelve exactamente los mismo datos de la consulta anterior, con
la diferencia que tiene un filtro de llave primaria. Por ende, puede reutilizar el
ResultMap rmClienteBasico.
ClienteMapper
TestService
Registre un cliente.
Elimine un cliente.
Consulta SQL
ClienteMapper.xml
Aplique el mismo principio del uso de ResultMap. En este caso, las columnas de la
consulta son campos calculados que no pertenecen a ningun bean. Una opción válida
es almacenar los valores en un Map, lo cual ha definido en el ResultMap
rmClienteReporte.
En este caso, es necesario definir el javaType para una conversión correcta del
JDBCType de la columna al atributo Java que le corresponda.
ClienteMapper
TestService
@Insert
@Update
@Delete
@Select
Por ejemplo:
REFERENCIAS
http://mybatis.github.io/mybatis-3/java-api.html (Sección Mapper Annotations)
LABORATORIO 16
Se implementará una versión similar a la aplicación del laboratorio 15 con mybatis con
el uso de Annotations.
a. Script:
use bd_mybatis;
b. Pasos a seguir:
Nota: Las operaciones SQL son las mismas que vio en el laboratorio 15.
ClienteMapper.java
Registre un cliente.
Elimine un cliente.
En el caso del tipo Cliente, el Mapped Statement recibe un bean que encapsula los
datos del cliente, los cuales son accedidos directamente en los SQL utilizando la
expresión #{atributo del bean}.
En el caso del tipo simple, cada parámetro tendrá asociado la anotación @Param que
sirve para asignar un alias al parámetro, el cual se utilizará en el SQL con la expresión
#{alias}. Esta anotación es opcional en caso solo haya un argumento en el método.
Dado que la sentencia SQL no devuelve todos los datos del cliente, es recomendable
definir ello en un elemento @Results, de modo que se especifíque cuales seran los
campos del Bean a poblar.
Adicional a ello, con el atributo id=true, indique cuál es el campo a indexar para
optimizar el rendimiento al recorrer el List.
Esta consulta SQL devuelve exactamente los mismo datos de la consulta anterior, con
la diferencia que tiene un filtro de llave primaria. Sin embargo, no puede reutilizarlo.
Por ello, debe definir nuevamente un @Results con los campos del Bean a poblar.
En este caso, es necesario definir el javaType para una conversión correcta del
JDBCType de la columna al atributo Java que le corresponda.
LABORATORIO 17
a. Script:
use bd_mybatis;
use bd_mybatis;
DELIMITER $$
DROP PROCEDURE IF EXISTS sp_nuevoCliente_1 $$
CREATE PROCEDURE sp_nuevoCliente_1 (
IN nombre VARCHAR(30),
IN apellido VARCHAR(30),
IN edad INT,
IN direccion VARCHAR(30),
OUT codigo INT)
BEGIN
END $$
DELIMITER;
DELIMITER $$
DROP PROCEDURE IF EXISTS sp_nuevoCliente_2 $$
CREATE PROCEDURE sp_nuevoCliente_2 (
IN nombre VARCHAR(30),
IN apellido VARCHAR(30),
IN edad INT,
IN direccion VARCHAR(30),
OUT codigo INT,
OUT mensaje VARCHAR(40))
BEGIN
END $$
DELIMITER;
DELIMITER $$
DROP PROCEDURE IF EXISTS sp_buscarCliente $$
CREATE PROCEDURE sp_buscarCliente (IN filtro VARCHAR(30))
BEGIN
SELECT cod_cli,
nom_cli,
ape_cli
FROM tb_cliente
WHERE nom_cli=filtro;
END $$
b. Pasos a seguir:
Vea los siguientes ejemplos que consumen los Stored Procedure creados:
ClienteMapper.xml
ClienteMapper.java
TestService.java
ClienteMapper.xml
ClienteMapper.java
TestService.java
ClienteMapper.xml
ClienteMapper.java
Este caso es similar al anterior, salvo por los campos de retorno del stored procedure
sp_nuevoCliente_2, pues además del código autogenerado devuelve un mensaje
informativo. Este último campo no pertenece al bean cliente ni a ningun otro bean
asociado, por lo cual es necesario utilizar un Map que contenga tanto el bean del
cliente como un objeto String para el mensaje.
TestService.java
3. Dynamic SQL
Se va a ver ejemplos básicos del uso de elementos que permiten manipular el SQL
definido:
IF
En este ejemplo, se está controlando que la clausula WHERE solo se aplique en caso
el usuario final desee filtrar por edad el cálculo del total. Si no envía edad, entonces el
WHERE no formará parte de la consulta SQL a ejecutar.
ClienteMapper.xml
ClienteMapper.java
TestService.java
FOREACH
En este ejemplo, el cliente tendrá la opción de enviar una o más edades de clientes a
considerar en el cálculo del query.
ClienteMapper.xml
ClienteMapper.java
TestService.java
WHERE / CHOOSE
En este ejemplo, se requiere ejecutar un único filtro a la consulta SQL según el dato
ingresado por el cliente, que puede ser apellido o nombre. Si cliente no envía filtro,
por defecto se filtrarán los registros de clientes cuya dirección sea diferente a NULL.
ClienteMapper.xml
ClienteMapper.java
TestService.java
REFERENCIA
http://mybatis.github.io/mybatis-3/dynamic-sql.html
LABORATORIO 18
a. Prototipos:
b. Pasos a seguir:
CargoMapper
CargoMapper.xml
DistritoMapper
DistritoMapper.xml
UsuarioMapper
UsuarioMapper.xml
EmpleadoMapper
EmpleadoMapper.xml
VendedorMapper
Como vio, en su momento, las Clases del modelo están relacionadas entre sí, por
ejemplo, en el proyecto, la Clase Vendedor tiene relación unidireccional con la Clase
Distrito y Empleado con la Clase Cargo.
VendedorMapper.xml
bean Distrito con el elemento association. En él, se asocia el atributo del bean
Vendedor(distrito) con el tipo de Objeto (alias distrito); y, al interno, cada uno de los
campos requeridos por la consulta SQL, con el elemento result.
Mybatis-config.xml
CargoServiceDAO
DistritoServiceDAO
LoginServiceDAO
VendedorServiceDAO
EmpleadoServiceDAO
6. Pruebe la aplicación.
7. Ejercicio complementario
context.xml
Mybatis-config.xml
Pruebe la aplicación.
UNIDAD
3
REPORTES CON JASPER
LOGRO DE LA UNIDAD DE APRENDIZAJE
Al término de la unidad el alumno utilizando el Framework STRUTS 2 Jasper
Reports y la herramienta IReport implementan una aplicación web que genera
reportes gráficos con criterios de búsqueda dinámicos y acceso a base de
datos con MyBatis.
TEMARIO
3.1 Tema 5 : Jasper Reports
3.1.1. : Diseño e implementación de reportes con la
herramienta IReport Designer
3.2 Tema 6 : Proyecto Plantilla
3.2.1. : Integración de Struts 2 y JasperReport
ACTIVIDADES PROPUESTAS
Este archivo fuente XML debe ser compilado para obtener un reporte real. La versión
compilada de fuente es nombrada con extensión “jasper".
Para facilitar el trabajo del programador, existe una herramienta llamada iReport, la
cual es un constructor y/o diseñador de reportes visual, fácil de usar para generar
reportes con Jasper. Esta herramienta permite también que los programadores corrijan
visualmente reportes complejos como cartas, imágenes, subreportes, etc.
iReport también está integrado con la biblioteca gráfica “JFreeChart”, una de las más
difundidas para Java. A continuación, se enumeran las principales características de
esta herramienta:
LABORATORIO 19
a. Prototipos:
b. Pasos a seguir:
Ir a Enlace:
http://sourceforge.net/projects/ireport/files/iReport/iReport-5.5.0/
2. Definir DataSource
Dé clic en ícono.
Seleccione New.
Dé clic en Test.
Para poder previsualizar el diseño, puede variar la configuración default, por ejemplo,
ir a propiedades del reporte y cambiar el valor del siguiente atributo:
Previsualice nuevamente.
La herramienta autogenerá un field por cada columna mapeando el tipo de dato con
su equivalente en Java. Asimismo, podrá previsualizar la data a recibir.
Compile y Previsualice
Observe que filas están muy separadas, entonces ajuste la altura de las
secciones.
Uso de VARIABLES
Nota: Para el uso de ruta relativa, es importante que la carpeta images esté en la
misma carpeta donde está el archivo *.jrxml
Compile y Previsualice .
Luego, cree un parámetro para utilizarlo en la consulta SQL como dato dinámico.
Creación de parámetro
Uso de parámetro
Compile y Previsualice .
Le saldrá un PROMT para ingresar el código del distrito, por ejemplo M1.
LABORATORIO 20
Se implementará una nueva versión del reporte que muestre vendedores por cada
Distrito.
a. Prototipos:
b. Pasos a seguir:
Según prototipo, va a realizar el agrupamiento por distrito. Por ello, debe obtener el
código de distrito. También, se requiere la descripción del Distrito para mostrarlo como
título de cada grupo.
4. Compile y Previsualice .
Observe que, aún, no hay diferencia en el resultado.
Dé clic derecho al nodo raíz del reporte y seleccione Add Report Group.
Se mostrará un wizard, donde definirá el nombre del grupo y el campo requerido para
agrupar.
Ahora, debe seleccionar las nuevas secciones que se deben añadir al reporte:
Dado que solo quiere mostrar su valor, seleccione The field value y dé clic en Ok.
Compile y Previsualice .
Para añadir totales por distrito, arrastre el field CODIGO_DIS a la sección Group
Footer 1.
Dado que necesita calcular el total de vendedores de cada distrito, seleccione The
result of an aggregation function (count) y dé clic en Ok.
Compile y Previsualice .
Nota: Para que un grupo no se muestre dividido por cambio de página, seleccione la
sección Group Header 1 y active el check de la propiedad Keep Together.
LABORATORIO 21
a. Prototipos:
b. Pasos a seguir:
Según el prototipo los datos requeridos, debe organizarse a nivel SQL de esta manera:
Para obtener los totales por estado civil en la consulta SQL, se realiza el agrupamiento
con el código de Estado Civil. Asimismo, sobre ello, hay que agrupar los resultados
por cada distrito.
3. A nivel del reporte, hay que agregar un Report Group asociado a distrito.
Dado que solo quiere mostrar su valor, seleccione The field value y dé clic en Ok.
Compile y Previsualice .
Para añadir total de vendedores por distrito, arrastre el field TOTAL a la sección
Group Footer 1.
Dado que necesita calcular el total de vendedores de cada distrito, seleccione The
result of an aggregation function (sum) y dé clic en Ok.
Compile y Previsualice .
Compile y Previsualice .
Compile y Previsualice .
Ahora, hay que configurar los valores en la ventana Category and Value con los fields
según la siguiente imagen:
Compile y Previsualice .
LABORATORIO 22
a. Prototipos:
b. Pasos a seguir:
El reporte que quiere configurar, en la aplicación, es el que vio en el laboratorio 20. Sin
embargo, tiene una diferencia: Se le ha quitado la consulta SQL, ya que, en la
aplicación, tiene la responsabilidad de ejecutar SQL en la capa de persistencia. Si
revisa el jrxml, verá que los Fields no se han modificado, eso quiere decir que debe
enviarle al reporte los datos en un listado de objetos que tengan definido los mismos
campos. Para ello, en el ejemplo, utilice un Map.
Consulta SQL
VendedorMapper.xml
VendedorMapper.java
VendedorService.java
VendedorServiceDAO.java
Struts-reporte.xml
Tiles.xml
Menú.jsp
Listo, hasta aquí, ha implementado una funcionalidad típica de búsqueda, lo único que
falta, aquí, es mostrar la lista de resultados en alguna página. En este caso, dichos
resultados los va a mostrar en un reporte Jasper.
Struts-reporte.xml
Struts-reporte.xml
9. Pruebe la aplicación.
ANEXOS
ANEXO
1
SOFTWARE REQUERIDO
Este curso requiere las siguientes herramientas de software:
Java JDK
Entorno integrado de desarrollo o IDE
Servidores de Aplicación
Base de datos
Framework Struts 2
Framework MyIbatis
Enlace:
http://www.oracle.com/technetwork/java/javase/downloads/index.html
Para entornos de programación, se requiere el JDK, pero para los de producción basta
con el JRE.
Descargue la última versión del JDK, ejecute el instalador y siga los pasos indicados
en el wizard.
Eclipse IDE:
Se debe escoger una de las opciones de los archivos .ZIP, por ejemplo el “Full
Distribution”.
ANEXO
2
GESTIÓN DE PROYECTOS CON
SCRUM
Gestión de proyectos de desarrollo de Software utilizando el marco de trabajo
Scrum.
Empirismo
Elementos emergentes
Auto-organización
Priorización
aunque esto sea muy obvio, actualmente, muchos equipos de trabajo quieren hacer
todo el trabajo de manera inmediata perdiendo el foco en las actividades claves o más
importantes. El mecanismo de priorización ayuda a que un equipo sea riguroso y
ordenado, asegurando el éxito del desarrollo de un producto usando Scrum.
Timeboxing
Así pues, Scrum, tiene una serie de principios sólidos sobre los cuales se rige para
lograr el la resolución de un problema, o en un caso más relacionado con los objetivos
de esta carrera: el desarrollo de un producto de Software de calidad. Y al igual que los
principios, Scrum, como marco de trabajo, nos especifica una serie de roles,
elementos y artefactos que facilitan su adopción y aseguran el éxito de su uso.
Roles de Scrum
Equipo de desarrollo
El equipo de desarrollo está conformado por todos los individuos necesarios para la
construcción de un producto de Software; cada uno de los miembros de este equipo
son los responsables de la construcción y calidad del producto.
Product Owner
Producto Owner es la persona responsable del éxito del producto desde el punto de
vista de los stakeholders (sponsors, usuarios del sistema, etc.). Como tal, tiene
responsabilidades como determinar la visión del producto y hacia dónde va el equipo
de desarrollo. De igual modo, debe saber manejar las expectativas de los stakeholders
y reunir los requerimientos. Además, debe determinar y conocer en detalle las
características funcionales y gestionar el plan de “reléase”, es decir las fechas en las
cuales se entrega un producto y con qué características contará para cada fecha.
Asimismo, debe determinar las prioridades de cada característica del producto o
cambiarla según sea el caso. Dadas estas funciones, el Product Owner es el único rol
capaz de aceptar o rechazar el producto construido al final de cada Sprint y proveer el
feedback o retroalimentación necesaria para mejorar el proceso (evolutivo).
ScrumMaster
ScrumMaster es la persona que sirve como Coach del equipo y ayuda a alcanzar su
máximo nivel de productividad.
Como se puede apreciar en este rol, el ScrumMaster como coach debe detectar
problemas y conflictos interpersonales y ayudar a que el equipo, como unidad auto-
organizada, pueda solucionar problemas de este calibre. Si un ScrumMaster no puede
solucionar el problema en cuestión, puede, eventualmente, involucrar a niveles más
altos de la gerencia.
Product Backlog
Product Backlog es el principal elemento de Scrum, conocido también como “pila del
producto” ya que contiene una lista de ítems llamados PBIs (Product Backlog Items)
que no son ni más ni menos que las características del producto a construir. Todos los
PBIs deben estar priorizados y actualizados; esta función la lleva a cabo el Product
Owner como se mencionó anteriormente en la sección de roles.
Cabe resaltar que aunque el Product Owner es quien tiene la última palabra sobre la
prioridad final de los ítems del Product Backlog, el equipo de desarrollo puede hacer
sugerencias o recomendaciones de acuerdo a los aspectos que considere
convenientes (carga de trabajo, dificultad de las tareas, curvas de aprendizaje, etc.).
Sprint Backlog
Historia de usuario
Historia de usuario es una dinámica la cual permite expresar de una manera rápida y
entendible la característica de un producto que se quiere implementar. Por lo general,
los PBIs deben ser expresados como historias de usuario para tener un alcance y
descripción más claros que facilitarán el desarrollo del equipo de trabajo. Asimismo,
pueden incluir criterios de aceptación, los cuales indicarán si una historia de usuario
cumple con los requisitos para ser considerada terminada (Definition of Done).
Para expresar una historia de usuario como tal es necesario tener en claro cómo
elaborar el enunciado, el cual está compuesto por los siguientes elementos: Rol,
Acción y Resultado. El enunciado no describe detalles de cómo se va a ejecutar la
acción que necesita el usuario.
Para una mejor clasificación y organización puede añadirse un código a cada historia,
para ayudar a su identificación única dentro del proyecto (actualmente hay
aplicaciones como ScrumWise o Jira que permiten gestionar todos los artefactos y
dinámicas que se explican en este anexo).
Para entender mejor cada uno de los elementos que componen una historia de
usuario, se explicarán en detalle en qué consisten:
Sprint (Iteración)
Pese a lo antes mencionado; el equipo Scrum por mutuo acuerdo puede decidir en
probar con iteraciones más largas o cortas. Esta decisión deberá estar respaldada por
razones bien fundamentadas como negocio cambiante, requerimientos ambiguos o
desconocidos, etc. Lo importante es tener claro que el ritmo de trabajo definido por el
Sprint ayudará a una mejor previsibilidad y a obtener, al final del periodo, un
incremento funcional potencialmente entregable.
Sprint Planning
El Daily Meeting o Daily Scrum son las reuniones diarias que deben realizarse al
empezar la jornada de trabajo (es lo recomendable). Estas reuniones son parte
fundamental del marco de Scrum pues uno de los beneficios de Scrum que se
encuentra en sus principios es el incremento de la comunicación dentro de un equipo
de trabajo. Esto facilita la coordinación e interacción entre los miembros y refuerza el
conocimiento actual que todos tienen, aparte de conocer las dependencias de las
actividades que realizan.
Cabe mencionar que aunque lo requerido en las reuniones son al equipo de trabajo y
al ScrumMaster; los otros roles como Product Owner o Stakeholders pueden participar
si lo consideran conveniente; no obstante, a menos que sea estrictamente necesario,
su participación es en calidad de expectadores u observadores; su participación cobra
más importancia en la reunión de revisión de producto, la cual se analizará a
continuación.
La Reunión de revisión del producto es una reunión que se realiza al finalizar cada
Sprint y tiene como objetivo exponer el entregable producido durante el periodo de
trabajo para obtener la aceptación o rechazo del Product Owner respecto a las
características construidas. Además, esta reunión sirve como dinámica clave para
recibir “feedback” por parte del Product Owner o los Stakeholders y hacer los ajustes
necesarios en la siguiente iteración.
Reunión de retrospectiva
Burndown Chart
Burndown Chart es una representación gráfica del trabajo que se debe realizar en un
determinado periodo de tiempo y del trabajo que se ha realizado también; de modo
que se pueda apreciar el progreso del trabajo durante un Sprint. Su representación se
realiza a través de un diagrama de dos dimensiones, en el cual el eje vertical
representa las actividades a realizar y el eje horizontal representa al tiempo.
Por lo general, la columna “TO VERIFY” puede ser obviada, ya que se utiliza para
fines de análisis de calidad o por los encargados de pruebas para monitorear su
trabajo. Lo más frecuente o más usado para delimitar el avance de tareas es “TO DO”,
“IN PROGRESS” o “DONE”.
Como bien se mencionó, este artefacto es una representación más gráfica del Sprint
Backlog que facilita a un miembro del equipo de trabajo administrar sus tareas de
manera ordenada y a los otros roles poder ver el estado de avance. Este artefacto
Cabe mencionar que el Sprint Backlog puede tener una tabla de estados similar que
está adjunta al documento o incluída en el mismo documento como se podrá ver más
adelante en la sección “Artefactos de Scrum”.
Una metodología hace referencia a una serie de procedimientos que deben realizarse
para alcanzar un determinado objetivo. Scrum, como tal, no define ningún
procedimiento o camino de éxito. Scrum brinda herramientas, técnicas, artefactos,
roles y dinámicas que se agrupan en un conjunto de buenas prácticas adoptables por
cualquier organización para cualquier tipo de proyecto (no necesariamente Software).
Es por ello que Scrum no se considera a sí mismo una metodología, sino más bien un
marco de trabajo que es resultado de la experimentación de muchas organizaciones
que han alcanzado objetivos de manera eficiente.
No obstante, son los stakeholders (clientes o auspiciadores) los que realmente definen
el sentido de urgencia de las características que deben priorizarse o no. Es por esta
razón, que la comunicación con el “Product Owner” debe ser bastante clara y muy
frecuente para asegurarse de que se estén realizando las actividades que el cliente
considere más urgentes. Pero, por lo general, se toman en cuenta las actividades que
representan un beneficio máximo para la empresa o entidad interesada; es justamente
el beneficio o característica que brinda el mayor retorno de inversión (ROI) el criterio
principal para la priorización de los elementos en un Product Backlog.
antes de iniciar un Sprint (durante el Sprint Planning). Para poder elaborar el Sprint
Backlog, es necesario tener priorizado el Product Backlog, de éste último se extraen
las características o elementos que se desarrollarán o en los que el equipo trabajará
durante el periodo de tiempo establecido (Sprint). Cada vez que está por iniciar un
Sprint, se debe realizar el planeamiento como es debido para tener el Sprint Backlog,
es decir, por cada Sprint que se realice, se debe tener un Sprint Backlog.
¿Cuál es la duración máxima del Daily Meeting y qué temas debería abarcar?
Una de las dinámicas más importantes para mantener vivo el concepto de Scrum es el
Daily Scrum o Daily Meeting. No obstante, a pesar de ser una dinámica muy
importante, su duración no debería exceder los 15 minutos; ya que esta dinámica sólo
está presente para dar un estado del trabajo que se viene realizando diariamente y
reportar los impedimentos que pueden estar obstruyendo el avance de alguna tarea o
característica necesaria del sistema.
Artefactos de Scrum
Product Backlog
Sprint Backlog
Burndown Chart