Table of contents
Introduction
Once a portlet is placed on a portal page, its data is not directly shared with other portlets. IPC (Inter Portlet Communication) defines the ways that a Portlet can interact and communicate with another Portlet. There are four ways to make inter portlet communication :
This post will show how to operate a Portlet communication using Public Render Parameters.
Public Render Parameters
Public Render Parameters was introduced in JSR 286 (Portlet 2.0) and aims to pass data from a portlet to another. Below the steps to use public render parameters:
-
Define the public render parameter in the portlet.xml
Declare the public render parameter in the Portlet.xml file. A public render parameter must have a unique identifier in a given namespace
12345678<portlet-app ...>...<public-render-parameter><identifier>identifier</identifier><qname xmlns:x="http://namespace.com">x:identifier</qname></public-render-parameter>...</portlet-app>
-
Configure portlets to use the public render parameter in the portlet.xml
All portlets that want to handle the public render parameter must declare in their Portlet.xml the property <supported-public-render-parameter> that refers to the public render parameter id.
12345<portlet>...<supported-public-render-parameter>identifier</supported-public-render-parameter>...<portlet>
-
Storing Data in the sender portlet
Set the renderParameter in the processAction portlet phase
1actionReponse.setRenderParameter("identifier", value);
-
Retrieving the stored data in the receiver portlet
Get the renderParameter from the renderRequest
1renderRequest.getParameter("identifier");
-
Removing the public render parameter
Public render parameter can only be removed in processAction phase
1actionReponse.removePublicRenderParameter("identifier");
The portal stores all public render parameters that are merged with regular parameters set in render URLs or on an ActionResponse.
Concrete example
Let’s see a full example of using the IPC with public render parameter.
The code source is available on Github. Download the source
Let’s consider two portlets :
- CarList (Sender portlet): This portlet shows a list of cars. The user can select a car from the list. When the user select a car, the car’s id is stored as a public render parameter. The car information will be displayed in the second portlet.
- CarInformation (Receiver portlet): If a car is selected (Id stored in the public render parameter), this portlet will display the car information.
Defining the public render parameter
First step is to define the public render parameter in which the car identifier will be stored in the portlet.xml file. If the portlets that handle the public render parameter are in the same Liferay Plugin Project, only one definition of the public render parameter must be in the portlet.xml file. If not, each Liferay plugin must declare it in its portlet.xml file.
In this example, the two portlets are in the same Liferay Plugin Project.
The identifier given to the public render parameter is “carId“. The declaration is as following :
1 2 3 4 5 6 7 |
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0"> <!-- Defining the public render parameter --> <public-render-parameter> <identifier>carId</identifier> <qname xmlns:x="http://roufid.com/carId">x:carId</qname> </public-render-parameter> </portlet-app> |
Sender portlet : CarList
- Portlet.xml
Defining the CarList portlet in the portlet.xml file. This portlet must support the defined public render parameter. It must define the <supported-public-render-parameter> property :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0"> <portlet> <portlet-name>CarList</portlet-name> <display-name>CarList</display-name> <portlet-class> javax.portlet.faces.GenericFacesPortlet </portlet-class> <init-param> <name>javax.portlet.faces.defaultViewId.view</name> <value>/views/carlist/view.xhtml</value> </init-param> <expiration-cache>0</expiration-cache> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <portlet-info> <title>CarList</title> <short-title>CarList</short-title> <keywords></keywords> </portlet-info> <security-role-ref> <role-name>administrator</role-name> </security-role-ref> <security-role-ref> <role-name>guest</role-name> </security-role-ref> <security-role-ref> <role-name>power-user</role-name> </security-role-ref> <security-role-ref> <role-name>user</role-name> </security-role-ref> <!-- CarList portlet supports the public render parameter "carId" --> <supported-public-render-parameter>carId</supported-public-render-parameter> </portlet> </portlet-app> |
- Selecting the car
In the jsp view, I used an actionURL to process a portlet action in which the public render parameter is setted. Below the code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<%@taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme"%> <%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%> <%@taglib uri="http://liferay.com/tld/aui" prefix="aui"%> <%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <portlet:defineObjects /> <liferay-theme:defineObjects /> <!-- Defining the action URL --> <portlet:actionURL var="selectCar" windowState="normal" name="selectCarAction" /> <table class="table table-striped"> <thead> <tr> <th></th> <th>Id</th> <th>Year</th> <th>Brand</th> <th>Color</th> <th>Action</th> </tr> </thead> <tbody> <c:forEach var="car" items="${cars}"> <!-- Defining a form for each car. --> <aui:form action="<%=selectCar%>" method="post" name="carList"> <input name="carId" value="${car.id}" style="visibility: hidden;" /> <tr> <td><img src="${car.imagePath}" width="50" height="50" /></td> <td><c:out value="${car.id}" /></td> <td><c:out value="${car.year}" /></td> <td><c:out value="${car.brand}" /></td> <td><c:out value="${car.color}" /></td> <td><input type="submit" name="selectButton" value="Select"> </td> </tr> </aui:form> </c:forEach> </tbody> </table> |
The public render parameter is setted in the selectCarAction, as below :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
import java.io.IOException; import java.util.List; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.PortletException; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import com.liferay.portal.kernel.util.ParamUtil; import com.liferay.util.bridges.mvc.MVCPortlet; import com.roufid.tutorials.bean.Car; import com.roufid.tutorials.service.CarService; /** * Listing cars. * @author Radouane ROUFID * */ public class CarList extends MVCPortlet { /** * Process the Portlet action URL. * @param actionRequest The ActionRequest. * @param actionResponse The ActionReponse. * @throws IOException * @throws PortletException */ public void selectCarAction(ActionRequest actionRequest, ActionResponse actionResponse) throws IOException, PortletException { // Getting the carId from the submitted form. String carId = ParamUtil.getString(actionRequest,"carId"); // Setting the car identifier as a public render parameters. actionResponse.setRenderParameter("carId", carId); } } |
The public render parameter is setted in the actionReponse. Let’s see now how it’s processed in the receiver portlet.
Receiver portlet : CarInformation
- Portlet.xml
Defining the CarInformation portlet in the portlet.xml file. This portlet must support the defined public render parameter. It must define the <supported-public-render-parameter> property :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0"> <portlet> <portlet-name>CarInformation</portlet-name> <display-name>CarInformation</display-name> <portlet-class> javax.portlet.faces.GenericFacesPortlet </portlet-class> <init-param> <name>javax.portlet.faces.defaultViewId.view</name> <value>/views/carinformation/view.xhtml</value> </init-param> <expiration-cache>0</expiration-cache> <supports> <mime-type>text/html</mime-type> <portlet-mode>view</portlet-mode> </supports> <portlet-info> <title>CarInformation</title> <short-title>CarInformation</short-title> <keywords></keywords> </portlet-info> <security-role-ref> <role-name>administrator</role-name> </security-role-ref> <security-role-ref> <role-name>guest</role-name> </security-role-ref> <security-role-ref> <role-name>power-user</role-name> </security-role-ref> <security-role-ref> <role-name>user</role-name> </security-role-ref> <!-- CarInformation portlet supports the public render parameter "carId" --> <supported-public-render-parameter>carId</supported-public-render-parameter> </portlet> </portlet-app> |
- Getting the carId from the portlet parameters
Retrieving the data from the portlet parameters.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
import java.io.IOException; import javax.portlet.PortletException; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import com.liferay.util.bridges.mvc.MVCPortlet; import com.roufid.tutorials.bean.Car; import com.roufid.tutorials.service.CarService; /** * Car information. * @author Radouane ROUFID. * */ public class CarInformation extends MVCPortlet { /** * Singleton carService bean injection. */ private CarService service = CarService.getInstance(); @Override public void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { // Getting the public render parameter. String carId = renderRequest.getParameter("carId"); Car car = service.getCarWithId(carId); renderRequest.setAttribute("car", car); super.doView(renderRequest, renderResponse); } } |
The public render parameter is getted from the renderRequest.
Rendering after deployment
The CarList portlet is on the left. CarInformation portlet is on the right.
Below the result after selecting BMW.
The code source is available on Github. Download the source