Ya hemos creado nuestro primer portlet con Spring Portlet MVC, incluso antes desarrollamos una pequeña demo con Maven, Hibernate y Spring. Ahora me gustaría entender cómo funciona esto de Spring Portlet MVC.
Aquí intentaré mostrar un esquema de cómo se maneja una petición en un portlet, es decir, como funciona nuestro pequeño portlet de “hola mundo”. En este caso el portlet solamente realiza una cosa: “mostrar un mensaje”.
Bueno pues cuando se carga la página en la que se encuentra el portlet, ahí una llamada (request) a nuestro portlet HelloSpring ¿Cómo se gestiona esa llamada? ¿Por qué clases va pasando? Con esto aprenderemos un poco mejor como es el patrón Modelo, Vista, Controlador.
¿Qué hace DisparcherPortlet?
DisparcherPortlet es el corazón del framework Spring Portlet MVC , por ello es el responsable de coordinar todas las peticiones de actividad de nuestro portlet.
En el siguiente diagrama vemos cómo interactúan las distintas clases que conforman el framework.
Explicando el esquema
Cuando el DisparcherPortlet recibe una petición (anotado como 1) lo primero que hace es encontrar un controlador “adecuado” para la petición, para ello se ayuda de los bean que hemos declarado, (en nuestro caso están declarados en HelloSpring-portlet.xml) donde usamos el bean PortletModeHandlerMapping que implementa HandlerMapping y que selecciona el controlador adecuado (anotado en el paso 2).
Llegados a este punto ya tenemos DisparcherPortlet ha elegido nuestro controlador llamado HelloWorldController que nunca mejor dicho controlará la vista de nuestro portlet.
Una vez que ya tenemos elegido al controlador de peticiones (HelloWorldController), el DisparcherPortlet invoca el método del controlador apropiado, dependiendo de la petición que le hayamos hecho al controlador. En nuestro caso el método handleRenderRequest es el responsable de manejar la petición y dar una respuesta a dicha petición.
La respuesta recibida en 1 es una solicitud de representación, es decir, lo que tenemos que hacer es mostrar unos datos (en nuestro caso “hello spring”) por lo que handleRenderRequest se encarga de manejarla (anotado como 3).
Este método (handleRenderRequest), de la clase HelloWorldController devuelve un objeto tipo ModelAndView. El DisparcherPortlet utiliza la información vista en ModelView para mostrar (capa vista) esta información en el portlet. En nuestro caso para mostrar la información utiliza una página JSP.
ViewResolver (anotado como 4) ayuda con la resolución de la vista, para ello lo que se hace es utilizar el bean InternalResourceViewResolver que resuelve la vista utilizando JSP.
TIP
El DispatcherPortlet detecta automáticamente que vista se va a utilizar basándose en el bean que se define en el context del portlet.
Definiendo cada elemento
- DispatcherPortlet: Invoca al controlador, resuelve la vista y hace las solicitud a ViewRendererServlet para renderizar la vista. Actua como punto de entrada de las solicitudes.
- HandlerMapping: Hace el mapeo entre la petición y el handler. Es necesario implementar la interfaz PortletModeHandlerMapping para poder utilizar los modos VIEW, EDIT, HELP, (con su correspondiente controlador). Este mapeo devuelve el “la vara de mando” de HelloWorldControler a DispatcheProtlet.
- HelloWorldController: Maneja la solicitud de representación y devuelve un objeto tipo ModelAndView al DispatcherPortlet.
- ViewResolver: Resuelve la vista actual basándose en el nombre de la vista (en nuestro caso “helloWorld”), el nombre de la vista lo ha pasado DisptcherPortlet.ViewRendererServlet: Renderiza la vista actual basándose en la información sobre la vista y el modelo pasada por el DispatcherPortlet.
Entendiendo el web application context xml
Ya hemos comentado antes que DispatcherPortlet es la parte central del portlet, en lo que se refiere a manejar y procesar peticiones, por otrolado debemso saber que web application context es la parte central para configurar correctamente Spring Portlet MVC.
Esta es la pinta que tiene el archivo web application context en el caso del portlet “Hello Spring” se llama “HelloSpring-portlet.xml” y se encuentra en la carpeta WEB-INF de nuestro proyecto.
<?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:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <bean id="helloWorldController" class="com.jesuslc.code.HelloWorldController"/> <bean id="portletModeHandlerMapping" class="org.springframework.web.portlet.handler.PortletModeHandlerMapping"> <property name="portletModeMap"> <map> <entry key="view"> <ref bean="helloWorldController" /> </entry> </map> </property> </bean> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
Los bean que se definen en este archivo contienen información específica de nuestro portlet como los DAO, los servicios, o información acerca de alguna implementación de interfaces específicas que explicaremos más adelante.
Para resumir en web application context definimos cada uno de los bean (componente software) que vamos a utilizar, para ello les proporcionamos un identificador (id) y le indicamos que clase implementa dicho bean, además definimos las propiedades necesarias en cada bean (atributos property)
Controller y handler –¿Qué es todo eso?
Llegados a este punto ya tenemos un poco menos difuso que en web application context debemos definir los bean ya que el Dispatcher Portlet leerá este archivo para poder manejar las peticiones, pero con el Controller y Handler he de decir que no he sido del todo riguroso y quizás los haya usado como sinónimos, por es quiero hacer un inciso para que afiancemos el concepto.
- Controller: es una clase que implementa a la interfaz Controller.
- Handler: en Spring es cualquier objeto responsable de manejar cualquier tipo de petición; un handler no necesita implementar una interfaz específica.
Por tanto los Controllers son bean especiales de Spring Portlet MVC que implementan la funcionalidad de manejo de peticiones del portlet.
¿Qué nos queda?
Bueno ya hemos entendido como Spring Portlet MVC maneja las peticiones de los portlets, ahora en otro post hablaremos sobre “Service Builder”, una herramienta para poder desarrollar portlets para Liferay que estos interactúen con la base de datos.
Referencias
Me he basado en en libro «Portlets In Action».
Hola,
sólo quería felicitarte por el Blog, los artículos son muy buenos y me están siendo de mucha ayuda para retomar Liferay.
Gracias y sigue así!!!
Me gustaMe gusta