Portlet 2.0 support inter-portlet communication, the following simple example show the step by step together using spring and portlet.
You may download the source from here
In the following tutorial, we will create 2 portlet to interact from pitch-portlet to catcher-portlet. In this example pitch-portlet will generate a random number and display on catcher portlet.
PitcherController
-
-
package com.loongest.sample.ipc.pitcher;
-
import java.util.Random;
-
import javax.portlet.ActionResponse;
-
import javax.portlet.RenderRequest;
-
import javax.xml.namespace.QName;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.ui.Model;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.bind.support.SessionStatus;
-
import org.springframework.web.portlet.bind.annotation.ActionMapping;
-
-
@Controller
-
@RequestMapping("VIEW")
-
public class PitcherController {
-
-
@ActionMapping("pitchBall")
-
public void pitchBallAction(SessionStatus status, ActionResponse response)
-
{
-
String pitchType = null;
-
int pitch = random.nextInt(3)+1;
-
switch(pitch) {
-
case 1 :
-
pitchType = "Fast Ball";
-
break;
-
case 2 :
-
pitchType = "Curve Ball";
-
break;
-
case 3 :
-
pitchType = "Slider";
-
break;
-
default :
-
pitchType = "Screw Ball";
-
}
-
-
QName qname = new QName("http://liferay.com/events","ipc.pitch");
-
response.setEvent(qname, pitchType);
-
status.setComplete();
-
}
-
-
@RequestMapping
-
RenderRequest req) {
-
return "pitcher";
-
}
-
}
-
CatcherController
-
-
package com.loongest.sample.ipc.catcher;
-
-
import javax.portlet.Event;
-
import javax.portlet.EventRequest;
-
import javax.portlet.EventResponse;
-
import javax.portlet.RenderRequest;
-
import javax.portlet.RenderResponse;
-
import org.springframework.stereotype.Controller;
-
import org.springframework.ui.ModelMap;
-
import org.springframework.web.bind.annotation.RequestMapping;
-
import org.springframework.web.portlet.bind.annotation.EventMapping;
-
-
@Controller
-
@RequestMapping("VIEW")
-
public class CatcherController {
-
-
@RequestMapping
-
return "catcher";
-
}
-
-
@EventMapping(value ="{http://liferay.com/events}ipc.pitch")
-
public void receiveEvent(EventRequest request, EventResponse response, ModelMap map)
-
{
-
map.put("pitch", pitch);
-
response.setRenderParameter("pitch", pitch);
-
}
-
}
-
catcher-portlet.xml
-
-
<?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">
-
-
<context:component-scan base-package="com.loongest.sample.ipc.catcher" />
-
-
<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/view/catcher/" />
-
<property name="suffix" value=".jsp" />
-
</bean>
-
</beans>
-
pitcher-portlet.xml
-
-
<?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">
-
-
<context:component-scan base-package="com.loongest.sample.ipc.pitcher" />
-
-
<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/view/pitcher/" />
-
<property name="suffix" value=".jsp" />
-
</bean>
-
-
</beans>
catcher.jsp
-
-
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
-
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %>
-
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-
<portlet:defineObjects/>
-
<p> And the pitch is … </p>
-
<p>
-
<c:if test="${param.pitch ne ”}">
-
<c:out value="${param.pitch}"/>
-
</c:if>
-
<c:if test="${param.pitch eq ”}">
-
…waiting for pitch
-
</c:if>
-
pitcher.jsp
-
-
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
-
<%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %>
-
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
-
<portlet:defineObjects/>
-
-
<p> Click the link below to pitch the ball </p>
-
<a href="<portlet:actionURL name="pitchBall"></portlet:actionURL>">Pitch !</a></span></span>
applicationContext.xml
-
-
<?xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:context="http://www.springframework.org/schema/context"
-
xmlns:mvc="http://www.springframework.org/schema/mvc"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:p="http://www.springframework.org/schema/p"
-
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
-
http://www.springframework.org/schema/mvc
-
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
-
-
<context:component-scan base-package="com.loongest.sample.ipc" />
-
-
</beans>
-
liferay-portlet.xml
-
-
<?xml version="1.0" encoding="UTF-8"?>
-
<!DOCTYPE liferay-portlet-app PUBLIC "-//Liferay//DTD Portlet Application 5.2.0//EN" "http://www.liferay.com/dtd/liferay-portlet-app_5_2_0.dtd">
-
-
<liferay-portlet-app>
-
-
<portlet>
-
<portlet-name>pitcher</portlet-name>
-
<icon>/icon.png</icon>
-
<instanceable>true</instanceable>
-
<header-portlet-css>/css/test.css</header-portlet-css>
-
<footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
-
</portlet>
-
-
<portlet>
-
<portlet-name>catcher</portlet-name>
-
<icon>/icon.png</icon>
-
<instanceable>true</instanceable>
-
<header-portlet-css>/css/test.css</header-portlet-css>
-
<footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
-
</portlet>
-
-
<role-mapper>
-
<role-name>administrator</role-name>
-
<role-link>Administrator</role-link>
-
</role-mapper>
-
-
<role-mapper>
-
<role-name>guest</role-name>
-
<role-link>Guest</role-link>
-
</role-mapper>
-
-
<role-mapper>
-
<role-name>power-user</role-name>
-
<role-link>Power User</role-link>
-
</role-mapper>
-
-
<role-mapper>
-
<role-name>user</role-name>
-
<role-link>User</role-link>
-
</role-mapper>
-
-
</liferay-portlet-app>
portlet.xml
-
-
<?xml version="1.0" encoding="UTF-8"?>
-
<portlet-app version="2.0"
-
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">
-
-
<portlet>
-
<portlet-name>pitcher</portlet-name>
-
<portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
-
<init-param>
-
<name>contextConfigLocation</name>
-
<value>/WEB-INF/context/pitcher-portlet.xml</value>
-
</init-param>
-
<supports>
-
<mime-type>text/html</mime-type>
-
<portlet-mode>view</portlet-mode>
-
</supports>
-
<portlet-info>
-
<title>Pitcher</title>
-
</portlet-info>
-
-
<supported-publishing-event>
-
<qname xmlns:x="http://liferay.com/events">x:ipc.pitch</qname>
-
</supported-publishing-event>
-
-
</portlet>
-
-
<portlet>
-
<portlet-name>catcher</portlet-name>
-
<portlet-class>
-
org.springframework.web.portlet.DispatcherPortlet
-
</portlet-class>
-
<init-param>
-
<name>contextConfigLocation</name>
-
<value>/WEB-INF/context/catcher-portlet.xml</value>
-
</init-param>
-
<supports>
-
<mime-type>text/html</mime-type>
-
<portlet-mode>view</portlet-mode>
-
</supports>
-
<portlet-info>
-
<title>Catcher</title>
-
</portlet-info>
-
-
<supported-processing-event>
-
<qname xmlns:x="http://liferay.com/events">x:ipc.pitch</qname>
-
</supported-processing-event>
-
</portlet>
-
-
<event-definition>
-
<qname xmlns:x="http://liferay.com/events">x:ipc.pitch</qname>
-
<value-type>java.lang.String</value-type>
-
</event-definition>
-
-
</portlet-app>
liferay-display.xml
-
-
<?xml version="1.0" encoding="UTF-8"?>
-
<!DOCTYPE display PUBLIC "-//Liferay//DTD Display 5.2.0//EN"
-
"http://www.liferay.com/dtd/liferay-display_5_2_0.dtd">
-
-
<display>
-
<category name="Spring MVC Portlet 3.0">
-
<portlet id="pitcher" />
-
<portlet id="catcher" />
-
</category>
-
</display>
Web.xml
-
-
<?xml version="1.0" encoding="UTF-8"?>
-
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns="http://java.sun.com/xml/ns/javaee"
-
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
-
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
-
id="WebApp_ID" version="2.5">
-
-
<display-name>Sample Portal</display-name>
-
-
<listener>
-
<listener-class>
-
org.springframework.web.context.ContextLoaderListener
-
</listener-class>
-
</listener>
-
-
<servlet>
-
<servlet-name>view</servlet-name>
-
<servlet-class>
-
org.springframework.web.servlet.ViewRendererServlet
-
</servlet-class>
-
</servlet>
-
-
<servlet>
-
<servlet-name>view</servlet-name>
-
<servlet-class>
-
org.springframework.web.servlet.ViewRendererServlet
-
</servlet-class>
-
</servlet>
-
-
<servlet-mapping>
-
<servlet-name>view</servlet-name>
-
<url-pattern>/WEB-INF/servlet/view</url-pattern>
-
</servlet-mapping>
-
-
</web-app>

Posted in 



Thanks, this was really helpful.
Thanks, looked ages for a working example…
Hi,
I am trying to implement IPC between two different portlets in “two different war files” using spring 3.0 MVC framework.
I have created the 2 projects and have implemented the code but seems that event is not getting fired or it was not getting caught in the other controller..
do you have any sample code to demonstrate the IPC between portlets in different war files.
Thanks in Advance
Hi, as far as i known it cant work in two different war files. Because the event is define in portlet.xml and each war will only load on their own portlet.xml. But you can give a try, because the the qname should be unique.
Hi, perhaps this is not on content but in any case, I have been reading about your web site and it looks truly neat. impassioned about your authorship. I’m building a new web log and hard put to make it appear great, and provide really good content. I have observed a lot on your web site and I look forward to more updates and will be coming back.
This is exactly what I am looking for. Thank you very much!!!
hi,
can we achieve this using ResourceMapping…?
In my case i m submitting the form thr ajax request and for that I have controller which has resource mapping which does nt allows ActionRequest and ActionResponse…is their any other way to achieve this?
From the idea you mention seem like first portlet is ajax approach and second is IPC. I suggest you revise the design, maybe you can implement for portletA with (ActionMapping and EventMapping) and portletB with (EventMapping). The effect will be the same.