Inter-portlet communication between multiple portlets in different portlet applications has been made easy with JSR 286 portlet API. It has brought a new revolution in portlet development. In JSR 168 a.k.a portlet specification 1.0, inter-portlet communication between portlets in different war files was not possible. The only way to achieve it was through IBM URL Generation classes. But JSR 286 gives you more flexibility to achieve this functionality.
There are 2 ways to achieve interportlet communication between portlets in different portlet applications:
1. By using public render parameters of JSR 286 portlet development API.
2. By using processEvent() method.
I will be discussing the second approach in this article. The first approach was discussed in the Part 1 of this article. In the first method you can pass only string params while the second one gives you flexibility to pass complex collection objects. I have created sample applications for both approaches.
The sample application uses IBM websphere portal 7, JSR 286 portlet development API, Annotation based Spring MVC Portlet framework 3.1. There are 2 portlets applications PortletApplication 1 which has TestPortlet1 and PortletApplication2 which has TestPortlet2.
Listing 1: TestPortlet1Controller.java
@Controller
@RequestMapping("VIEW")
public class TestPortlet1Controller{
@RenderMapping
protected ModelAndView defaultHandleRenderRequest(RenderRequest request,RenderResponse response) throws Exception {
ModelAndView mav = new ModelAndView("list1");
return mav;
}
@ActionMapping(params = "action=insert")
public void insert(ActionRequest request, ActionResponse response) {
String address = request.getParameter("address");
QName qName = new QName("http://bcbsfl.com","testEvent");
response.setEvent(qName, address);
}
}
Listing 1.1 TestPortlet1.xml:
<portlet>
…
<supported-publishing-event>
<qname xmlns:customns="http://bcbsfl.com">customns:testEvent</qname>
</supported-publishing-event>
…
<event-definition>
<qname xmlns:customns="http://bcbsfl.com">customns:testEvent</qname>
<value-type>java.lang.String</value-type>
</event-definition>
…
</portlet>
Listing 2: TestPortlet2Controller.java
@Controller
@RequestMapping("VIEW")
public class TestPortlet2Controller{
@RenderMapping
protected ModelAndView defaultHandleRenderRequest(RenderRequest request,
RenderResponse response) throws Exception {
ModelAndView mav = new ModelAndView("list2");
String address = request.getParameter(“address”);
mav.addObject("address",address);
return mav;
}
@EventMapping(value="{http://bcbsfl.com}testEvent")
public void processEvent(EventRequest request, EventResponse response)
{
Event e = request.getEvent();
System.out.println("SelectController2.processEvent()=======Got an event");
System.out.println("QName: " + e.getQName());
System.out.println("Event Name: " + e.getName());
System.out.println("Event Value:========== " + e.getValue());
response.setRenderParameter("address",(String)e.getValue());
}
}
Listing 2.1 TestPortlet2.xml:
<portlet>
…
<supported-processing-event>
<qname xmlns:customns="http://bcbsfl.com">customns:testEvent</qname>
</supported-processing-event>…
<event-definition>
<qname xmlns:customns="http://bcbsfl.com">customns:testEvent</qname>
<value-type>java.lang.String</value-type>
</event-definition>
…
</portlet>
After coding part is completed you have to create wires via websphere portal admin GUI and you are all set.
This is helpful. Thanks!
ReplyDeleteCan you add how to pass more complex information? For example an object of type com.mycompany.MyObject? How will the portlet from the other WAR file recognize my custom object? Do I need to include it in the portal class path?
ReplyDeleteYes you have to add it as a jar file or you can put that class in shared library so it is available to both source portlet and target portlet. But again it depends which option do you want to implement in interportlet communication.
ReplyDeleteThanks Chirag. Very helpful blog.
ReplyDelete