Spring Portlet IPC – Inter-portlet communications

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

  1.  
  2. package com.loongest.sample.ipc.pitcher;
  3. import java.util.Random;
  4. import javax.portlet.ActionResponse;
  5. import javax.portlet.RenderRequest;
  6. import javax.xml.namespace.QName;
  7. import org.springframework.stereotype.Controller;
  8. import org.springframework.ui.Model;
  9. import org.springframework.web.bind.annotation.RequestMapping;
  10. import org.springframework.web.bind.support.SessionStatus;
  11. import org.springframework.web.portlet.bind.annotation.ActionMapping;
  12.  
  13. @Controller
  14. @RequestMapping("VIEW")
  15. public class PitcherController {
  16.  
  17.     @ActionMapping("pitchBall")
  18.     public void pitchBallAction(SessionStatus status, ActionResponse response)
  19.     {
  20.                 String pitchType = null;
  21.                 Random random = new Random(System.currentTimeMillis());
  22.                 int pitch = random.nextInt(3)+1;
  23.                 switch(pitch) {
  24.                         case 1 :
  25.                                 pitchType = "Fast Ball";
  26.                                 break;
  27.                         case 2 :
  28.                                 pitchType = "Curve Ball";
  29.                                 break;
  30.                         case 3 :
  31.                                 pitchType = "Slider";
  32.                                 break;
  33.                         default :
  34.                                 pitchType = "Screw Ball";
  35.                 }
  36.  
  37.         QName qname = new QName("http://liferay.com/events","ipc.pitch");
  38.         response.setEvent(qname, pitchType);
  39.         status.setComplete();
  40.     }
  41.  
  42.     @RequestMapping
  43.     public String render(Model model, SessionStatus status,
  44.                     RenderRequest req) {
  45.         return "pitcher";
  46.     }
  47. }
  48.  

CatcherController

  1.  
  2. package com.loongest.sample.ipc.catcher;
  3.  
  4. import javax.portlet.Event;
  5. import javax.portlet.EventRequest;
  6. import javax.portlet.EventResponse;
  7. import javax.portlet.RenderRequest;
  8. import javax.portlet.RenderResponse;
  9. import org.springframework.stereotype.Controller;
  10. import org.springframework.ui.ModelMap;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.portlet.bind.annotation.EventMapping;
  13.  
  14. @Controller
  15. @RequestMapping("VIEW")
  16. public class CatcherController {
  17.  
  18.         @RequestMapping
  19.         public String doView(RenderRequest request, RenderResponse response){
  20.                 return "catcher";
  21.         }
  22.  
  23.         @EventMapping(value ="{http://liferay.com/events}ipc.pitch")
  24.         public void receiveEvent(EventRequest request, EventResponse response, ModelMap map)
  25.         {
  26.                 Event event = request.getEvent();
  27.                 String pitch = (String)event.getValue();
  28.                 map.put("pitch", pitch);
  29.                 response.setRenderParameter("pitch", pitch);
  30.         }
  31. }
  32.  

catcher-portlet.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5.     xmlns:p="http://www.springframework.org/schema/p"
  6.     xmlns:context="http://www.springframework.org/schema/context"
  7.     xsi:schemaLocation="
  8.        http://www.springframework.org/schema/beans
  9.        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  10.        http://www.springframework.org/schema/context
  11.        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  12.  
  13.     <context:component-scan base-package="com.loongest.sample.ipc.catcher" />
  14.  
  15.     <bean id="viewResolver"
  16.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  17.         <property name="viewClass"
  18.             value="org.springframework.web.servlet.view.JstlView" />
  19.         <property name="prefix" value="/WEB-INF/view/catcher/" />
  20.         <property name="suffix" value=".jsp" />
  21.     </bean>
  22. </beans>
  23.  

pitcher-portlet.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  5.     xmlns:p="http://www.springframework.org/schema/p"
  6.     xmlns:context="http://www.springframework.org/schema/context"
  7.     xsi:schemaLocation="
  8.        http://www.springframework.org/schema/beans
  9.        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  10.        http://www.springframework.org/schema/context
  11.        http://www.springframework.org/schema/context/spring-context-3.0.xsd">
  12.  
  13.     <context:component-scan base-package="com.loongest.sample.ipc.pitcher" />
  14.  
  15.     <bean id="viewResolver"
  16.         class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  17.         <property name="viewClass"
  18.             value="org.springframework.web.servlet.view.JstlView" />
  19.         <property name="prefix" value="/WEB-INF/view/pitcher/" />
  20.         <property name="suffix" value=".jsp" />
  21.     </bean>
  22.  
  23. </beans>

catcher.jsp

  1.  
  2. <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  3. <%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %>
  4. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  5.  
  6. <portlet:defineObjects/>
  7. <p> And the pitch is … </p>
  8. <p>
  9.     <c:if test="${param.pitch ne ”}">
  10.           <c:out value="${param.pitch}"/>
  11.     </c:if>
  12.     <c:if test="${param.pitch eq ”}">
  13.            …waiting for pitch
  14.     </c:if> 
  15.  

pitcher.jsp

  1.  
  2. <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
  3. <%@ taglib prefix="portlet" uri="http://java.sun.com/portlet" %>
  4. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
  5.  
  6. <portlet:defineObjects/>
  7.  
  8. <p> Click the link below to pitch the ball </p>
  9. <a href="<portlet:actionURL name="pitchBall"></portlet:actionURL>">Pitch !</a></span></span>

applicationContext.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <beans xmlns="http://www.springframework.org/schema/beans"
  4.         xmlns:context="http://www.springframework.org/schema/context"
  5.         xmlns:mvc="http://www.springframework.org/schema/mvc"
  6.         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  7.         xmlns:p="http://www.springframework.org/schema/p"
  8.         xsi:schemaLocation="
  9.                 http://www.springframework.org/schema/beans
  10.                 http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  11.                 http://www.springframework.org/schema/context
  12.                 http://www.springframework.org/schema/context/spring-context-3.0.xsd
  13.                 http://www.springframework.org/schema/mvc
  14.                 http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
  15.  
  16.         <context:component-scan base-package="com.loongest.sample.ipc" />
  17.  
  18. </beans>
  19.  

liferay-portlet.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <!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">
  4.  
  5. <liferay-portlet-app>
  6.  
  7.         <portlet>
  8.                 <portlet-name>pitcher</portlet-name>
  9.                 <icon>/icon.png</icon>
  10.                 <instanceable>true</instanceable>
  11.                 <header-portlet-css>/css/test.css</header-portlet-css>
  12.                 <footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
  13.         </portlet>
  14.  
  15.         <portlet>
  16.                 <portlet-name>catcher</portlet-name>
  17.                 <icon>/icon.png</icon>
  18.                 <instanceable>true</instanceable>
  19.                 <header-portlet-css>/css/test.css</header-portlet-css>
  20.                 <footer-portlet-javascript>/js/test.js</footer-portlet-javascript>
  21.         </portlet>
  22.  
  23.         <role-mapper>
  24.                 <role-name>administrator</role-name>
  25.                 <role-link>Administrator</role-link>
  26.         </role-mapper>
  27.  
  28.         <role-mapper>
  29.                 <role-name>guest</role-name>
  30.                 <role-link>Guest</role-link>
  31.         </role-mapper>
  32.  
  33.         <role-mapper>
  34.                 <role-name>power-user</role-name>
  35.                 <role-link>Power User</role-link>
  36.         </role-mapper>
  37.  
  38.         <role-mapper>
  39.                 <role-name>user</role-name>
  40.                 <role-link>User</role-link>
  41.         </role-mapper>
  42.  
  43. </liferay-portlet-app>

portlet.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <portlet-app version="2.0"
  4.     xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
  5.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6.     xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd
  7.        http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
  8.  
  9.     <portlet>
  10.         <portlet-name>pitcher</portlet-name>
  11.         <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
  12.         <init-param>
  13.             <name>contextConfigLocation</name>
  14.             <value>/WEB-INF/context/pitcher-portlet.xml</value>
  15.         </init-param>
  16.         <supports>
  17.             <mime-type>text/html</mime-type>
  18.             <portlet-mode>view</portlet-mode>
  19.         </supports>
  20.         <portlet-info>
  21.             <title>Pitcher</title>
  22.         </portlet-info>
  23.  
  24.         <supported-publishing-event>
  25.                 <qname xmlns:x="http://liferay.com/events">x:ipc.pitch</qname>
  26.         </supported-publishing-event>
  27.  
  28.     </portlet>
  29.  
  30.     <portlet>
  31.         <portlet-name>catcher</portlet-name>
  32.         <portlet-class>
  33.             org.springframework.web.portlet.DispatcherPortlet
  34.         </portlet-class>
  35.         <init-param>
  36.             <name>contextConfigLocation</name>
  37.             <value>/WEB-INF/context/catcher-portlet.xml</value>
  38.         </init-param>
  39.         <supports>
  40.             <mime-type>text/html</mime-type>
  41.             <portlet-mode>view</portlet-mode>
  42.         </supports>
  43.         <portlet-info>
  44.             <title>Catcher</title>
  45.         </portlet-info>        
  46.  
  47.         <supported-processing-event>
  48.                 <qname xmlns:x="http://liferay.com/events">x:ipc.pitch</qname>
  49.         </supported-processing-event>
  50.     </portlet>
  51.  
  52.     <event-definition>
  53.         <qname xmlns:x="http://liferay.com/events">x:ipc.pitch</qname>
  54.         <value-type>java.lang.String</value-type>
  55.     </event-definition>    
  56.  
  57. </portlet-app>

liferay-display.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <!DOCTYPE display PUBLIC "-//Liferay//DTD Display 5.2.0//EN"
  4.          "http://www.liferay.com/dtd/liferay-display_5_2_0.dtd">
  5.  
  6. <display>
  7.         <category name="Spring MVC Portlet 3.0">
  8.                 <portlet id="pitcher" />
  9.                 <portlet id="catcher" />
  10.         </category>
  11. </display>

Web.xml

  1.  
  2. <?xml version="1.0" encoding="UTF-8"?>
  3. <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.         xmlns="http://java.sun.com/xml/ns/javaee"
  5.         xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  6.         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  7.        http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  8.         id="WebApp_ID" version="2.5">
  9.  
  10.     <display-name>Sample Portal</display-name>
  11.  
  12.     <listener>
  13.         <listener-class>
  14.             org.springframework.web.context.ContextLoaderListener
  15.         </listener-class>
  16.     </listener>
  17.  
  18.     <servlet>
  19.         <servlet-name>view</servlet-name>
  20.         <servlet-class>
  21.             org.springframework.web.servlet.ViewRendererServlet
  22.         </servlet-class>
  23.     </servlet>
  24.  
  25.         <servlet>
  26.         <servlet-name>view</servlet-name>
  27.         <servlet-class>
  28.             org.springframework.web.servlet.ViewRendererServlet
  29.         </servlet-class>
  30.     </servlet>
  31.  
  32.     <servlet-mapping>
  33.         <servlet-name>view</servlet-name>
  34.         <url-pattern>/WEB-INF/servlet/view</url-pattern>
  35.     </servlet-mapping>
  36.  
  37. </web-app>

Done !

You can leave a response, or trackback from your own site.

8 Responses to “Spring Portlet IPC – Inter-portlet communications”

  1. zielgruppe says:

    Thanks, this was really helpful.

  2. Rob says:

    Thanks, looked ages for a working example…

  3. Mandar Chatufale says:

    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

  4. loongest says:

    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.

  5. miedzyzdroje says:

    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.

  6. yw214 says:

    This is exactly what I am looking for. Thank you very much!!!

  7. aditya says:

    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?

  8. loongest says:

    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.

Leave a Reply

Security Code: