Está en la página 1de 52

[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS

DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Introducción

En este tema veremos el acceso a datos mediante SPRING MVC y segurizarlo y testearlo así como

conoceremos la programación orientada a aspectos y profundizaremos en las capacidades

específicas de Spring.

es
2.
ca
lifi
ua
l.c
ua
irt
sv
pu
m
ca

campusvirtual.cualifica2.es
1 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Objetivos

Conocer el acceso de datos especiales para su uso.

Aprender las capacidades específicas de Spring.

es
2.
ca
lifi
ua
l.c
ua
i rt
sv
pu
m
ca

campusvirtual.cualifica2.es
2 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Mapa Conceptual

[[[Elemento Multimedia]]]

es
2.
ca
lifi
ua
l.c
ua
irt
sv
pu
m
ca

campusvirtual.cualifica2.es
3 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Introducción a Spring.

En el 2001 el API de Java Servlet y el modelo de Enterprise Java Beans eran las plataformas

imperantes para las aplicaciones web. Estos dos estándares fueron creados por la hoy extinta Sun

Microsystems colaborando con otras compañías y desarrolladores que contaban con bastante

popularidad en la comunidad de desarrollo en Java. Estas aplicaciones no se basaban en

soluciones web, como las aplicaciones cliente o las aplicaciones batch, que podían escribirse con la

base de utilidades y proyectos open source y comerciales que van a proveer las necesidades que

es
requerían aquellos proyectos.

2.
Se compuso un equipo pequeño de desarrolladores cuyo fin era ampliar el framework y crearon

ca
para ello un proyecto en Sourceforge en el año 2003. Tras más de un año de trabajo llegó la versión

lifi
1.0 en el 2004. Tras este lanzamiento, Spring se popularizó entre la comunidad, en parte gracias al

empleo de Javadoc y la disponibilidad de una documentación para los desarrolladores muy por
ua
encima del resto de proyectos open source.
l.c

Spring es un framework basado el patrón Modelo-Vista-Controlador. MVC es un patrón


ua

arquitectónico de software cuyo fin es separar en una aplicación los datos y la lógica de negocio

de la interfaz de usuario y de la parte que se encarga de la gestión de eventos y comunicaciones.


rt

Para lograrlo Modelo Vista Controlador propone una separación en tres capas diferenciadas que
i
sv

son el modelo, la vista y el controlador, de ahí su nombre. Esto es, primero define los elementos

destinados a representar la información y a interactuar con el usuario, por otra parte define los
pu

procedimientos para tratar tanto la información y transformas las peticiones y respuestas del
m

servidor y del cliente y por último se encarga de trabajar con la recuperación y almacenamiento

propiamente dicho de los datos. Este patrón de arquitectura se fundamenta en la reutilización de


ca

código y en la separación de los distintos conceptos que conforman una aplicación, persiguiendo

facilitar el desarrollo y el mantenimiento de las aplicaciones.

Aunque originalmente MVC se diseñó para programas de escritorio se ha ido adaptando a multitud

de arquitecturas para el diseño e implementación de aplicaciones web con la mayoría de

lenguajes de programación. Multitud de frameworks tanto comerciales como no comerciales se

han desarrollado implementando este patrón. La diferencia entre estos últimos es cómo

interpretan la funciones de Modelo, vista y controlador entre el cliente y el servidor.

campusvirtual.cualifica2.es
4 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

La finalidad de Spring es facilitar el desarrollo de aplicaciones web con Java. Sus características

son:

Simplicidad y acoplamiento débil: pretende ser simple y se basa en la inyección de

dependencias para obtener un acoplamiento débil. En resumen Inyección de dependencias

es un patrón software en el que un módulo suministra los objetos ya creados en lugar de que la

propia clase los cree.

Es un contenedor: es más que un framework normal, es un contenedor que gestiona el ciclo

es
de vida de los objetos y como se relacionan entre ellos.

2.
Ligero: es muy rápido en tiempo de procesamiento y no es intrusivo a la hora de programar.

ca
Esta es uno de sus características más importantes.

Orientado a aspectos: soporta la programación orientada a aspectos, lo que permite facilitar

lifi
una capa de servicios que son ideales para este tipo de programación como auditoría, o gestión
ua
de transacciones.
l.c

En Spring hay diversos módulos que se pueden se pueden utilizar en el desarrollo. Cada
ua

programador agrega los módulos que necesite. Spring Core es el núcleo de Spring, es el único

módulo que obligatoriamente debemos utilizar en Spring, ya que contiene entre otras cosas la DI
rt

(inyección de dependencias) y la configuración.


i
sv

Otros módulos conocidos son: AOP para trabajar con aspectos, DAO para trabajar con base de
pu

datos, MVC para la capa web, JMS para mensajería y Security para el control de seguridad.
m

En el 2003 el API de Java Servlet y el modelo de Enterprise Java Beans eran las
ca

plataformas imperantes para las aplicaciones web.

Verdadero.

Falso.

campusvirtual.cualifica2.es
5 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Spring MVC.

Spring es un framework basado el patrón Modelo-Vista-Controlador. En Spring las peticiones pasan

por un Servlet, el DispatcherServlet, este delega las peticiones a controladores los cuales llevan a

cabo la lógica de negocio. Pero el DispatcherServlet necesita conocer a qué controlador corresponde

cada petición, de esto se ocupa el HandlerMapping, si no hemos configurado uno por defecto se

utilizará la clase BeanNameUrlHandlerMapping.

es
2.
ca
lifi
ua
l.c
ua
irt
sv
pu
m

Como podemos ver el DispatcherServlet sirve de punto de entrada en las peticiones. Se la entrega a
ca

una clase HandlerMapping y esta le da el controlador apropiado. El controlador procesa la petición y

devuelve un modelo (datos) y una identificación de que vista usar. ViewResolver se ocupa de

devolver la vista al DispatcherServlet y este obtiene la respuesta a devolver.

Estructura de un controlador

campusvirtual.cualifica2.es
6 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

es
2.
ca
lifi
En Spring 2.5 se introdujo un modelo de programación basado en anotaciones para los

controladores, existen anotaciones como @RequestMapping, @RequestParam,


ua
@ModelAttribute, etc. El soporte de anotaciones también se soporta con Servlet MVC y Portlet

MVC. Los controladores que siguen este estilo no tienen que extender una clase especifica ni
l.c

implementar determinadas interfaces. Es más, normalmente no tienen que dependencia directa con
ua

las APIs de Servlet o Portlet. Sin embargo su acceso es fácilmente configurable.


rt

Con la siguiente anotación:


i
sv
pu

Se define una URL cuyas peticiones serán tardadas por el controlador, en este caso peticiones GET
m

y POST que son las implementadas en el ejemplo. Una petición GET es resultado de por ejemplo un
ca

usuario que consulta la página con un explorador web y POST cuando se envíen datos a través de un

formulario. Hay otros tipos que se pueden emplear como PUT y DELETE pero lo más habitual es

usar GET y POST.

Así mismo es posible ver cómo devuelve una secuencia de texto tanto el método GET como el

método POST:

campusvirtual.cualifica2.es
7 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Esta cadena indica la ubicación de la vista (sin la extensión .jsp), se traduciría a la ruta definida en

configuración para las vistas, generalmente en WEB-INF/views. Si por ejemplo se necesita

redireccionar al usuario a otra página o dirección externa, podemos hacerlo con la instrucción:

En versiones anteriores a la 2 se devolvía un objeto ModelAndView, devolviendo un String se evitan

dependencias y se ahorra código.

es
La nueva URL puede ser también la ubicación de una vista. Ahora en el caso del método post(), se

2.
observa entre los parámetros:

ca
lifi
ua
Significa que un formulario web envía la información usando dicha entidad, de la siguiente

manera:
l.c
ua
rt

Observamos también la instrucción @Valid junto a la variable:


i
sv
pu

Su función es realizar una validación de los parámetros que se han enviado por medio de la
m

entidad del formulario y guardar el resultado del procedimiento de en una variable result. Por
ca

ejemplo:

Si el cliente en el formulario web manda un

espacio en blanco, una letra acentuada, un subrayado u otro carácter inválido que no coincida con
la expresión regular, debe mostrarse el error previsto en la variable mensaje. Esto se haría tal que
así:

campusvirtual.cualifica2.es
8 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Viendo este ejemplo, si hay errores en el formulario, se devuelve a la vista empleando la variable

es
model. En el GET es posible ver como se ha cargado la página inicializando el formulario con la

instrucción siguiente:

2.
ca
Recordamos también que en la vista, para que el formulario muestre el mensaje de error debe de

lifi
tener la siguiente instrucción:
ua
l.c
ua

Manejo de sesiones
rt

Para utilizar una sesión con el mismo nombre, agregamos al inicio de la clase la anotación:
i
sv
pu
m
ca

Ahora cuando se hace esta

definición existen muchas maneras de implementar la sesión, esto es que se ha consultado la


bbdd y el usuario y contraseña sean correctos:

Aquí se envía la variable sesión a la vista, esta contiene una entidad que se llama usuario la cual

contiene el nombre, apellido, teléfono y demás detalles que determinan al usuario de la sesión.

campusvirtual.cualifica2.es
9 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

En el paso que sigue nos ponemos en el supuesto de que el usuario va a otro módulo en la

página, existen dos maneras de obtener la variable de sesión y realizar la validación del usuario

que realiza la consulta:

En este caso se valida que el atributo guardado en la estructura de sesión no sea nulo y en caso

es
contrario se hace un casting del objeto a Usuario. Para finalizar, cerramos la sesión de esta manera:

2.
ca
Recibir

lifi
parámetros por la URL y nuevos campos en el formulario POST
ua
También podemos captar parámetros como parte de la URL. Por ejemplo podemos obtener la id del
l.c

usuario que se va a editar, en este caso:


ua
i rt
sv

Ahora en los métodos GET y POST agregamos la siguiente variable:


pu
m

Ahora si se desea mandar una variable por medio de un


ca

formulario que no se encuentra en la entidad, se agrega así:

Puede ser cualquier campo válido para un formulario HTML (select, text, textarea...), esto es, no

usamos la biblioteca de Spring y enviamos esta variable por separado:

La

campusvirtual.cualifica2.es
10 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

instrucción anterior la agregamos a los parámetros que recibe el método POST. Esto puede ser
útil cuando por ejemplo en la base de datos guardamos la imagen como File y no como
MultipartFile, en ese caso tenemos que coger la imagen que se ha enviado por el form y
transformarla en File:

En la anotación anterior, la imagen enviada por el formulario es opcional.

es
Si el cliente en el formulario web manda un espacio en blanco, una letra
acentuada, un subrayado u otro carácter inválido que no coincida con la

2.
expresión regular, debe mostrarse el error previsto en la variable mensaje

ca
Verdadero.

lifi
Falso. ua
l.c
ua
irt
sv
pu
m
ca

campusvirtual.cualifica2.es
11 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Acceso a Datos

Uno de los grandes problemas que tiene hoy en día el desarrollo de aplicaciones Web en Java es que

el ciclo de desarrollo es, en muchas ocasiones, demasiado largo (o por lo menos más largo de lo

que nos gustaría.

Debido a este problema han surgido alternativas del estilo de Ruby on Rails

(http://www.rubyonrails.org/) o incluso Google App Engine (http://code.google.com/appengine/)

es
una alternativa que propone Google, basada en el lenguaje Python.

2.
Todas estas alternativas pueden resultar muy interesantes, pero suelen estar basadas en lenguajes

ca
con chequeo de tipos débil, o trasladando el chequeo de tipos a tiempo de ejecución (como Python),

lo que provoca que puedan ser muy útiles para hacer rápidamente pequeñas aplicaciones o

lifi
prototipos, pero que se pueden convertir en un gran problema cuando queremos construir
ua
aplicaciones medianas o grandes donde intervienen varias personas o incluso equipos en el proceso

de desarrollo. Para este caso de aplicaciones medianas o grandes y grupos de desarrollo


l.c

colaborativos, se hace necesario un lenguaje fuertemente tipado, donde podamos definir jerarquías
ua

de tipos (clases o interfaces) en las que el resto del equipo se pueda apoyar para desarrollar sin

riesgos.
i rt

En este apartado veremos cómo gracias a Spring + Hibernate + Anotaciones podemos conseguir
sv

un desarrollo tan rápido como el que podemos conseguir con las alternativas antes mencionadas.
pu

Ya hemos visto en otros tutoriales el uso de Spring o Hibernate, pero en este tutorial vamos a
m

intentar sacar todo el partido a las Anotaciones de Java 5 para, basándonos en el concepto de
ca

“convención frente a configuración”, centrarnos en el código, olvidarnos de la base de datos y de

esos tediosos ficheros de configuración en XML.

Con esto no quiero decir que debamos olvidarnos por completo de esos ficheros XML, sino que

debemos centrarnos a resolver el problema que nos ocupa, de forma rápida y con un buen diseño,

consiguiendo un código legible y mantenible. Si luego queremos hacer ciertos refinamientos, o

virguerías, los XML siempre estarán esperándonos para poder sobreescribir el comportamiento

establecido con las anotaciones.

campusvirtual.cualifica2.es
12 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Vamos a hacer una pequeña aplicación donde se muestre un listado de productos. Podría quedar

algo como:

es
2.
ca
lifi
ua
l.c
ua
rt

Y la pantalla de edición de productos:


i
sv
pu
m
ca

campusvirtual.cualifica2.es
13 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

es
2.
ca
lifi
ua
l.c
ua

La capa de persistencia

Vamos a empezar “de abajo a arriba”, es decir, partiremos definiendo nuestras entidades
rt

persistentes con Hibernate, e iremos “subiendo” hasta la capa de presentación y control con JSF,
i
sv

pasando antes por el negocio (el modelo) con Spring.


pu

Las entidades
m

En nuestro ejemplo solo tenemos la entidad producto, con los atributos nombre, descripción y
ca

precio.

Veamos como nos quedaría la clase:

campusvirtual.cualifica2.es
14 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

es
2.
ca
lifi
ua
l.c
ua
i rt
sv
pu
m

Podemos ver como se trata de una clase totalmente normal, donde en la línea 1 anotamos que se

trata de una entidad, y en las líneas 3 y 4 indicamos cual es el id de la entidad y que este id será
ca

generado por la base de datos.

Cabe destacar dos cosas:

Todas las notaciones usadas pertenecen al estándar de JPA por lo que son válidas tanto para

Hibernate como para EJB3.0.

Hemos anotado un atributo privado que no se usa en ningún sitio, ni siquiera tenemos getter o

setter. Esto lo hacemos a posta ya que es algo que gestionará internamente Hibernate, y

campusvirtual.cualifica2.es
15 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

queremos condicionar lo menos posible nuestro diseño (nuestro negocio).

El DAO

El DAO es el Data Access Object, es decir, será la clase donde resida la lógica de manejo de

Hibernate (o JDO o JDB o JPA o …). De esta forma conseguimos que nuestra lógica de negocio no

sepa nada de Hibernate, y siempre que quiera acceder a los datos lo hará usando esta clase.

es
Veamos un ejemplo sencillo: Primero definimos una interfaz, así podemos intercambiar la

implementación fácilmente si algún día nos cansamos de Hibernate (no lo creo ;):

2.
ca
lifi
ua
l.c
ua
rt

Para el ejemplo solo hemos definido algunas operaciones simples. Ahora veamos una posible
i
sv

implementación usando las facilidades que nos proporciona Spring + Hibernate:


pu
m
ca

campusvirtual.cualifica2.es
16 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

es
2.
ca
lifi
ua
l.c
ua
i rt
sv

No es el ámbito de este tutorial estudiar la implementación de los métodos, para más información
pu

sugiero al lector repasar otros tutoriales relacionados o acudir a la documentación de Spring e


m

Hibernate y la documentación sobre Generics de Java.


ca

Aunque el lector en un principio no entienda la implementación lo que creo que queda claro es que

es sencilla, puesto que se limita a unas pocas líneas (de nuevo sugiero repasar la documentación).

Donde si vamos a hacer especial hincapié es en las nuevas anotaciones que nos han aparecido:

En la línea 1 nos encontramos con @Repository. Esta es una anotación de Spring. Estamos

indicando que esta es una clase relacionada con la capa de persistencia, y que debe ser un

Singleton (solo habrá una instancia de la clase HibernateDaoSupport, y todos los Threads de la

aplicación la compartirán).

campusvirtual.cualifica2.es
17 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

En la línea 4 nos encontramos con @Autowired. Esta es una anotación de Spring. Sirve para

indicarle a Spring que cuando vaya a crear la instancia de HibernateDaoSupport debe

“inyectarle” (pasarle) en el constructor una referencia al SessionFactory (el SessionFactory sí

lo configuraremos mediante XML, lo veremos más adelante).

Por último, en la línea 9, 14, 20 … nos encontramos con la anotación @Transactional. Esta es

una anotación de Spring. Estamos indicando que el método en cuestión es transaccional. Lo

que hará Spring es comprobar si ya existe una transacción abierta, si existe se unirá a ella, y si

no existe, abrirá una nueva transacción (este comportamiento es configurable). De esta forma

es
nos aseguramos que toda operación de la base de datos se realiza dentro de una transacción.

2.
Además si durante la ejecución del método se produce alguna excepción de Runtime, se hará

ca
automáticamente rollback de la transacción (este comportamiento también es configurable).

lifi
Ya hemos terminado con la capa de persistencia. Rápido ¿verdad? En ningún momento hemos visto
ua
sentencias SQL, ni siquiera para crear las tablas de la base de datos. Más adelante veremos cómo

configuramos Hibernate para que se encargue de crearnos las tablas automáticamente (Los ficheros
l.c

de configuración los veremos todos al final, por ahora sigamos con el código Java).
ua

La capa de negocio
rt

En esta aplicación el negocio no es gran cosa, poco más que obtener los productos o guardarlos, así
i
sv

que la clase nos va a quedar muy sencillita:


pu
m
ca

campusvirtual.cualifica2.es
18 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Haciendo una clase tan sencilla y que lo único que hace es delegar en el DAO, hay quien me podría

acusar de estar cayendo en el antipatrón “Poltergeist”, ya que desde control podríamos usar

directamente el DAO para recuperar o guardar los productos, y quitarnos esta clase de enmedio.

Pero no creo que este sea el caso ya que prima el MVC y el bajo acoplamiento.

Siempre debemos intentar que la capa de control y presentación sean lo más tontas posibles. Pensar

por un momento que no usamos esta clase “manager” y que usamos el DAO desde las clases de

control de JSF (los managed-beans), si ahora quisiéramos montar un web service para

es
aprovechar esta aplicación desde otras aplicaciones ¿cuánto código que ya habríamos escrito en el

2.
managed-bean tendríamos que repetir en el web service?

ca
Pero vamos al lío, que hemos venido a hablar de las anotaciones

lifi
En la línea 1 nos encontramos con @Service. Esta es una anotación de Spring, similar a
ua
@Repository que ya habíamos visto antes. Estamos indicando que esta es una clase relacionada

con la capa de servicio (clases de negocio), y que debe ser un Singleton.


l.c

En la línea 4 nos encontramos con @Resoruce. Esta anotación es del estándar, por lo que es
ua

válida tanto con Spring como con EJB3.0. Está indicando que al crear la instancia de esta clase

se debe “inyectar” (inicializar) en este atributo una referencia a la instancia del Dao (es la
rt

instancia que habíamos declarado anteriormente con @Repository).


i
sv

Vamos a implementar el control con los managed-beans de JSF. Como tenemos dos pantallas
pu

podemos hacer dos managed-bean.


m

El de la pantalla con el listado de productos nos podría quedar algo como:


ca

campusvirtual.cualifica2.es
19 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

es
2.
ca
lifi
ua
l.c
ua
rt

La clase para la edición de los productos:


i
sv
pu
m
ca

campusvirtual.cualifica2.es
20 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Fijándonos en la clase de listado, las nuevas anotaciones que aparecen son:

En la línea 1 nos encontramos con @Controller. Esta es una anotación de Spring, similar a

@Repository o @Service que ya habíamos visto antes. Estamos indicando que esta es una clase

relacionada con la capa de control.

En la línea 2 nos encontramos con @Scope("session"). Esta es una anotación de Spring. Con

ella estamos sobreescribiendo el comportamiento por defecto de Spring, que es hacer

Singletons, y le estamos diciendo que nos cree una instancia diferente de esta clase por cada

es
sesión Http. Es decir, cada usuario tendrá su propio managed-bean.

2.
También cabe destacar desde la línea 5 hasta la 9. La anotación @Resource ya la hemos

ca
comentado antes, pero quiero recalcar como se está “inyectando” la referencia al manager (la

clase de negocio) y la referencia a otro managed-bean de la capa de control de JSF, es decir,

lifi
Spring es capaz de gestionar las dependencias entre los diferentes managed-beans de JSF.
ua
La capa de presentación
l.c

Está implementada con JSF + Facelets + ICEfaces, pero no tiene nada de especial. Es decir la

construiremos como habitualmente se trabaja con estas tecnologías.


ua

Cuando queramos acceder a los managed-beans desde el Expression Language simplemente lo


rt

haremos. Por ejemplo:


i
sv
pu
m
ca

Hibernate.cfg.xml (configuración de Hibernate)

campusvirtual.cualifica2.es
21 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

En la línea 9 es donde le estamos diciendo a Hibernate que queremos que nos cree las tablas al

arrancar la aplicación. Ojo porque si las tablas ya existen las borra primero, es decir, esto puede ser

muy conveniente para desarrollo o pruebas, pero no para producción ! Lo que podemos hacer es,

una vez están creadas, hacer un “export” de la base de datos para obtener los scripts de creación

que podemos retocar para dejarlos listos para producción (pero nos ahorramos lo gordo).

ApplicationContext.xml (configuración de Spring)

es
2.
ca
lifi
ua
l.c
ua
i rt
sv
pu
m
ca

Puede parecer que hay mucho pero en realidad solo hay 4 cosas: configuración de Spring para que

haga caso a las anotaciones, definir el datasource (de hibernate, del servidor por jndi, …), definir el

campusvirtual.cualifica2.es
22 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

sessionFactory de Hibernate, y definir el transactionManager (el de Hibernate, JTA, …)

Si os fijáis no hay ni una sola definición de bean de clases que hayamos escrito nosotros, de forma

que este fichero se mantendrá constante con independencia de los beans que tenga nuestra

aplicación.

Faces-config.xml (configuración de JSF)

es
2.
ca
lifi
ua
l.c
ua
i rt
sv
pu

Se puede apreciar como solo hay configuración general de JSF y reglas de navegación. Pero no
m

declaramos ningún managed-bean. Esto funciona gracias a la línea 13 donde se le indica a JSF que
ca

debe delegar en Spring para buscar los managed-beans. Es decir, JSF los buscará entre los que

declaremos en el fichero (si es que declaramos alguno, que no es nuestro caso), y si no lo encuentra,

lo buscará en Spring.

Como se puede comprobar, también nos ahorramos escribir cantidad de código en ese XML.

Diferencia entre las anotaciones @Repository, @Service, @Controller

La diferencia es básicamente semántica, es decir, cada una denota perfectamente a que “capa”

corresponde la clase anotada. Pero todas se comportan de igual manera (por ejemplo en todas

campusvirtual.cualifica2.es
23 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

nuestras clases podríamos haber usado la anotación @Service y hubiera funcionado igual).

Esto se consigue porque las tres anotaciones extienden la anotación @Component.

El hecho de usar anotaciones diferentes puede ser muy interesante si luego queremos aplicar

aspectos (AOP = Aspect Oriented Programming) a todas las clases de una misma capa. Es decir, por

ejemplo, puedo hacer una regla para aplicar cierto advice a todas las clases con la anotación

@Controller.

es
El DAO es el Data Access Object, es decir, será la clase donde resida la lógica de

2.
manejo de Hibernate (o JDO o JDB o JPA o …). De esta forma conseguimos que

ca
nuestra lógica de negocio no sepa nada de Hibernate, y siempre que quiera
acceder a los datos lo hará usando esta clase.

lifi
Verdadero.
ua
Falso.
l.c
ua
irt
sv
pu
m
ca

campusvirtual.cualifica2.es
24 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Programación Orientada a Aspectos (AOP.

Con bastante frecuencia, necesitamos producir fragmentos de código diseminados por la

totalidad o gran parte de la aplicación, para plasmar la lógica de alguna propiedad o

características del sistema, con las dificultades asociadas al mantenimiento y al desarrollo. Este

problema es conocido como scattered code, que se puede traducir como código disperso. Otro

problema que puede surgir, es que en un módulo concreto tenga que implementar varios aspectos

de la aplicación a la vez. Este problema es conocido como tangle code, que se puede traducir como

es
código enmarañado. A día de hoy existen algunos rumbos de diseño complicados de capturar,

2.
porque algunos problemas no pueden encapsularse de manera clara de la misma manera con la que

ca
normalmente resolvemos la definición de otra funcionalidad u otros objetos.

lifi
La Programación Orientada a Aspectos o AOP (Aspect Oriented Programming) es un paradigma

de programación cuya intención es formalizar y representar de forma concisa los elementos que son
ua
transversales (comunes) a todo el sistema. De esta forma se pueden encapsular los diferentes
l.c

conceptos que componen una aplicación en entidades bien definidas, eliminando las dependencias

entre los módulos.


ua

En la orientación a objetos , el sistema se basa en la idea de clases y sus jerarquías. La herencia


rt

permite modularizar el sistema, evitando la duplicación de código. Sin embargo, hay aspectos que
i
sv

son comunes a todo el sistema, como por ejemplo un sistema en el que se debe verificar que el

usuario tenga permiso para manipular un objeto:


pu

public class UnObjeto {


m

protected void compruebaPermisos() throws NoPermitidoException {


//comprobamos los permisos y si no esta permitido lanzamos excepción
ca

}
public void metodoRestringido() throws NoPermitidoException {
compruebaPermisos();
//código
}
public void metodoRestringido() throws NoPermitidoException {
compruebaPermisos();
//código
}
}

Como se puede ver, se puede minimizar la repetición de código, tenemos una llamada en cada

método y una sentencia throws, pero es prácticamente imposible reducir aún más la repetición.

campusvirtual.cualifica2.es
25 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Objetivo: la Programación Orientada a Aspectos tiene la misión principal de separar las

funcionalidades en el sistema.

Por una parte las funcionalidades habituales empleadas en la aplicación.

Por otra parte, la funcionalidad intrínseca de cada parte.

Conceptos básicos de AOP:

Aspecto (Aspect): es una funcionalidad transversal (cross-cutting) que se implementara de

es
forma modular y separada del resto del sistema.

Punto de Cruce o de Unión (Join point): es un punto de ejecución dentro del sistema donde

2.
un aspecto puede ser conectado, como una llamada a un método, el lanzamiento de una

ca
excepción o la modificación de un campo. El aspecto será insertado en el flujo de ejecución de

lifi
la aplicación para ampliar su funcionalidad.

Consejo (Advice): es la implementación del aspecto, dicho de otra manera, un Aspecto puede
ua
alterar el comportamiento el código aplicando un Consejo (comportamiento adicional) en un
l.c

Punto de Unión.

Puntos de Corte (Pointcut): define los Consejos que se aplicarán a cada Punto de Cruce. Se
ua

especifica mediante Expresiones Regulares o mediante patrones de nombres (de clases,


rt

métodos o campos), e incluso dinámicamente en tiempo de ejecución según el valor de ciertos


i

parámetros.
sv

Introducción (Introduction): permite añadir métodos o atributos a clases ya existentes. Por


pu

ejemplo supongamos que queremos mantener la información de la última modificación a un

objeto, para ello crearíamos un Consejo de Auditoría que mantenga la dicha información,
m

mediante una variable y un método, que serían introducidos en todas las clases (o sólo en
ca

algunas) para tener esta nueva funcionalidad.

Destinatario (Target): con target nos referimos a la clase "aconsejada".

Intermediario (Proxy): es el objeto resultante de aplicar el Consejo al Destinatario, cuando se

llama a un método de un objeto que ha sido "aconsejado" es el Intermediario el que la recibe y

redirige la llamada al objeto original o al método definido en el Consejo.

Tejido (Weaving): es el proceso de aplicar Aspectos a los Objetos Destinatarios para crear los

nuevos Objetos Resultantes en los especificados Puntos de Cruce. Este proceso puede ocurrir a

lo largo del ciclo de vida del Objeto Destinatario:

campusvirtual.cualifica2.es
26 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Aspectos en Tiempo de Compilación, que necesita un compilador especial.

Aspectos en Tiempo de Carga, los Aspectos se implementan cuando el Objeto

Destinatario es cargado. Requiere un ClassLoader especial.

Aspectos en Tiempo de Ejecución.

Mediante la Programación Orientada a Aspectos evitamos la dispersión del código y la

es
implementación queda más comprensible, adaptable y reusable. Algunas tecnologías con
diferentes nombres se dirigen a la consecución de objetivos similares, el término Programación

2.
Orientada a Aspectos se emplea para hacer referencia a múltiples tecnologías que se relacionan
en como los métodos se adaptan, como los filtros de composición o la separación en varias

ca
dimensiones de competencias.

lifi
ua
l.c
ua
i rt

Como ya se ha dicho, un punto de corte o pointcut es un punto de interés en el código antes,


sv

después o "alrededor" del cual queremos ejecutar algo (un advice). Un pointcut no puede ser
pu

cualquier línea arbitraria de código. La versión actual de Spring solo soporta puntos de corte en

ejecuciones de métodos de beans. La implementación completa de AspectJ permite usar también el


m

acceso a campos, la llamada a un constructor, etc., aunque esto en AOP de Spring no es posible.
ca

Es importante destacar que al definir un pointcut realmente no estamos todavía diciendo que

vayamos a ejecutar nada, simplemente marcamos un "punto de interés". La combinación de

pointcut + advice es la que realmente hace algo útil. Por ello, los ejemplos dados en este apartado

por sí solos no tienen demasiado sentido, no hay que intentar probarlos tal cual, aunque aquí los

explicaremos aislados para poder describir con cierto detalle su sintaxis antes de pasar a la de los

advices.

Lo que sigue es un conjunto de ejemplos que ilustran las opciones más comunes para pointcuts, no

campusvirtual.cualifica2.es
27 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

una referencia exhaustiva, que no tendría sentido estando ya la documentación de Spring y la de

AspectJ para ello.

Expresiones más comunes

La expresión más usada en pointcuts de Spring es execution(), que representa la llamada a un

método que encaje con una determinada signatura. Se puede especificar la signatura completa del

método incluyendo tipo de acceso (public, protected,...), tipo de retorno, nombre de clase

(incluyendo paquetes), nombre de método y argumentos. Teniendo en cuenta:

es
2.
El tipo de acceso y el nombre de clase son opcionales, pero no así el resto de elementos

Podemos usar el comodín * para sustituir a cualquiera de ellos, y también el comodín .., que

ca
sustituye a varios tokens, por ejemplo varios argumentos de un método, o varios subpaquetes

lifi
con el mismo prefijo.

En los parámetros, () indica un método sin parámetros, (..) indica cualquier número de
ua
parámetros de cualquier tipo, y podemos también especificar los tipos, por ejemplo (String, *,
l.c

int) indicaría un método cuyo primer parámetro es String, el tercero int y el segundo puede ser

cualquiera.
ua
rt

Por ejemplo, para especificar todos los métodos con acceso "public" de cualquier clase dentro del
i

paquete es.ua.jtech.aop pondríamos:


sv
pu
m

Donde el primer * representa cualquier tipo de retorno, el segundo * cualquier clase y el tercer *
ca

cualquier método. Los .. representan cualquier conjunto de parámetros

Algunos ejemplos más de execution()

campusvirtual.cualifica2.es
28 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

within() permite especificar todos las llamadas a métodos dentro de un paquete o subpaquetes del

mismo (usando el comodín .. al igual que en la sintaxis de execution()).

args() permite especificar el tipo deseado para los argumentos. No se suele usar tal cual, sino

combinado con execution como un "truco" para darle nombre a los argumentos (ver el apartado

es
siguiente).

2.
ca
lifi
ua
Combinar pointcuts
l.c

Se pueden combinar pointcuts usando los operadores lógicos &&, || y !, con el mismo significado que

en el lenguaje C. Por ejemplo:


ua
irt
sv

El operador && se suele usar en conjunción con args como una forma de "dar nombre" a los
pu

parámetros, por ejemplo:


m
ca

Encajaría con un setter cualquiera, dándole el nombre nuevoValor al parámetro pasado al mismo.

Veremos la utilidad de esto, cuando definamos advices, como método para acceder al valor del

parámetro.

Pointcuts con nombre

Se le puede asignar un nombre arbitrario a un pointcut (lo que se denomina una signatura). Esto

permite referenciarlo y reutilizarlo de manera más corta y sencilla que si tuviéramos que poner la

expresión completa que lo define. La definición completa consta de la anotación @Pointcut seguida

campusvirtual.cualifica2.es
29 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

de la expresión que lo define y la signatura. Para definir la signatura se usa la misma sintaxis que

para definir la de un método Java en un interfaz. Eso sí, el valor de retorno debe ser void. Por

ejemplo:

Esta signatura se puede usar por ejemplo al combinar pointcuts:

es
2.
ca
lifi
ua
Advices
l.c

Con los advices ya tenemos la pieza del puzzle que nos faltaba para que todo cobre sentido. Un

advice es algo que hay que hacer en un cierto punto de corte, ya sea antes, después, o "alrededor"
ua

(antes y después) del punto.


rt

Los advices se especifican con una anotación con el pointcut y la definición del método Java a
i
sv

ejecutar (signatura y código del mismo). Como en Spring los puntos de corte deben ser ejecuciones

de métodos los casos posibles son:


pu
m

Antes de la ejecución de un método (anotación @Before)

Después de la ejecución normal, es decir, si no se genera una excepción (anotación


ca

@AfterReturning)

Después de la ejecución con excepción/es (anotación @AfterThrowing)

Después de la ejecución, se hayan producido o no excepciones (anotación @After)

Antes y después de la ejecución (anotación @Around)

Un aspecto (aspect) es un conjunto de advices. Siguiendo la sintaxis de AspectJ, los aspectos se

representan como clases Java, marcadas con la anotación @Aspect. En Spring, además, un aspecto

debe ser un bean, por lo que tendremos que anotarlo como tal.

campusvirtual.cualifica2.es
30 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

@Before

es
Esta anotación ejecuta un advice antes de la ejecución del punto de corte especificado. Por ejemplo:

2.
ca
lifi
ua
l.c
ua

Ejecutaría controlaPermisos() antes de llamar a cualquier getter.


rt

@AfterReturning
i
sv

Esta anotación ejecuta un advice después de la ejecución del punto de corte especificado, siempre

que el método del punto de corte retorne de forma normal (sin generar excepciones). Por ejemplo:
pu
m
ca

Evidentemente para hacer log nos puede interesar saber el valor retornado por el método del punto

de corte. Este valor es accesible con la sintaxis alternativa:

campusvirtual.cualifica2.es
31 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Al poner Object como tipo de la variable asociada al valor de retorno, estamos indicando que nos da

es
igual el tipo que sea (incluso si es primitivo). Especificando un tipo distinto, podemos reducir el

2.
ámbito del advice para que solo se aplique a los puntos de corte que devuelvan un valor del tipo

deseado.

ca
lifi
@AfterThrowing
ua
Esta anotación ejecuta un advice después de la ejecución del punto de corte especificado, si el

método del punto de corte genera una excepción. Podemos tanto acceder a la excepción generada
l.c

como restringir el tipo de las excepciones que nos interesan, usando una sintaxis como la siguiente:
ua
i rt
sv
pu
m
ca

El ejemplo anterior indicaría que no hay que ejecutar el advice a menos que la excepción generada

sea del tipo DAOException, y nos permite acceder a su valor a través del parámetro daoe.

@After

Esta anotación ejecuta un advice después de la ejecución del punto de corte especificado, genere o

no una excepción, es decir, al estilo del finally de Java. Se usa típicamente para liberar recursos y

otras tareas habituales para finally.

campusvirtual.cualifica2.es
32 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

@Around

Esta anotación ejecuta parte del advice antes y parte después de la ejecución del punto de corte

especificado. La filosofía consiste en que el usuario es el que debe especificar en el código del advice

en qué momento se debe llamar al punto de corte. Por ello, el advice debe tener como mínimo un

parámetro de la clase ProceedingJoinPoint, que representa el punto de corte. Llamando al método

proceed() de esta clase, ejecutamos el punto de corte. Por ejemplo:

es
2.
ca
lifi
ua
l.c

Hay que destacar varias cuestiones del código anterior. Como ya se ha dicho, cuando queremos
ua

llamar al punto de corte invocamos a proceed(). Además debemos devolver como valor de retorno
rt

del advice el devuelto por el punto de corte. Finalmente, si el método del punto de corte requiere
i

parámetros, podemos pasarle un Object[].


sv

Acceder a los parámetros y otra información del punto de corte


pu

Spring ofrece al advice acceso tanto a los parámetros del método del punto de corte como a
m

información adicional sobre el mismo. Ya hemos visto cómo acceder al valor de retorno, en el
ca

ejemplo de @AfterReturning, y a la excepción lanzada en el caso del @AfterThrowing.

Para hacer accesibles al advice los argumentos del punto de corte se puede usar args. Por ejemplo:

Con esto enlazamos el valor del argumento del punto de corte con la variable nuevoValor, y además

campusvirtual.cualifica2.es
33 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

al poner int como tipo de nuevoValor indicamos que solo queremos aplicar el advice si el argumento

del punto de corte es int.

Otra forma de hacer lo anterior sería usar un punto de corte "con nombre":

es
2.
ca
Podemos acceder a información sobre el punto de corte en el primer parámetro del advice si es de

tipo JoinPoint. Esta clase tiene métodos para obtener por ejemplo la signatura del método del punto

lifi
de corte, o sus argumentos, etc.
ua
l.c
ua
rt

Más de un advice para el mismo punto de corte


i

Aunque no se ha dicho explícitamente hasta el momento, por supuesto se puede definir más de un
sv

advice que encaje con el mismo punto de corte. La pregunta surge entonces de forma natural: ¿cuál
pu

es el orden de aplicación de los advices?


m

Para los advices especificados dentro del mismo aspecto, se puede tomar como una regla básica que
ca

el orden de ejecución es el mismo que el de declaración. Es decir, que si declaramos varios advices

de tipo before, se ejecutará primero el que primero aparezca declarado, y si declaramos varios de

tipo after ocurrirá lo mismo (en realidad en el caso after si se piensa un poco se verá que el de

mayor importancia es el que se ejecuta el último).

El caso en que tenemos advices definidos en aspectos distintos es más complejo, ya que en principio

no está definida la precedencia por defecto y para especificarla hay que escribir algo de código Java.

En concreto el aspecto debe implementar el interface org.springframework.core.Ordered. Remitimos

al lector a la documentación de Spring para más información.

campusvirtual.cualifica2.es
34 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

AOP "implícita" en Spring 3

La AOP constituye uno de los pilares en que se fundamenta Spring, incluso aunque nunca la

usáramos en nuestros proyectos de modo explícito. A continuación resumimos alguno de los usos

directos de AOP en el framework:

Transaccionalidad declarativa: la gestión automática de las transacciones implica la

intercepción AOP de los métodos marcados como transaccionales. El TransactionManager es el

es
que intercepta los métodos y se encarga de crear nuevas transacciones, hacer rollback

automáticos, etc. según sea necesario.

2.
Seguridad: Spring Security es un proyecto que intenta mejorar la seguridad declarativa

ca
estándar de JavaEE, haciéndola más potente sin aumentar la complejidad de uso. Mediante

este proyecto se puede por ejemplo controlar de manera declarativa el acceso a los métodos de

lifi
los beans, de manera similar a como se hace en Servlets 3.0:
ua
l.c
ua
rt

Pero va mucho más allá, permitiendo el uso de expresiones en el lenguaje EL de Spring para
i

evaluar los permisos de acceso. Por ejemplo, queremos que también el propio usuario pueda borrar
sv

su cuenta, además del administrador:


pu
m
ca

• authentication.name sería el login del usuario que se ha autentificado, y estamos intentando

comprobar si corresponde con el del usuario que queremos borrar (el # nos da acceso al parámetro).

• Spring Roo: es un framework de desarrollo rápido de aplicaciones. Crea la estructura CRUD de la

aplicación usando Spring en todas las capas (presentación, negocio y datos). Todo el código

necesario se introduce de forma "no invasiva" usando AOP. Por ejemplo si decimos que queremos

usar JPA en la capa de persistencia, Roo se encarga de convertir nuestra clase de dominio en una

entidad JPA y de gestionar el Entity Manager y los métodos JPA básicos, pero todo este código no

campusvirtual.cualifica2.es
35 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

será visible directamente en nuestras clases y no nos "molestará". Todo esto se hace usando AspectJ,

aunque es un uso más avanzado que el que nosotros hemos visto aquí.

• Cache declarativa: es una de las nuevas características incorporadas en la versión 3.1. Nos

permite usar de manera transparente frameworks para gestión de cache ya conocidos y muy

probados como Ehcache. Por ejemplo, podemos hacer que un método de un DAO cachee

automáticamente los resultados sin más que usar la anotación correspondiente:

es
2.
ca
Si ya se ha llamado anteriormente al método con el mismo valor de "isbn", en lugar de ejecutar el

lifi
método, se sacará el LibroTO de la cache. Lo que está pasando es que con AOP se está

interceptando el método con @Before y comprobando si es necesario o no ejecutarlo.


ua
l.c

El operador && se suele usar en conjunción con args como una forma de "dar
nombre" a los parámetros.
ua

Verdadero.
irt

Falso.
sv
pu
m
ca

campusvirtual.cualifica2.es
36 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Gestión de Transacciones.

En una base de datos una transacción es una secuencia de acciones que se tratan como una sola

unidad de trabajo. Estas acciones se deben completar o no tener ningún efecto en absoluto, es decir

si ocurre algún inconveniente en alguna instrucción la transacción se interrumpe y los cambios

realizados no permanecen. La gestión de transacciones es una parte importante de toda aplicación

empresarial orientada a un Sistema de Gestión de Base de Datos Relacionales (siglas en inglés

RDBMS) para garantizar la integridad y la coherencia de los datos.

es
El concepto de transacciones se puede describir con las siguientes cuatro propiedades clave

2.
descritas como ACID:

ca
lifi
Atomicity (Atomicidad): una transacción debe ser tratada como una sola unidad de

operación, lo que significa que toda la secuencia de operaciones es exitosa o no.


ua
Consistency (Consistencia): la consistencia de la integridad referencial de la base de datos,
l.c

como claves primarias que deben ser únicas y sus referencias desde otras tablas.

Isolation (Aislamiento): puede haber muchas transacciones siendo procesadas al mismo


ua

tiempo y con el mismo conjunto de datos. Cada transacción debe aislarse de otras para evitar la

corrupción de datos.
rt

Durability (Durabilidad): una vez que una transacción ha terminado, los resultados de esta
i
sv

transacción tienen que ser permanentes y no se pueden borrar de la base de datos debido al
pu

fallo del sistema.


m

Spring proporciona una capa de abstracción sobre las diferentes APIs de gestión de transacciones
ca

subyacentes. El soporte de transacciones de Spring tiene como objetivo proporcionar una alternativa

a las transacciones de EJB agregando capacidades de transacción a POJOs. Spring soporta tanto la

gestión programática como declarativa de transacciones.

Tradicionalmente, los desarrolladores de Java EE han tenido dos opciones para la gestión de

transacciones: transacciones globales o locales, ambas opciones tienes determinadas limitaciones.

Transacciones globales

La gestión transacciones globales se requiere en un entorno de computación distribuida en el que

campusvirtual.cualifica2.es
37 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

todos los recursos se distribuyen a través de múltiples sistemas. En tal caso, la gestión de

transacciones debe realizarse tanto a nivel local como global. Una transacción distribuida o global se

ejecuta en múltiples sistemas y su ejecución requiere la coordinación entre el sistema global de

gestión de transacciones y todos los gestores de datos locales de los sistemas implicados.

Transacciones locales

Las transacciones locales son específicas a recursos, como una transacción asociada a una

es
conexión JDBC. Mientras que las transacciones globales pueden abarcar múltiples recursos en un

sistema distribuido.

2.
La gestión de transacciones locales puede ser útil en un entorno informático centralizado en el que

ca
los componentes y recursos de las aplicaciones se ubiquen en un único sitio y la gestión de

lifi
transacciones solo implique un gestor de datos local ejecutándose una sola máquina. Las

transacciones locales pueden ser más fáciles de usar, pero tienen notables desventajas: no pueden
ua
funcionar a través de múltiples recursos transaccionales. Por ejemplo, el código que
l.c

administra las transacciones con una conexión JDBC no puede ejecutarse dentro de una transacción

JTA global. Dado que el servidor de aplicaciones no participa en la administración de transacciones,


ua

no puede ayudar a garantizar la exactitud entre varios recursos. (Vale la pena señalar que la
rt

mayoría de las aplicaciones utilizan un único recurso de transacción.) Otro inconveniente es que las
i

transacciones locales son invasivas al modelo de programación.


sv
pu

Programático vs. Declarativo


m

Como comentamos, Spring soporta dos tipos de gestión de transacciones:


ca

Gestión programática de transacciones: esto significa que la transacción se gestiona con la

ayuda de la programación. Eso le da una flexibilidad extrema, pero es difícil de mantener.

Gestión declarativa de transacciones: en este caso se separa la gestión de transacciones de

la lógica de negocio (código). En Spring solo se pueden utilizar las anotaciones o la

configuración basada en XML para administrar las transacciones.

La gestión declarativa de transacciones es preferible a la gestión de manera programática, aunque

lo declarativa es menos flexible que la programática la cual permite controlar las transacciones a

campusvirtual.cualifica2.es
38 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

través del código. Pero como una especie de característica transversal, la gestión declarativa de

transacciones puede modularizarse con el enfoque AOP. Spring soporta la gestión declarativa de

transacciones a través del marco AOP de Spring.

Estrategia de transacciones en Spring

La clave a la abstracción de transacciones en Spring está definida por la interfaz

org.springframework.transaction.PlatformTransactionManager que se muestra a

continuación:

es
2.
public interface PlatformTransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;

ca
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}

lifi
Tengamos en cuenta que, de acuerdo con la filosofía de Spring, PlatformTransactionManager es
ua
una interfaz y, por lo tanto, puede ser fácilmente implementada cuando sea necesario.. Las

implementaciones de PlatformTransactionManager se definen como cualquier otro objeto (o


l.c

bean) en el contenedor de Spring. Incluso cuando se trabaja con JTA, los códigos que definen las
ua

transacciones pueden ser probados con mayor facilidad que si se utiliza directamente JTA.
rt

Metodo Descripción
Este método devuelve una transacción
i
sv

TransactionStatus actualmente activa o crea una nueva, de


getTransaction(TransactionDefinition definition) acuerdo al comportamiento de
propagación definido
pu

Este método realiza un commit (guardar


void commit(TransactionStatus status) cambios) de la transacción pasada como
m

parámetro, de acuerdo a su estado


Este método lleva a cabo un rollback
ca

void rollback(TransactionStatus status) (restablecer los cambios) de la transacción


pasada.

La definición de la interfaz TransactionDefinition:

public interface TransactionDefinition {


int getPropagationBehavior();
int getIsolationLevel();
String getName();
int getTimeout();
boolean isReadOnly();
}

campusvirtual.cualifica2.es
39 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Descripción de los métodos

Metodo Descripción
Este método devuelve el comportamiento de propagación. Spring
int getPropagationBehavior() ofrece todas las opciones de propagación de transacciones
familiares de EJB CMT.
Este método el grado en el que la transacción está aislada del
int getIsolationLevel()
trabajo de otras
String getName() Nombre de la transacción
int getTimeout() El tiempo en segundos en el que la transacción debe finalizar

es
boolean isReadOnly() Si la transacción es de solo lectura

2.
ca
−Para la implementación de las transacciones se utiliza la anotación @Transactional, la cual se

coloca encima del método que va a ser utilizado por Spring.

lifi
Podemos preguntarnos por ejemplo cuánto durará la transacción, desde que comienza la ejecución
ua
hasta el commit final. Esta empieza con la primera línea del método que se ha marcado con
l.c

@Transactional hasta el final del mismo.


ua

A continuación los posibles valores de los tipos de propagación:


rt

Nombre de constante Descripción


Soporta una transacción actual;
i
sv

TransactionDefinition.PROPAGATION_MANDATORY lanza una excepción si la


transacción actual no existe.
pu

Se ejecuta dentro de una


TransactionDefinition.PROPAGATION_NESTED transacción anidada si existe una
transacción actual.
m

No admite la existencia de una


transacción actual, lanza una
ca

TransactionDefinition.PROPAGATION_NEVER
excepción si existe una transacción
actual.
No admite una transacción actual,
TransactionDefinition.PROPAGATION_NOT_SUPPORTED sino que siempre se ejecuta de
forma no transaccional.
Soporta la transacción actual, crea
TransactionDefinition.PROPAGATION_REQUIRED
una nueva si no existe.
Crea una nueva transacción,
TransactionDefinition.PROPAGATION_REQUIRES_NEW suspendiendo la transacción actual
si existe.

campusvirtual.cualifica2.es
40 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Soporta una transacción actual, se


TransactionDefinition.PROPAGATION_SUPPORTS ejecuta no transaccionalmente si
no existe.
Utiliza el timeout predeterminado
del sistema de transacciones
TransactionDefinition.TIMEOUT_DEFAULT
subyacente, o ninguno si no se
admiten timeouts.
La interfaz TransactionStatus proporciona una forma sencilla de que el código transaccional

controle la ejecución de la transacción y el estado de la transacción de consulta:

es
public interface TransactionStatus extends SavepointManager {
boolean isNewTransaction();

2.
boolean hasSavepoint();
void setRollbackOnly();

ca
boolean isRollbackOnly();
boolean isCompleted();
}

lifi
Descripción:
ua
Método Descripción
l.c

Este método devuelve si esta transacción lleva internamente un


boolean hasSavepoint() savepoint(punto de salvaguarda), es decir, se ha creado como una
transacción anidada basada en un savepoint.
ua

Este método indica si esta transacción se ha completado, es decir,


boolean isCompleted()
si ya se ha hecho commit o rollback.
rt

boolean isNewTransaction() Este método devuelve true si la transacción actual es nueva.


i

Este método devuelve si la transacción se ha marcado como solo


sv

boolean isRollbackOnly()
rollback.
void setRollbackOnly() Este método establece la transacción como solo rollback.
pu
m
ca

campusvirtual.cualifica2.es
41 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Spring Web Services.

Spring Web Services (Spring-WS) es un producto desarrollado por la comunidad de Spring

centrado en la creación de servicios web basados en documentos. Spring Web Services tiene como

objetivo facilitar el desarrollo del servicio SOAP siguiendo el modelo de contract-first (contrato

primero), permitiendo la creación de servicios web flexibles. Spring-WS se basa en Spring, lo que

significa que puede utilizar sus componentes como como la inyección de dependencias.

es
Es un producto de la comunidad de Spring centrado en la creación de Web services o servicios web.

Facilita el primer contacto con el desarrollo de servicios SOAP, permitiendo la creación de servicios

2.
web flexibles utilizando varias formas de manipulación de ficheros XML.

ca
Para un servicio web SOAP empezaríamos describiendo como serian los mensajes, por ejemplo un

lifi
servicio de consulta de recetas de cocina:
ua
<?xml version="1.0" encoding="UTF-8"?>
l.c

<RecipeListRequest xmlns="http://www.ejemplococina.com/spring/ws/schemas">
<nacion_origen>India</nacion_origen>
<dificultad>baja</dificultad>
ua

</RecipeListRequest>

Un XML Schema para la petición: recipeListRequest.xsd


irt
sv

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://www.ejemplococina.com/spring/ws/schemas"
pu

xmlns:schemas="http://www.ejemplococina.com/spring/ws/schemas">

<xsd:element name="RecipeListRequest">
m

<xsd:complexType>
<xsd:sequence>
ca

<xsd:element name="nacion_origen" type="xsd:string" />


<xsd:element name="dificultad" type="schemas:dificultadType"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>

<xsd:simpleType name="dificultadType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="baja" />
<xsd:enumeration value="media" />
<xsd:enumeration value="alta" />
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>

campusvirtual.cualifica2.es
42 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Definimos una interfaz del servicio y una clase que lo implemente:

package com.test.example;

public interface RecipesService {


void Recipe[] listRecipes(String nacion, string dificultad);
}

//Otro fichero
package com.test.example;
import org.springframework.stereotype.Service;

es
@Service
public class RecipesImpl implements RecipesService {

2.
void Recipe[] listRecipes(String nacion, string dificultad) {
//Realizamos la consulta

ca
}
}

lifi
Una clase Endpoint es la encargada de recibir tratar la petición
ua
package com.test.example;
import org.springframework.beans.factory.annotation.Autowired;
l.c

import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
ua

import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
rt

@Endpoint
public class RecipesListEndpoint {
i

private static final String TARGET_NAMESPACE = "http://www.ejemplococina.com/spring/ws";


sv

@Autowired
private RecipesService recipesService;
pu

@PayloadRoot(localPart = "RecipeListRequest", namespace = TARGET_NAMESPACE)


public @ResponsePayload RecipeListResponse getListRecipes(@RequestPayload ListRecipeRequest
request)
m

{
ListRecipeResponse response = new AccountDetailsResponse();
ca

//Servicio inyectado
Recipe[] resp = recipesService.getListRecipes(request.getParams());
response.setListRecipes(account);
return response;
}
public void setRecipesService(RecipesService serv)
{
this.recipesService = serv;
}
}

campusvirtual.cualifica2.es
43 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Spring Security.

Un aspecto principal en el desarrollo de toda aplicación web es la seguridad de la misma. Una

función básica sería la comprobación de la identidad del usuario y sus permisos.

Spring Security es un framework utilizado para la autenticación y control de acceso muy

personalizable. Permite gestionar todo lo relacionado a la seguridad de una aplicación web, desde el

protocolo de seguridad hasta los roles de usuario.

es
Al igual que en el anterior apartado, la principal característica de este framework de Spring es la

2.
facilidad tanto de implementación como de uso que presenta. También podemos destacar el gran

ca
soporte que presenta en su comunidad, además de tener un Servlet API integrado y la posibilidad de

implementarse con Spring Web MVC. Prácticamente Spring Security es declarativo y apenas es

lifi
necesario escribir código, incluso no es necesario escribir una página de login, ya que Spring
ua
Security lo puede hacer por ti.
l.c

Autenticación

Una vez añadida su dependencia en el proyecto bastaría con ir creando filtros en el web.xml, sin
ua

embargo se puede hacer ilegible y díficil de mantener. Por ello lo normal es definir un único filtro
rt

web, junto con un AuthenticationProvider y AuthenticationEntryPoint:


i
sv

<filter>
<filter-name>springSecurityFilterChain</filter-name>
pu

<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
m

<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
ca

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

Como alternativa a definir múltiples filtros podemos utilizar el elemento <http>, dicho elemento

junto al atributo auto-config a true, configurará los filtros obligatorios, beans y la cadena de

seguridad.

Se creará el bean springSecurityFilterChain que se encargará de gestionar los diferentes filtros de

la cadena de seguridad. También se definirá el filtro de autenticación authenticationProcessingFilter

que permitirá generar la sesión, el token, etc.

campusvirtual.cualifica2.es
44 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

En el siguiente ejemplo tenemos una configuración básica para la autentificación de usuarios:

<?xml version="1.0" encoding="UTF-8"?>


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sec="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.0.xsd">

es
<bean id="authenticationProcessingFilter"
class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
<property name="authenticationManager" ref="authenticationManager" />

2.
<property name="filterProcessesUrl" value="/j_spring_security_check" />
<property name="authenticationSuccessHandler">

ca
<bean
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandl
er">

lifi
<property name="defaultTargetUrl" value="/pages/home" />
</bean>
</property>
ua
<property name="authenticationFailureHandler">
<bean class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
l.c

<property name="defaultFailureUrl" value="/pages/errorlogin" />


</bean>
</property>
ua

</bean>

<bean id="authenticationManager"
rt

class="org.springframework.security.authentication.ProviderManager">
<property name="providers">
i

<list>
sv

<ref bean="myAuthenticationProvider" />


</list>
pu

</property>
</bean>
m

<bean id="myAuthenticationProvider" class="com.test.filter.MyAuthenticationProvider">


<property name="userDetailsService" ref="myUserDetailsService" />
</bean>
ca

<bean id="myUserDetailsService" class="com.test.filter.MyUserDetailsService" />

<sec:http auto-config="true" use-expressions="true" access-denied-page="/pages/denied"


authentication-manager-ref="authenticationManager">
<sec:intercept-url pattern="/login" access="permitAll" />
<sec:intercept-url pattern="/user/*" access="hasRole('USER')" />
<sec:form-login login-page="/login" default-target-url="/user" />
<sec:logout invalidate-session="true" delete-cookies="JSESSIONID" logout-success-url="/" logout-
url="/j_spring_security_logout" />
</sec:http>

</beans>

campusvirtual.cualifica2.es
45 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

En el ejemplo podemos ver que hemos definido el bean AuthenticationManager. Este bean, entre

otras cosas, es responsable de recuperar la información de usuario que se está intentando loguear

en el sistema. Esto lo consigue mediante un provider que es necesario definir. Este provider es el

que proporciona al AuthenticationManager los detalles de nuestro usuario. El provider construye un

objeto UsernamePasswordAuthenticationToken si la contraseña es la correcta y se lo pasa al

AuthenticationManager. Éste será el que se encargue de rellenar el SecurityContextHolder. Se

pueden definir varios providers según sea necesario, además de definir uno propio.

es
Entre otras el AuthenticationManager tiene la propiedad authenticationSuccessHandler que

2.
redirigiría a la página solicita antes de del logeo, en caso de que haya entrado por sí mismo en dicha

página se redirigirá a la default.

ca
También se puede observar como requerimos un rol de usuario en una de las rutas de <sec:http>

lifi
(sec es el prefijo que definimos para los elementos del schema de security). Los roles se
ua
configurarán declarativamente en el spring-security.xml. También hemos definido un

UserDetailsService, este es el que provee los datos de los usuarios al AuthenticationProvider, por
l.c

ejemplo pueden venir de la base de datos.


ua

Debemos tener en cuenta que otros ficheros de configuración se deben definir con el elemento
rt

<context-param>:
i
sv

<context-param>
<param-name>contextConfigLocation</param-name>
pu

<param-value>
classpath:applicationContext.xml
classpath:spring-security.xml
m

</param-value>
</context-param>
ca

A continuación tenemos una implementación del AuthenticationProvider

public class MyAuthenticationProvider implements AuthenticationProvider {

private UserDetailsService userDetailsService;

public void setUserDetailsService(UserDetailsService userDetailsService) {

this.userDetailsService = userDetailsService;
}

campusvirtual.cualifica2.es
46 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {

UserDetails userDetails = this.userDetailsService.loadUserByUsername(authentication.getName());


if (userDetails != null && new
BasicPasswordEncryptor().checkPassword(authentication.getCredentials().toString(),
userDetails.getPassword())) {
return new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
}

throw new BadCredentialsException("Bad credentials");


}
}

es
Como podemos ver recibe un objeto Authentication del que obtiene el nombre que usará con el

2.
userDetailsService para obtener los detalles del usuario, compara la clave recibida con la clave

encriptada en los detalles y devolvemos un UsernamePasswordAuthenticationToken con

ca
userDetails y sus roles.

lifi
ua
El AuthenticationManager tiene la propiedad authenticationSuccessHandler que
redirigiría a la página solicita antes de del logeo, en caso de que haya entrado por
l.c

sí mismo en dicha página se redirigirá a la default.

Verdadero.
ua
rt

Falso.
i
sv
pu
m
ca

campusvirtual.cualifica2.es
47 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Spring Test.

Test podemos traducirlo en este caso como la prueba o el análisis de rendimiento de nuestra

aplicación. En eso se basa Spring Test, en analizar las ventajas que aporta Spring al ámbito de la

programación y como un proyecto mejora en rendimiento.

Algunas de las mejoras en las que se centra son:

es
En el ámbito del contexto. Es decir cuando necesitamos de algún contexto de la aplicación nos

ayuda a analizarlo y ver cómo estamos trabajando con él. Todo de forma simple y reduciendo la

2.
cantidad de código que necesitamos para realizar muchas de las comprobaciones. Esto es

ca
debido a que nos facilita la localización de recursos como los metadata de la configuración de

lifi
XML.

Permite analizar las transacciones realizadas. La integración con estas se traduce como algo
ua
simple y de gran efectividad.
l.c

Es útil a la hora de escribir los tests de integración con clases específicas de Spring.
ua
i rt
sv
pu
m
ca

campusvirtual.cualifica2.es
48 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Capacidades especificas.

Una de las capacidades más valoradas en Spring son los módulos. Todos ellos están contenidos en el

Spring Core Container y cada uno posee una función determinada:

Spring-core. Es el encargado de implementar el código del IoC de Spring permitiendo otras

instalaciones de códigos externos.

Spring-beans. Se encarga de implementar las librerías de Bean de forma automática.

es
Spring-context. Se puede decir que es el contexto del framework y el encargado de administrar

2.
los recursos del proyecto.

ca
Existen más pero con estas 3 definiciones podemos ver la potencia de los módulos en Spring.

lifi
ua
l.c
ua
i rt
sv
pu
m
ca

campusvirtual.cualifica2.es
49 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Recuerda

[[[Elemento Multimedia]]]

es
2.
ca
lifi
ua
l.c
ua
irt
sv
pu
m
ca

campusvirtual.cualifica2.es
50 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

Autoevaluación

Este framework diseñado para la aplicación del modelo-vista-controlador está


diseñado por un conjunto de ... que distribuyen las peticiones a estos.

Variables.

es
Controladores.

2.
ca
Clases.

lifi
Indica si el siguiente enunciado es verdadero o falso: Spring requiere un
ua
contenedor de Servlets para funcionar.
l.c

Falso.
ua
rt

Verdadero.
i
sv

¿Qué es la inyección de dependencias?


pu
m

Una característica única de Spring que nos permite que un objeto sea "inyectado" en
tiempo de compilación.
ca

Un patrón de diseño donde los objetos de los cuales dependen otros son pasados a
estos últimos en tiempo de ejecución.

Un patrón de diseño donde las relaciones entre objetos se definen en un xml.

Indica si el siguiente enunciado es verdadero o falso: El modelo de Spring nos


permite configurar nuestra aplicación de varias formas para que no tengamos

campusvirtual.cualifica2.es
51 / 52
[AFO022366] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA (SECTOR: EMPRESAS DE CONSULTORÍA Y ESTUDIOS
DE ME(...)
[MOD016525] IFCT034PO DESARROLLO DE APLICACIONES CON JAVA
[UDI096117] SPRING MVC.

que establecernos a un modelo únicamente.

Falso.

Verdadero.

El marco de ... proporciona una alternativa al modelo de páginas de servidor

es
para crear aplicaciones web.

2.
ca
Java.

lifi
XML.
ua
J2EE.
l.c
ua
irt
sv
pu
m
ca

campusvirtual.cualifica2.es
52 / 52

También podría gustarte