Nuestro primer Portlet en Liferay

Hasta el momento hemos visto cómo configurar Liferay sobre un Servidor Glassfish v3 para producción. Esto nos permite tener un Portal en blanco listo para que nosotros le configuremos todo. Es decir, el Liferay que viene preconfigurado con el GF, Tomcat o Jetty que está disponible en la página de descarga de liferay.com, tiene contenido preparado, textos de ejemplo, temas, aplicaciones completas, etc. Además que viene configurado con HSQLDB. Si al preconfigurado le cambiamos el acceso a la base de datos para que utilice el MySQL o cualquiera, en ese momento todo el contenido del Portal estará en blanco.

Recomiendo la versión preconfigurada de liferay para conocer un poco cómo funciona, y además, para usarlo como caja de arena para probar nuestros portlets.

En este post veremos cómo hacer un Portlet para Liferay usando NetBeans 6.x

Quizás te preguntarás por qué quiero usar más GlassFish que Tomcat, así sea para una aplicación web simple. No tengo nada en contra de Tomcat, fue mi primer contenedor Servlet/JSP que utilicé (exactamente la versión 3). Es rápido y simple de usar. Pero para mi me es un problema cuando quiero gestionar con base de datos. Tomcat maneja su Pool de conexiones de manera eficiente, pero configurarlo no es muy agradable que digamos (editar un archivo .xml que es parte del .war no creo que sea muy portable si quiero pasar de desarrollo a producción sin editar nada) Mientras que en GlassFish la configuración del DataSource se hace desde la misma consola del servidor.
Bueno, esto fue un offtopic del post, explicando porqué uso más GlassFish que Tomcat.

Comencemos con la preparación de nuestro NetBeans para desarrollar un portlet:

Configurando NetBeans con un Servidor Liferay+Glassfish v3

Previamente ya debe estar instalado los plugins del PortalPack, que lo vimos en un post anterior.

  1. Abrimos nuestro NetBeans y vayamos al panel de Prestaciones (Services) con Ctrl+5. Abrimos el nodo "Servidores" y hacemos clic derecho sobre ese nodo, seleccionando la opción "Agregar Servidor".





  2. Seleccionamos de la lista "Liferay Portal Server 5.1.x/5.2.x" y hacemos clic en Siguiente.








  3. Seleccionamos el tipo de Servidor a GlassFish, y el GlassFish Home a "C:\glassfishv3\glassfish".







  4. Clic en "Siguiente". Dejamos los valores por omisión, y clic en "Terminar"

Ejecutando Liferay desde NetBeans

Bien, ahora que ya tenemos nuestro NetBeans configurado con Liferay, será bueno primero iniciar el Liferay para ver sobre donde vamos a trabajar. Para ello, hacemos clic derecho sobre el ícono del Liferay que hemos acabado de agregar al NetBeans, y seleccionamos "Start".


... y si tienes un computador tan lento como el que tengo en la oficina, en unas horas en unos momentos, se mostrará el Liferay en el navegador.



Nuestro primer portlet básico

Un portlet es en realidad una aplicación web que se distribuye en .war y que tiene archivos .xml de despliegue adicionales. Como aplicación web, también cuenta con su ruta de contexto (context-path), sus configuraciones del web.xml y demás. Ahora con la versión JavaEE6, también puede contener EJB 3.1, ya que - como acabo de decir - es una aplicación web. Solo que esta aplicación web no se desplegará desde la consola del contenedor web, sino desde el mismo contenedor de portlets, en este caso, desde liferay.

Creando un proyecto web

  1. Así que comencemos creando una aplicación web desde Archivo > Nuevo proyecto > Java Web > Web Application.






  2. Clic en Siguiente. Luego indicamos el nombre del proyecto y su ubicación. Le ponemos que se llamará SimplePortlet, y tomar la ubicación predeterminada.






  3. Clic en Siguiente. Seleccionamos el servidor donde se desplegará. En este caso seleccionamos el que acabamos de agregar al IDE hace un momento. Notar que cuenta la versión del Java EE y la ruta de contexto.







  4. Clic en Siguiente. Cuando nos pida los "Frameworks" a utilizar, activamos el que dice "Portlet Support". Y más abajo dice "Create Portlet". Lo dejamos desactivado para crearlo posteriormente.








  5. Clic en Terminar.
Vemos que es un proyecto web mas archivos .xml adicionales....
Insisto diciendo que es un proyecto web, para que no sea chocante tratar de pensar que es otro tipo de proyecto y no se hagan preguntas como:
  • ¿Puedo ponerle mis imágenes? ¿Dónde?
  • ¿Puedo usar .css?
  • ¿Puedo poner .js?
  • ¿Dónde pongo las clases?
  • etc... etc.. etc
Este proyecto podrá tener más de un portlet. Así que comenzaremos a crear el primero.

Creado un portlet


Advertencia: Al momento de hacer este post, encontré problemas para desplegar un portlet desde NetBeans + PortalPack al Liferay/GFv3. Esto es porque el PortalPack considera que el Servidor a utilizar es Liferay/GFv2 o Tomcat. Utiliza el JSR88 para desplegarlo sobre GFv2, y este JSR88 ya no está disponible para GFv3. En resumen. Si utilizas el Liferay+GFv2, el despliegue será inmediato. Pero para este post haremos la manera no cómoda pero que funciona: desplegar el Portlet desde la Consola de Liferay.
  1. Hagamos clic en Nuevo > Archivo nuevo (Ctrl+N) y seleccionamos Portlets > Portlet







  2. Clic en Siguiente. Luego escogemos como nombre de la clase Portlet FactorialPorlet del paquete portlets. Eso es solo la característica de la clase. Pero esta clase debe tener características como Porlet, por ejemplo el nombre, descripción, etc. Así que pongamos los siguientes valores:






    • PortletName: FactorialPortlet
    • Portlet Display Name: Factorial Portlet
    • Porlet Description: Portlet que calcula el factorial
    • Portlet title: Factorial en Portlet
    • Portlet Short Title: Factorial
    • Activar los checks  "Edit" y "Help". Estas serán páginas adicionales que interactuará con el usuario.

  3. Clic en Siguiente. Activamos el check para que nos cree los .jsp correspondientes.







  4. Clic en Terminar.

Con esto nos habrá creado una clase FactorialPortlet, y dentro de WEB-INF/jsp estarán los archivos .jsp que serán utilizados para el interfaz de usuario.

Vemos que hay dos métodos que nos llaman la atención (que nos recuerdan al doGet y doPost de los Servlets) processAction(), doView, doEdit y doHelp. Estos métodos son invocados por el Portal para mostrar una página dependiendo de la petición que haya hecho el usuario. Si solo quiere ver, se ejecutará el doView, si va a editar las preferencias del portlet, ejecutará doEdit, y si quiere ver la ayuda del portlet, se ejecutará doHelp. Pero cuando se quiere atender una petición, se ejecutará el método processAction(). Notemos que dentro está la clase PortletRequestDispatcher que no es más que una especialización de la clase RequestDispatcher utilizada en los servlet bajo el modelo MVC. Así que, aquí no hay modo de fallar :).

Ahora, editemos el archivo FactorialPortlet.java para que calcule el Factorial. Primero, el método que hace el cálculo.

    static long factorial(long base) {        if (base < 2) {            return 1;        }        return base + factorial(base - 1);    }

Y, editemos el método processAction() para leer un parámetro de la web, lo calculamos, y lo mostramos al usuario.

    public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {        String numero = request.getParameter("numero");        System.out.println("Parametro leido:" + numero);        if (numero != null && !numero.isEmpty()) {            try {                long $numero = Long.parseLong(numero);                long factorial = factorial($numero);                System.out.println("resultado:" + factorial);                request.setAttribute("factorial", factorial);            } catch (NumberFormatException ex) {                ex.printStackTrace();            }        }    }

Ahora, nos falta el formulario. Abramos el archivo FactorialPortlet_view.jsp, y escribamos el siguiente código:
<%@page contentType="text/html"%><%@page pageEncoding="UTF-8"%><%@ page import="javax.portlet.*"%><%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%><h3>Cálculo de factorial</h3><form action="<portlet:actionURL/>" method="post">    Ingrese un número:    <input type="text" name="numero" /><br/>    <button type="submit">Calcular</button>    <div>        Resultado: ${factorial}    </div></form>

La mayor parte del formulario nos es conocido: tiene input, botones, imprime resultado, etc. Pero el tag <portlet:actionURL/> quizás no sea claro, pero puede darnos la idea de qué es. Este tag devuelve la ubicación del mismo portlet dentro de toda la página de portlets. Me explico mejor:

Recordemos que cuando hacemos un formulario en JSP, siempre el action debe apuntar a una dirección web que recibirá los parámetros del formulario: puede ser un Servlet u otro JSP. Ahora, ¿qué pasaría si tuvieramos varios forms en una misma página que apuntan a diferentes direcciones? ¿Cómo hacemos para que diferencie que un formulario es diferente a otro y diferenciar las peticiones? Pues, hacer que el url del action sea totalmente diferente. Pues bien, bajo la misma lógica, el tag <portlet:actionURL/> nos ahorra saber cuál es el URL del Portlet que debemos ejecutar, además que le pone una identificación única para diferenciarlos de los demás Portlets.

Creando el archivo de despliegue

Para crear un archivo .war que contiene el Portlet, es bastante simple. Es tan igual como cuando se crea un archivo. Clic derecho el ícono de proyecto, y seleccionar Limpiar y Construir (Clean and Build).

Con esto, nos creará un archivo .war. Veamos donde lo creado en el panel de Salida (Ctrl+4) del NetBeans.

Desplegando el .war

Para desplegar un .war tenemos dos maneras: la larga, y la corta. Solo mencionaré la forma corta. Es simple: basta con copiar el .war en la carpeta "deploy" del GlassFish...


...esperamos unos segundos y el archivo desparecerá. Esperamos unos segundos más y estará desplegado en el Servidor.

Colocando el Portlet en el Portal

Primero debemos iniciar la sesión (por omisión es test@liferay.com con contraseña test). Luego, en el parte superior derecha está menú "dock", al que le damos clic y seleccionamos "Add application"
Esto hará que se muestre un panel en la margen izquierda y veamos una ventana con todas los portlets disponibles, agrupados por categorías. Nuestro portlet está en la categoría "User_Portlets".



Le damos clic en "Add" para agregar el Portlet, o si gustamos, lo arrastramos y lo soltamos en cualquier parte de la página.

Y lo hacemos funcionar...


Nota: Para cambiar la categoría del Portlet, debemos editar el archivo liferay-display.xml desde NetBeans.

Conclusión

Este post me fue lo más accidentando que me he atrevido a hacer. Pudo haber sido más simple o más completo, pero a medida que hago el tutorial, también construyo el proyecto para asegurarme que todo lo que digo sea correcto. Pero me encontré con problemas de versiones, componentes faltantes, y más cosas no esperadas. Quería terminar con el .JSF, pero ya no me dio el  tiempo. Será para otro post. (También tengo que hacer cosas en donde trabajo.) En fin. Este post me motivó hacerlo ya que implementé el Liferay para el Site de la oficina donde trabajo. Aún no está del todo terminado, hicimos un par de portlets que funcionan bien, solo nos falta hacer un par más, implementar un nuevo Theme con los colores de la oficina y listo. Así que cada cosa que encuentro, lo voy colocando en mi blog.

Un tip importante que aprendí cuando hemos desarrollado los portlets de manera rápida (ya que mi computador es bastante lento para desplegar un .war en liferay), es:
  1. Cambiar en las propiedades del proyecto a para que utilice el GlassFish v3 en lugar del Liferay
  2. Desarrollar, probar, ejecutar, depurar como si se tratase de una aplicación web. Considerando los elementos de portlets, adaptar la aplicación para que funcione sin él. (Recordar que el método processAction() es similar a un Servlet, así que convendría utilizar un servlet por mientras.
  3. Luego, cuando esté listo, acomodar los tags de la aplicación para pasar a liferay.
  4. Cambiar en las propiedades del proyecto para que utilice Liferay en lugar de GlassFish v3.
  5. Construir el .war
  6. Desplegar el .war al Liferay.
 Se pueden agregar más servlets, componentes JQuery, Ajax, Dojo, etc.

Espero que te haya hecho de utilidad.

El proyecto que utilicé en este post está aquí: http://java.net/downloads/apuntes/samples/web/SimplePortlet.tar.gz

Comentarios

  1. Muchas gracias por la info, sabes me he leido todos tus post y me han sido de gran utilidad para donde trabajo, estoy en la construccion de temas para liferay pero no entiendo muy bien la estuctura. Al modificar el tema no hay problema pero no voy a mas de eso de cambiar el header, tipo de letra, color, etc. Lo que quisiera es cambiar la apariencia total pero para esto necesito conservar la estructura base me imagino o nose algo asi me podrias ayudar que es lo que se debe tener en cuenta al cambiar el tema totalmente.

    Muchas Gracias por la ayuda
    Saludos
    Ecuador

    ResponderBorrar
  2. Bien, afortunadamente todo la apariencia está basada en CSS. Es decir, que la estructura NO está puesta en una plantilla y que desde ahí se hace llamadas a las partes que se desea mostrar (como es el caso del Joomla). Toda la ubicación del menú dock, del menú superior, etc etc está en los archivos .css del theme.
    Puedes crear un proyecto con NetBeans (como se mostró en este ejemplo) y en lugar de crear un portlet, crea un Theme (ahí aparece la opción) y el NetBeans te creará toda la estructura del theme nuevo para Liferay. Edita los archivos, adjunta imágenes y listo. Claro, como cualquier diseño, debes de probar y probar.

    Que te vaya bien!
    PD.: también he pensado en hacer un post sobre themes en liferay, pero que sea básico y efectivo

    ResponderBorrar
  3. Hola Diego,

    Muy buenos tus aportes, me han sido de gran ayuda. Pero tengo una consulta: Estoy tratando de configurar liferay 6 con oracle 10g y me salen errores en la consola al levantar el portal y luego cuando estoy en el admin el workflow no funciona; y tambien salen errores en la consola.
    Tienes algo referente a esto?? o alguien que siga el blog tiene algun dato??

    ResponderBorrar
  4. Hola Luis

    gracias por los comentarios. Referente a la pregunta, también estoy teniendo problemas con el LR6, sobretodo en la migración desde la versión anterior. Es más, aún no hay documentación de guía de administrador de esa versión. Cuando tenga alguna novedad, lo publicaré por esta vía.

    saludos

    P.D.: me auno a Luis: si alguien tiene alguna respuesta a esta duda, será bienvenida!

    ResponderBorrar
  5. Hola Diego,

    gracias por tu post. Te quería hacer una pregunta acerca de Liferay o relacionado. ¿Hay alguna forma rápida de transformar el contenido de una página web convencional en un portal web por ejemplo con Liferay para que podamos tener el contenido de la página original y 2 o 3 portlets? No sé si la pregunta será demasiado ingenua o estupida pero bueno..

    Muchas gracias y un saludo.

    ResponderBorrar
  6. felicitaciones, me fue de gran ayuda tu informacion

    ResponderBorrar
  7. Muchas gracias por la Información, me ha sido muy util dada la poca proliferación de información referente a liferay en castellano.

    Desde luego este blog y la gente de http://www.adictosaltrabajo.com y http://www.coretec.es de lo mejorcito que hay

    ResponderBorrar
  8. Muy bueno el ejemplo, me sirvió de mucho.
    Estoy comenzando a usar liferay. El primer paso que quiero hacer es migrar muchos articulos que poseo en una base de datos, a la base de datos de liferay, para esto es necesario el uso de la API de liferay, pero no he encontrado como hacerlo.
    Me gustaria saber si tienes conocimiento de como hacerlo? espero puedas ayudarme.

    Saludos,
    Ernesto

    ResponderBorrar
  9. Lo Felicito hasta el Dia De hoy no he encontrado Post mas Educativos de 1 a 10 le doy 100

    ResponderBorrar
  10. Gracias Oscar.. palabras como las tuyas hacen que uno pueda seguir aportando a la comunidad. Saludos

    ResponderBorrar
  11. muchas gracias por tus aportes, encuentro siempre soluciones al dia dia del programador

    ResponderBorrar

Publicar un comentario

Si quieres hacer una pregunta más específica, hazla en los foros que tenemos habilitados en Google Groups


Ah! solo se permiten comentarios de usuarios registrados. Si tienes OpenID, bienvenido! Puedes obtener su OpenID, aquí: http://openid.net/

Entradas más populares de este blog

Groovy: Un lenguaje dinámico y ágil para la Plataforma Java

Cambiar ícono a un JFrame

UML en NetBeans