You are on page 1of 64

Programación Avanzada

Laboratorio de Prácticas
Índice
 Objetivos  IDE Eclipse (Entorno de
 Entorno de Desarrollo Desarrollo Integrado)
 Instalación  Integración Maven 3
Ejecución/Depuración de
Apache Maven 3


aplicaciones
 Gestión de Proyectos
 Plugin Maven 3
 POM
 SVN
 Dependencias
 Conceptos Básicos
 Ciclo de Vida
 Plugin para Eclipse
 Ejemplos del Laboratorio
 Creación Inicial del Proyecto
 Estructura Maven 3
 Configuración Maven 3
 Miniportal
 Compilación  Servidores Web
 Jetty
 Tomcat
 Recomendaciones Finales

Laboratorio - 2
Objetivos
 Familiarizarse con el entorno y herramientas de
desarrollo de aplicaciones empresariales
 Ejecutar los ejemplos según se vaya avanzando en
clase de teoría
 Realización de la Práctica de la asignatura
 Enfoque basado en iteraciones, de manera que cada
iteración incorpora más funcionalidad sobre la anterior,
hasta que en la última iteración se termina con un software
que implementa toda la funcionalidad
 En cada iteración se hace análisis, diseño, implementación y
pruebas
 Grupos: 3 personas

Laboratorio - 3
Entorno de Desarrollo (1)
 Sistema Operativo: Windows / Linux / Mac OS
 Herramienta de modelado de aplicaciones
 MagicDraw for UML 16.5 - Professional Java Edition
 Instalada en las máquinas de refencia
 /opt/MagicDraw_UML_16.5/bin/mduml
 Applications > Programming > MagicDraw 16.5
 Se puede utilizar cualquier otra
 Dia (Windows, Linux y Mac): http://dia-installer.de/
 Umbrello (Linux): http://umbrello.kde.org/
 starUML 1.0 (Windows):
http://staruml.sourceforge.net/v1/download.php

 IDE de desarrollo
 Eclipse 4.4 Luna
 Incluye plugins para: Maven 3 / SVN
Laboratorio - 4
Entorno de Desarrollo (y 2)
 ftp://ftp.fic.udc.es/publico/POJOyWS
 Eclipse 4.4 (Luna)
 JDK 1.8.0_05
 Apache Maven 3.2.2
 Mysql 5.6.19
 Apache Tomcat 8.0.9
 [Opcional Windows] Tortoise SVN 1.8.7

 Documentación
 https://moodle.udc.es/course/view.php?id=29114
 Se permite acceso como usuario invitado

Laboratorio - 5
Instalación (1)
 Seguir los pasos de los ficheros que se pueden
descargar desde moodle
 LEEME_WINDOWS.txt: Windows
 LEEME_UNIX.txt: Linux y Mac

 Los ficheros contienen los pasos necesarios para


 Instalar el Software (el mismo que en ISD)
 IMPORTANTE: Descargar las versiones adecuadas del
software para el sistema operativo y la arquitectura (32 o 64
bits)

 Descargar y desempaquetar los ejemplos de PA


 https://campusvirtual.udc.es/moodle
 pojo-examples-<version>-src.{tar.gz,.zip}
Laboratorio - 6
Instalación (y 2)
 Los ficheros contienen los pasos necesarios para
(cont)
 Establecer variables de entorno (igual que en ISD)
 Comprobar que se han establecido correctamente

 Crear las Bases de Datos necesarias para los ejemplos


 Similar a ISD, pero se crean con otros nombres (pojo y
pojotest) y con permisos para otro usuario (pojo/pojo)

 Inicializar datos de ejemplo y compilar los ejemplos de PA


cd pojo-examples-<version>
mvn sql:execute install

 Configurar Eclipse (igual que en ISD, más un paso adicional


para instalar el plugin “WTT Web Tools for Tapestry”)
Laboratorio - 7
Apache Maven 3 - Gestión de Proyectos

 Herramienta de Gestión de proyectos Software


 Estas herramientas sirven para automatizar gran cantidad de
tareas que los desarrolladores de software necesitan
ejecutar repetidamente durante las diferentes fases de un
proyecto
 Compilar el código fuente
 Empaquetar el código binario y otros recursos (e.g. en ficheros
JAR o WAR)
 Ejecutar las pruebas
 Generar “distribuciones fuente”
 Etc.
 Documentación
 Maven en 5 minutos
 http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html
 Guía básica de Maven
 http://maven.apache.org/guides/getting-started/index.html

Laboratorio - 8
Ejemplos - Estructura Maven 3 (1)
pom.xml
pom.xml

MySQLCreateTables.sql

Laboratorio - 9
Ejemplos – Configuración Maven 3 (2)
 “Profiles” y filtrados
 Permiten especificar ciertos aspectos de configuración de los
recursos como variables, que son reemplazadas por un valor
concreto en tiempo de construcción del proyecto (cuando se
ejecuta maven)
 Hemos definido el perfil “mysql”, activo por defecto, asignándole a
las variables los valores correspondientes para la conectividad con
la BD MySQL
 Plugins
 Compiler (mvn compile)
 Configuración del compilador
 Assembly (mvn assembly:assembly)
 Permite generar distribuciones
 En los ejemplos se usa para generar una distribución fuente
 SQL (mvn sql:execute)
 Ejecución de los scripts SQL de creación de tablas
 Jetty (mvn jetty:run)
 Permite ejecutar una aplicación en el servidor Web Jetty sin necesidad
de empaquetarla en un fichero WAR

Laboratorio - 10
Ejemplos – Configuración Maven 3 (3)

Ciclo de vida: Fases Plugins

… archetype
mvn compile compile
… compiler

process-test-resources sql-maven-plugin
… mvn sql:execute
test db:pojotest db:pojo
mvn test

surefire
package
… jar
mvn install install
install
deploy

Laboratorio - 11
Ejemplos – Compilación (y 4)
 Configuración por defecto de BD: MySQL
 BD para la ejecución de la aplicación: pojo
 BD para la ejecución de las pruebas: pojotest
 En ambos casos => usuario pojo, password pojo
 Disponer de ambas bases de datos, permite que la ejecución
de la aplicación no afecte a la ejecución de las pruebas, y
viceversa
 Arrancar la BD
 Utilizar maven para crear las tablas en la base de
datos y compilar los ejemplos

cd pojo-examples-<version>
mvn sql:execute install

Laboratorio - 12
Eclipse (1)
 Arrancar Eclipse
 eclipse&

 Antes de continuar, deben haberse seguido todos los


pasos de configuración de Eclipse especificados en el
fichero LEEME_PA_WINDOWS.txt o
LEEME_PA_UNIX.txt de moodle

Laboratorio - 13
Eclipse - Importar Ejemplos (2)

 Configuración de Eclipse para importar todos los


módulos de los ejemplos como un proyecto
(utilizando m2eclipse)
 Ir a "File > Import > Maven > Existing Maven
Projects"
 Seleccionar el directorio raíz del proyecto
 Click sobre "Finish“

 Plugin de Tapestry
 Click sobre una clase página
 Botón Derecho > Open With > Tapestry Editor
 Aparecerán 2 tabs
Uno muestra el código java de la página y el otro la plantilla
NOTA: Esto habrá que hacerlo para cada página una sola vez; eclipse
recordará el editor seleccionado para abrirla la próxima vez
Laboratorio - 14
Eclipse - Ejecución y Depuración de Clases de los Ejemplos (y 3)

 Iniciar la base de datos


 Ejecución desde Eclipse
 pojo-minibank
es.udc.pojo.minibank.test.experiments.hibernate.CreateAccount
es.udc.pojo.minibank.test.experiments.hibernate.ExistAccount <accId>
es.udc.pojo.minibank.test.experiments.hibernate.FindAccount <accId>
es.udc.pojo.minibank.test.experiments.hibernate.FindAccountsByUserId <userId>
es.udc.pojo.minibank.test.experiments.hibernate.RemoveAccount <accId>
es.udc.pojo.minibank.test.experiments.transfer.Transfer <srcAccId> <destAccId>

Laboratorio - 15
SVN – Conceptos básicos (1)
 Utilizaremos subversion como sistema de control de
versiones
 https://svn.fic.udc.es/grao3/pa/14-15
 Estructura recomendada
https://svn.fic.udc.es/grao3/pa/14-15/pa001
pojo-app Cada branch contiene modificaciones
Directorio realizadas a partir del código asociado
raíz del a un tag
proyecto Cada tag contiene código asociado a una
revisión específica

El trunk contiene la versión actual del


código (ultima revisión)

Laboratorio - 16
SVN – Conceptos básicos (2)
 Creación de tags para la entrega de iteraciones
 El comando svn copy permite realizar una copia ligera de un
directorio del repositorio a otra ubicación
svn copy https://svn.fic.udc.es/grao3/pa/14-15/pa001/pojo-app/trunk \
https://svn.fic.udc.es/grao3/pa/14-15/pa001/pojo-app/tags/version-1.0 \
-m "Etiqueta de la versión 1.0 del proyecto pojo-app"

Laboratorio - 17
SVN & Eclipse (y 3)
 Plugin “subclipse”
 Botón derecho > Team
 Update to HEAD
 Commit…
 Add to Version Control
 Branch/Tag…
 Show History
 …
 Botón derecho > Delete

Laboratorio - 18
Creación Inicial del Proyecto (1)
 Arquetipo: pojo-miniportal-archetype
 Proyecto generado por el arquetipo: MiniPortal
 Modelo
 Capa Web
 Layout
 Session y Cookies
 Filtros de regeneración de sesión / acceso a recursos
 Uso del arquetipo
 Cómo añadir datos a la base de datos
 Cómo añadir una entidad persistente al modelo
 Cómo añadir una operación al modelo
 Cómo añadir un test de integración de la capa modelo
 Cómo añadir una página web
 Cómo habilitar el patrón “Open Session in View”

Laboratorio - 19
Creación Inicial del Proyecto (2)
 Añadir a la lista de repositorios el del arquetipo
+ cd $HOME/.m2

+ wget http://www.tic.udc.es/is-java/maven-repo/settings.xml

 Crear el esqueleto del proyecto y subirlo al


repositorio
 Es necesario tener en cuenta las siguientes consideraciones
 artifactId representa el nombre del proyecto (cambiar pojo-app
por el nombre del proyecto, que puede estar basado en la temática de
la práctica)
 groupId representa la jerarquía de paquetes básica de la aplicación,
por lo que tiene que especificarse en minúsculas y no incluir guiones.
Suele ser el nombre de la organización más el nombre del proyecto
dentro de la organización (cambiar es.udc.pojoapp por el nombre
del paquete principal de la práctica del grupo, como por ejemplo
es.udc.pa.pa001.practicapa, siendo pa001 el nombre del grupo
de prácticas correspondiente y practicapa el nombre del proyecto)

Laboratorio - 20
Creación Inicial del Proyecto (3)
 Crear el esqueleto del proyecto y subirlo al
repositorio
+ mvn archetype:generate -DarchetypeGroupId=es.udc.pojo.archetypes
-DarchetypeArtifactId=pojo-miniportal-archetype -DarchetypeVersion=2.2.0
-DgroupId=es.udc.pojoapp -DartifactId=pojo-app -Dversion=1.0.0
+ Confirmar el proceso: Y

+ cd pojo-app
+ mkdir trunk branches tags
+ mv pom.xml src trunk

+ svn import https://svn.fic.udc.es/grao3/pa/14-15/pa001/pojo-app


-m "Proyecto pojo-app" --username XX --password XX

+ cd ..
+ rm pojo-app

 NOTA: Sustituir pojo-app por el nombre del proyecto y pa001 por el


grupo correspondiente y especificar usuario y contraseña
 NOTA: Sólo debe de realizarlo un miembro del grupo

Laboratorio - 21
Creación Inicial del Proyecto (4)
 Bajar el proyecto del repositorio y crear un proyecto
Eclipse
+ Importar el proyecto desde Eclipse mediante “File -> Import -> Maven -> Check
out Maven Projects from SCM"
* Especificar la URL "svn" "https://svn.fic.udc.es/grao3/pa/14-15/pa001/pojo-
app/trunk"
* Click en Next
* (Opcional) Deseleccionar "Use default workspace location"
Browse -> elegir un directorio en el que se creará el proyecto
En ese directorio se creará un directorio con el nombre del proyecto
o con nombre maven.<TIMESTAMP> con el código fuente del proyecto dentro
* Click en Finish

* Introducir usuario y contraseña en caso de que la pida

Laboratorio - 22
Creación Inicial del Proyecto (y 5)
 Instrucciones, tras el import
 En ese momento eclipse crea el directorio .settings y los
ficheros .project, .classpath
+ Botón derecho sobre el proyecto -> Team > Synchronize with repository
Esto hace que te muestre los ficheros que no están sincronizados
Sobre los ficheros .project, .classpath y directorio .settings, target:
+ botón derecho > Team > Add to svn:ignore

NOTA: Add to svn:ignore sólo se puede hacer sobre ficheros/directorios


que no estén ya subidos al SVN. Para los subidos, primero hay que
eliminarlos

 Cómo hacer commits/updates desde Eclipse


+ Botón derecho sobre el/los fichero(s) modificado(s) (e.g. pom.xml) ->
Team -> Commit
(Sólo un miembro del grupo; el resto de miembros Team -> Update to Head
sobre el proyecto)

Laboratorio - 23
MiniPortal
 El arquetipo genera la aplicación MiniPortal
 ¿Qué es MiniPortal?
 Un portal con registro de usuarios y sin contenidos
 Arquitectura reusable para implementar un portal real con
usuarios registrados
 ¿Qué aporta MiniPortal frente a MiniBank?
 Gestión de sesiones y cookies
 Extensión del procesador de peticiones para
 Mantenimiento de la sesión
 Obligar a que las acciones que requieren autenticación sólo
estén disponibles para los usuarios autenticados

 Constituye la base para el desarrollo de la práctica

Laboratorio - 24
Estructura de src/main (1)

pojo-miniportal
src/main

java
es.udc.pojoapp
model
userprofile
userservice
util
util
web
components
pages
user
services
util
(Continúa en la siguiente transparencia)
Laboratorio - 25
Estructura de src/main (y 2)
pojo-miniportal

src/main

resources

es/udc/pojoapp/web
components
pages

user
org/apache/tapestry5
corelib
pages

webapp
css
WEB-INF

Laboratorio - 26
Modelo de MiniPortal (1)
 es.udc.pojoapp.model.userprofile.UserProfile
 Modela la información de registro de un UserProfile
usuario
- userProfileId : Long
 No incluye la propiedad version anotada con
- loginName : String
@Version porque aunque se trata de una - encryptedPassword : String
entidad modificable, sólo el usuario puede - firstName : String
cambiar sus datos de perfil por lo que no hay - lastName : String
posibilidad de modificación concurrente - email : String
 Para gestionar su persistencia se define un + Constructores
DAO, que extiende del genérico y utiliza + métodos get/set
Hibernate

 es.udc.pojoapp.model.userservice.UserService
 Servicio que modela la interacción del usuario con el portal
 Registrar usuario
 Autenticarse
 Recuperar información de registro
 Actualizar información de registro
 Cambiar contraseña

Laboratorio - 27
Modelo de MiniPortal (2)
UserProfileDetails
- firstName : String
- lastName : String
- email : String
+ Constructor
+ Métodos get

<<interface>>
UserService

+ registerUser(loginName : String, clearPassword : String, userProfileDetails : UserProfileDetails) : UserProfile


+ login(loginName : String, password : String, passwordIsEncrypted : boolean) : UserProfile
+ findUserProfile(userProfileId : Long) : UserProfile
+ updateUserProfileDetails(userProfileId : Long, userProfileDetails : UserProfileDetails) : void
+ changePassword(userProfileId : Long, oldClearPassword : String, newClearPassword : String) : void

UserServiceImpl
<<use>> PasswordEncrypter <<use>> jcrypt

Laboratorio - 28
Modelo de MiniPortal (3)
 Cuando un usuario se registra, introduce su
contraseña en claro
 El portal no permite actualizar la contraseña y el
resto de información de registro a través del mismo
formulario, dado que las contraseñas se guardan
cifradas
 Para cifrar las contraseñas se utiliza la clase
es.udc.pojoapp.model.userservice.util.PasswordEncrypter

 Las operaciones de registro de usuario y


actualización de información de registro de la
fachada trabajan con UserProfileDetails, que
no incluye la contraseña

Laboratorio - 29
Modelo de MiniPortal (y 4)
 El caso de uso login devuelve UserProfile
porque se necesita la siguiente información
 userProfileId
 Se mantendrá en la sesión (caché), porque se necesita para
invocar los casos de uso de búsqueda y actualización de
información de usuario (además, su presencia en la sesión se
utiliza para saber si un usuario está autenticado)
 firstName
 Se mantendrá en la sesión (caché), dado que se visualiza en
todas las páginas
 Ocupa poca memoria
 encryptedPassword
 Si el usuario selecciona “recordar mi contraseña”, es preciso
enviar su valor como cookie

Laboratorio - 30
Capa Web de MiniPortal
 De forma similar a pojo-minibank, en MiniPortal
todas las páginas tienen el mismo layout (se basan
en el componente
es.udc.pojoapp.web.components.Layout)

Título (tag title)


MiniPortal Autenticarse | [nombre usuario] + Menú

Contenido

Pie de página

Laboratorio - 31
Session State Objects (1)
 A diferencia de MiniBank, MiniPortal permite realizar diferentes
operaciones en función de si hay o no un usuario autenticado
 Tapestry permite crear objetos que estén accesibles a todas las
páginas: Session State Objects (SSOs)
 En MiniPortal hemos definido la clase UserSession, que contiene
información de un usuario, necesaria una vez se ha
autenticado/registrado
 Los SSOs típicamente tienen que tener un constructor sin
argumentos (o con argumentos para inyectar servicios)
 Para hacer accesible ese objeto a una página en concreto, es
necesario añadir una propiedad de ese tipo a la página
correspondiente y anotarla con @SessionState
 Sólo puede haber un SSO por clase de objeto
 Es decir, cualquier página que declare una propiedad de la clase
UserSession, anotándola con @SessionState, referenciará al
mismo objeto, aunque el nombre de la propiedad sea diferente

Laboratorio - 32
Session State Objects (y 2)
 Como cualquier otra propiedad de una página, es
necesario definir métodos get para poder acceder a
ella desde la plantilla
 Por defecto, los SSOs se almacenan en la Sesión
(javax.servlet.http.HttpSession)
 Si no existe la Sesión cuando se referencia un SSO por
primera vez, se crea
 Si se ha anotado utilizando el parámetro create=false,
el SSO no se creará de forma automática (será necesario
inicializarlo de forma explícita)
 Ésta es la alternativa considerada en los ejemplos
 Tapestry contempla el uso de SSOs en un entorno en
cluster

Laboratorio - 33
UserSession.java
public class UserSession {

private Long userProfileId;


private String firstName;

public Long getUserProfileId() {


return userProfileId;
}

public void setUserProfileId(Long userProfileId) {


this.userProfileId = userProfileId;
}

public String getFirstName() {


return firstName;
}

public void setFirstName(String firstName) {


this.firstName = firstName;
}

Laboratorio - 34
Layout.java
@Import(library = {"tapestry5/bootstrap/js/collapse.js",
"tapestry5/bootstrap/js/dropdown.js"},
stylesheet="tapestry5/bootstrap/css/bootstrap-theme.css")

public class Layout {


@Property
@Parameter(required = true, defaultPrefix = "message")
private String title;

@Parameter(defaultPrefix = "literal")
private Boolean showTitleInBody;

@Property
@SessionState(create=false)
private UserSession userSession;

@Inject
private Cookies cookies;
...

 En función de si un usuario está autenticado o no, las opciones


del menú serán diferentes Laboratorio - 35
Layout.tml
...
<ul class="nav navbar-nav navbar-right">
<t:if test="userSession">
<li class="dropdown">
<a href="#" class="dropdown-toggle"
data-toggle="dropdown">${userSession.firstName}
<span class="caret"></span></a>
<ul class="dropdown-menu" role="menu">
<li><a href="#" t:type="PageLink"
t:page="user/updateprofile">${message:updateProfile}</a></li>
<li><a href="#" t:type="PageLink"
t:page="user/changepassword">${message:changePassword}</a></li>
<li class="divider"></li>
<li><a href="#" t:type="ActionLink"
t:id="logout">${message:logout}</a></li>
</ul>
</li>
<p:else>
<li><a href="#" t:type="PageLink"
t:page="user/login">${message:authenticate}</a></li>
</p:else>
</t:if>
</ul>
... Laboratorio - 36
Capa Web de MiniPortal
Clic en Register
user/Register
user/Login
onValidateFromXxx() onValidateFromXxx()

onSuccess() onSuccess()
Clic en
Authenticate

Index Clic en Logout


Index
(sin autenticar) (autenticado)
Clic en

onSuccess()
onSuccess()
Update profile Clic en
Change password

onActionFromLogout() onPrepareForRender()

user/UpdateProfile user/ChangePassword

onValidateFromXxx() onValidateFromXxx()

Laboratorio - 37
Gestión de Cookies
 Para gestionar las cookies, Tapestry proporciona el
servicio Cookies
 Permite leer el valor de cookies que llegan en la petición
HTTP, así como eliminar y modificar/añadir cookies a la
respuesta HTTP
 Para hacer uso de este servicio sólo es necesario
inyectarlo en la página que lo vaya a utilizar
@Inject
private Cookies cookies;

 Para gestionar las cookies hemos definido una clase


utilidad, CookiesManager, que recibe como
parámetro el servicio Cookies

Laboratorio - 38
CookiesManager.java
public class CookiesManager {
private static final String LOGIN_NAME_COOKIE = "loginName";
private static final String ENCRYPTED_PASSWORD_COOKIE =
"encryptedPassword";
private static final int REMEMBER_MY_PASSWORD_AGE =
30 * 24 * 3600; // 30 days in seconds

public static void leaveCookies(Cookies cookies, String loginName,


String encryptedPassword) {
cookies.getBuilder(LOGIN_NAME_COOKIE, loginName).
setMaxAge(REMEMBER_MY_PASSWORD_AGE).write();
cookies.getBuilder(ENCRYPTED_PASSWORD_COOKIE, encryptedPassword).
setMaxAge(REMEMBER_MY_PASSWORD_AGE).write();
}

public static void removeCookies(Cookies cookies) {


cookies.removeCookieValue(LOGIN_NAME_COOKIE);
cookies.removeCookieValue(ENCRYPTED_PASSWORD_COOKIE);
}

public static String getLoginName(Cookies cookies) {


return cookies.readCookieValue(LOGIN_NAME_COOKIE);
}

public static String getEncryptedPassword(Cookies cookies) {


return cookies.readCookieValue(ENCRYPTED_PASSWORD_COOKIE);
} Laboratorio - 39
Login.java (1)
public class Login {

@Property
private String loginName;
@Property
private String password;
@Property
private boolean rememberMyPassword;

@SessionState(create=false)
private UserSession userSession;

@Inject
private Cookies cookies;

@Component
private Form loginForm;

@Inject
private Messages messages;
@Inject
private UserService userService;

private UserProfile userProfile = null;


...

Laboratorio - 40
Login.java (y 2)
void onValidateFromLoginForm() {
if (!loginForm.isValid()) {
return;
}
try {
userProfile = userService.login(loginName, password,
false);
} catch (InstanceNotFoundException e) {
loginForm.recordError(messages.
get("error-authenticationFailed"));
} catch (IncorrectPasswordException e) {
loginForm.recordError(messages.
get("error-authenticationFailed"));
}
}

Object onSuccess() {
userSession = new UserSession();
userSession.setUserProfileId(userProfile.getUserProfileId());
userSession.setFirstName(userProfile.getFirstName());

if (rememberMyPassword) {
CookiesManager.leaveCookies(cookies, loginName, userProfile
.getEncryptedPassword());
}
return Index.class;
}
} Laboratorio - 41
Login.tml
http://localhost:9090/pojo-miniportal/user/login
Authentication - MiniPortal

 La plantilla de user/Login hace uso del componente CheckBox


...
<div class="checkbox">
<label for="rememberMyPassword">
<input t:type="Checkbox" t:id="rememberMyPassword"/>
${message:rememberMyPassword-label}
<p class="help-block">${message:rememberMyPassword-help}</p>
</label>
/div>
...
Laboratorio - 42
Acción de Logout
 No existe página de Logout
 Como no requería plantilla, se ha implementado como un
ActionLink desde Layout.tml
 En la clase Layout se ha añadido el método
onActionFromLogout, responsable de la destrucción del
objeto que representa la sesión del usuario y de borrar las
cookies

...
@Property
@SessionState(create=false)
private UserSession userSession;

@Inject
private Cookies cookies;

Object onActionFromLogout() {
userSession = null;
CookiesManager.removeCookies(cookies);
return Index.class;
}
...

Laboratorio - 43
Gestión de Cookies en MiniPortal
 MiniPortal utiliza dos cookies para recordar la contraseña de un
usuario durante 30 días: loginName y encryptedPassword
 El método onValidateFromLoginForm de la página
user/Login
 Valida las credenciales del usuario (método login de UserService)
 Inicializa la propiedad userProfile
 El método onSuccess de la página user/Login añade las
cookies a la respuesta HTTP (CookiesManager.leaveCookies)
 Obtiene la información de contraseña encriptada de la propiedad
userProfile
 El método onActionFromLogout del componente Layout
destruye el objeto userSession y borra las cookies
(CookiesManager.removeCookies)
 Los métodos getLoginName y getEncryptedPassword de la
clase CookiesManager son utilizados para recuperar el nombre y
contraseña del usuario a partir de las cookies recibidas
 Más adelante se verá cómo se utilizan estos métodos para autenticar
de forma automática a un usuario, sin necesidad de introducir nombre
de usuario y contraseña, si el cliente posee las cookies loginName y
encryptedPassword

Laboratorio - 44
Mantenimiento de Sesión y Control de Acceso (1)

 Problema 1: Mantenimiento de la sesión


 Si un usuario se ha autenticado chequeando “recordar mi
contraseña”, cuando vuelva a acceder al portal debe de
autenticarse de forma automática si le caducó la sesión y las
cookies no han expirado
 Problema 2: Prohibir determinadas acciones a usuarios no
autenticados
 Si un usuario no autenticado intenta acceder a las páginas
“actualizar info. registro” o “cambiar contraseña”, o las asociadas a
sus botones de Submit, o a la asociada al enlace “Logout”, debería
redirigírsele a la página de autenticación
 En este caso la interfaz de usuario no presenta estas opciones a un
usuario no autenticado, pero podría ocurrir si no ha seleccionado
“recordar mi contraseña” y su sesión ha caducado
 Portal de comercio electrónico
 Normalmente permiten que cualquier usuario busque y añada
productos al carrito de la compra
 Cuando el usuario intenta comprar, si no se había autenticado, se le
redirige a la página de autenticación

Laboratorio - 45
Mantenimiento de Sesión y Control de Acceso (2)

 Todas las peticiones de páginas de Tapestry pasan


por el filtro de Tapestry configurado en el fichero
web.xml
 Ese filtro delega en diferentes cadenas de filtros para
realizar distintos procesamientos sobre la petición
 Tapestry permite añadir nuevos filtros a esas cadenas, para
realizar procesamientos adicionales.
 En particular, MiniPortal añade dos tipos de filtros diferentes
 Para resolver el problema 1: Mantenimiento de Sesión
 Añade un filtro que utiliza el servicio Cookies (clase
CookiesManager) para intentar recuperar las cookies
loginName/encriptedPassword
 Si encuentra las cookies, utiliza sus valores para autenticar al
usuario y crear el SSO UserSession.
 En otro caso, elimina las cookies, por ser inválidas

Laboratorio - 46
Mantenimiento de Sesión y Control de Acceso (y 3)

 En particular, MiniPortal añade dos tipos de filtros diferentes


(cont.)
 Para resolver el problema 2: Control de Acceso
 Define una política de acceso, con diferentes niveles, a través de
la enumeración AuthenticationPolicyType
 ALL_USERS. Cualquier usuario puede realizar esa acción
 AUTHENTICATED_USERS. Sólo puede acceder un usuario que
previamente se haya autenticado
 NON_AUTHENTICATED_USERS. Sólo pueden acceder usuarios que no
se hayan autenticado previamente
 Asigna un nivel de acceso a cada uno de los elementos (páginas o
métodos de procesamiento de eventos) de la aplicación a través
de la anotación AuthenticationPolicy.
 Valor por defecto ALL_USERS
 Añade un filtro que implementa la lógica que aplique la política de
acceso en base a las anotaciones de cada elemento solicitado y el
estado de la sesión del usuario (usuario autenticado o no
autenticado)

Laboratorio - 47
Uso del Arquetipo
 Uso del arquetipo
 Cómo añadir datos a la base de datos
 Cómo añadir una entidad persistente al modelo
 Cómo añadir una operación al modelo
 Cómo añadir un test de integración de la capa modelo
 Cómo añadir una página web
 Cómo habilitar el patrón “Open Session in View”

Laboratorio - 48
Añadir Datos a la Base de Datos
 Base de datos de pruebas y de ejecución de
aplicaciones
 MiniPortal utiliza dos bases de datos: una para pruebas
(tests) y otra para la ejecución de aplicaciones
 De esta manera, la ejecución de una aplicación no afecta a
las pruebas, y viceversa
 Para crear los datos necesarios para la ejecución de la
aplicación (e.g. categorías y productos en una tienda de
comercio electrónico)
 Añadir sentencias INSERT INTO en el siguiente script
 src/sql/2-MySQLCreateData.sql

Laboratorio - 49
Añadir una Entidad Persistente al Modelo
 Para añadir una nueva entidad persistente Xxx
 Crear la clase que implemente la entidad persistente en
es.udc.pojoapp.model/Xxx/Xxx
 Añadir la clase a la lista de mappings del fichero de
configuración de hibernate
<mapping class="es.udc.pojoapp.model/Xxx/Xxx" />
 Crear la interfaz en
es.udc.pojoapp.model.xxx.XxxDao que extienda del
DAO genérico, GenericDao<E, PK>
 Crear la clase de implementación en
es.udc.pojoapp.model.xxx.XxxDaoHibernate que
extienda de GenericDaoHibernate<E,PK> e implemente
XxxDao
 Anotarla con @Repository("xxxDao")
 Añadir métodos no soportados por el DAO genérico

Laboratorio - 50
Añadir una Operación al Servicio
 Crear una interfaz si se define un nuevo servicio
 Definir las operaciones del servicio
 Añadir método a la interfaz que define el servicio
 Crear una clase de implementación del servicio que implemente
la interfaz
 Anotar la clase para representar un servicio
 @Service("serviceName")
 Gestión declarativa de la transaccionalidad de las
operaciones
 Anotar la clase con @Transactional (redefinir en métodos
e.g. para optimizar: readOnly)
 Inyectar los DAOs necesarios para las operaciones
 @Autowired sobre las propiedades que almacenan las
instancias de los DAOs
 Definir las operaciones en términos de DAOs

Laboratorio - 51
Añadir un Test de Integración de la Capa Modelo

 Crear una nueva clase de test si se está probando un


nuevo servicio
 Anotar la clase con
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration, indicando la localización de los
ficheros de configuración de Spring
 @Transactional
 Inyectar los servicios y DAOs necesarios para la
implementación de los casos de prueba
 @Autowired sobre las propiedades que almacenan las
instancias de los servicios o DAOs
 Crear un método por cada caso de prueba y anotarlo con
@Test

Laboratorio - 52
Añadir una Página Web (1)
 Clase Java
 Para usar sesiones utilizar la anotación @SessionState
@SessionState(create=false)
private UserSession userSession;
 Para usar servicios del modelo utilizar la anotación @Inject
@Inject
private UserService userService;

 Plantilla
 Uso del componente Layout
<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"
t:type="Layout" t:title="title" showTitleInBody="false">
</html>

Laboratorio - 53
Añadir una Página Web (y 2)
 Control de acceso a la página / métodos
 Anotar los elementos de la aplicación (páginas o métodos de
procesamiento de eventos) de forma adecuada
 Usar la anotación @AuthenticationPolicy
 Especificar el nivel de acceso al recurso mediante uno de los
valores posibles de la enumeración
AuthenticationPolicyType
 Ejemplos
 Las páginas user/Login y user/Register son sólo aplicables
a usuarios que no se hayan autenticado todavía
@AuthenticationPolicy(
AuthenticationPolicyType.NON_AUTHENTICATED_USERS)
public class Login { ... }
 El evento logout del componente Layout sólo puede ser invocado
por usuarios que se hayan autenticado previamente
@AuthenticationPolicy(
AuthenticationPolicyType.AUTHENTICATED_USERS)
Object onActionFromLogout() { ... }

Laboratorio - 54
Habilitar Patrón “Open Session in View”

 Para habilitar el patrón “Open Session in View” es


necesario descomentar las siguientes secciones en el
fichero web.xml de la aplicación web

<filter>
<filter-name>openSessionInView</filter-name>
<filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>openSessionInView</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

 NOTA: MiniPortal no lo incluye habilitado porque no lo necesita

Laboratorio - 55
Jetty & Maven 3 (1)
 Jetty: Servidor HTTP y contenedor de servlets open source
escrito 100% en Java
 Maven 3 + plugin Jetty
 Desarrollo ágil: Permite ejecutar una aplicación Web sin
empaquetarla en un fichero WAR (entiende los directorios "src" y
"target" de la distribución fuente)
 El plugin puede configurarse para que detecte automáticamente
cambios en la aplicación web y la recargue, o para permitir una
recarga manual
 Ejecución:
 cd <module>
 mvn jetty:run
 Cargar en el navegador http://localhost:9090/<module>
 Ejemplo:
 cd pojo-minibank
 mvn jetty:run
 http://localhost:9090/pojo-minibank
 Para parar Jetty: CTRL-C
 Para recargar la aplicación web: ENTER

Laboratorio - 56
Jetty - Modificación del puerto por defecto (2)

 Por defecto se arranca en el puerto 8080


 En los ejemplos de la asignatura se ha configurado para que
arranque en el puerto 9090
 Se ha incluido el siguiente fragmento en la configuración del
plugin de Jetty (dentro del tag configuration)

<connectors>
<connector
implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
<port>9090</port>
</connector>
</connectors>

Laboratorio - 57
Jetty - Detección de cambios (3)
 Cambios a “ficheros Web estándar”
 Ficheros Web estándar: páginas JSP o ficheros HTML en
src/main/webapp
 Al igual que cualquier otro servidor de aplicaciones Java,
Jetty detecta automáticamente los cambios que se hagan a
este tipo de ficheros de forma transparente al desarrollador
 Cambios a plantillas y ficheros de mensajes
 Las plantillas y los ficheros de mensajes son conceptos
específicos a Tapestry (los ficheros de mensajes son
estándar, pero en nuestro caso, su uso está ligado a las
plantillas de Tapestry)
 Jetty utiliza las versiones disponibles en target/classes
(equivalente a WEB-INF/classes)
 Cuando Tapestry está configurado en modo desarrollo,
Tapestry detecta automáticamente los cambios que se
hagan a este tipo de ficheros de forma transparente al
desarrollador Laboratorio - 58
Jetty - Detección de cambios (4)
 Cambios a plantillas y ficheros de mensajes (cont)
 Si se importa el proyecto con m2eclipse, cuando se modifica un
fichero de recursos en src/main/resources, Eclipse lo copia
automáticamente a target/classes
 “Project -> Build Automatically” tiene que estar habilitado, o
alternativamente hay que ejecutar explícitamente “Project -> Build
Project” sobre el proyecto
 Si se utilizase otro IDE que no hiciese esta copia automáticamente,
basta hacer mvn process-resources
 En consecuencia, con nuestro entorno de desarrollo, cada vez que
se hace un cambio a una plantilla o un fichero de mensajes,
Tapestry lo detecta automáticamente de forma transparente al
desarrollador
 Cambios a ficheros fuente Java
 Los ficheros objeto de las clases Java residen en
target/classes
 Jetty, al igual que otros servidores de aplicaciones Java, no detecta
automáticamente los cambios a los ficheros objeto de las clases
Java (WEB-INF/classes)

Laboratorio - 59
Jetty - Detección de cambios (5)
 Cambios a ficheros fuente Java (cont)
 Es posible configurar Jetty para que recargue la aplicación
Web
 En la asignatura hemos optado por configurar Jetty para que
recargue la aplicación Web pulsando ENTER en la consola de
Jetty
 Si se importa el proyecto con m2eclipse, cuando se modifica
un fichero fuente Java, Eclipse lo copia automáticamente a
target/classes
 “Project -> Build Automatically” tiene que estar habilitado, o
alternativamente hay que ejecutar explícitamente “Project ->
Build Project” sobre el proyecto
 Si se utilizase otro IDE que no hiciese esta copia
automáticamente, basta hacer mvn compile
 Caso especial: cuando Tapestry está configurado en modo
desarrollo, Tapestry detecta automáticamente (y de forma
transparente al desarrollador) los cambios que se hagan a
las clases en los paquetes components y pages de la capa
Web
Laboratorio - 60
Jetty - Detección de cambios (6)
 Cambios a ficheros fuente Java (cont)
 En consecuencia
 Con nuestro entorno de desarrollo, cada vez que hacemos un
conjunto de cambios a ficheros Java que no estén en los
paquetes components y pages de la capa Web, y a
continuación queremos acceder a la aplicación Web, es
necesario pulsar ENTER en la consola de Jetty
 Si los cambios sólo afectan a clases que estén en los paquetes
components y pages de la capa Web, no es necesario hacer
nada
 Cambios en el resto de ficheros
 Ficheros de configuración de Spring/Hibernate, WEB-
INF/web.xml, etc.
 Es necesario pulsar ENTER en la consola de Jetty

Laboratorio - 61
Jetty – Depuración (y 7)
 Depuración Web
 Crear una configuración para ejecutar el goal “jetty:run”
 Arrancar Jetty a través del plugin de Maven 3 de Eclipse en
modo debug
 Run > Debug Configurations ...
 Maven Build > New para crear una nueva configuración o
elegir una configuración de maven existente
 Debug
 Icono “Debug” de la barra de herramientas > Elegir
configuración a ejecutar
 Para finalizar la ejecución de Jetty, hay que pulsar
sobre el botón rojo de la consola de Jetty en Eclipse
 Para más información sobre el plugin de Jetty puede
consultarse su documentación
 http://wiki.eclipse.org/Jetty/Feature/Jetty_Maven_Plugin

Laboratorio - 62
Apache Tomcat
 Configuración
 cd $HOME/software/apache-tomcat-8.0.9
 Seguir pasos del README.txt de los ejemplos

 Arranque:
 bin/startup.sh -> http://localhost:8080

 Finalización:
 bin/shutdown.sh

 Instalación de Aplicaciones
 Copiar el fichero WAR al directorio webapps

 LOGS
 logs/localhost.<FECHA>.log
 logs/catalina.out

Laboratorio - 63
Recomendaciones Finales
 Gestor de base de datos (MySQL)
 Finalizarlo de forma correcta para evitar que las Bases de
Datos se corrompan
 La práctica debe poder ser compilada y empaquetada
con maven 3, y ejecutada desde Tomcat, aunque se
utilicen Eclipse y Jetty como entorno de desarrollo

Laboratorio - 64

You might also like