Uncategorized
Kanban Martien van Steenbergen 22 May, 2013
Coordination between portlets is a very common requirement. An example of information sharing between portlets can be a weather portlet displaying the weather information of a city and a map portlet displaying the location of the city. Since, both the portlets would be using the same zip code for a user, there should be mechanism provided by the portlal containers to allow portlets to share the zip code.
Prior to JSR 286, the support for inter portlet communication was rather minimal and information sharing between different portlets was accompalished primarily using application scoped session objects or vendor specific APIs. Both of above methods were rather problematic as in the former maintaining the uniqueness of the session attribute over a complex aaplication was a concern and in the later portability of the portlet was hampered. In order to provide coordination between portlets the Java Portlet Specification v2.0 (JSR 286) introduces the following mechanisms:id1 x:param1 id2 x:param22. Specify the render parameter the portlet would like to share in the portlet section.
PortletA id1 id2 PortletB id1 PortletC id2The public render paramters declared above are processed as explained in the figure below.
. . . . . . x:Address com.xebia.Address
@XmlRootElement public class Address implements Serializable { public Address() { } private String street; private String city; private String country; //getters and setters }Note: The object must be serializable and must be instrumented with valid JAXB annotation. This might be required to ensure that portlets can send events to and receive events from remote portlets. However, in case of local communication, portal containers, for optimization purposes, might not serialize event payload.
ContinentPortlet ContinentPortlet ................. x:Address(iii) In the portlet section, specify the event name defined above for those portlets that want to process this event.
ContinentMapPortlet ContinentMapPortlet x:Address ContinentInfoPortlet ContinentInfoPortlet x:Address2. Issue an event in the portlet that was specified as supported-publishing-event in the portlet.
public class ContinentPortlet extends GenericPortlet { public void processAction(ActionRequest request, ActionResponse response) throws PortletException,IOException { QName qname = new QName("https:xebia.com/address" , "Address"); Address add = new Address(); //set values in address response.setEvent(qname, add); } }3. Process the event in the portlet that has specified as supported-processing-event in the portlet
public class ContinentInfoPortlet extends GenericPortlet { public void processEvent(EventRequest request, EventResponse response) { Event event = request.getEvent(); if(event.getName().equals("Address")){ Address payload = (Address )event.getValue(); //process payload here } } }Portlet events provide more sphisticated way of exchanging information between portlets as compared to public render paramters as they can be used to share objects rather than simple string values. They also provide an additional callback method, processEvent, which can be used to process the event information before the view for the portlet in rendered. Also, portlet events share the information in a type safe manner as the event payload id bound to a type which we declare in the portlet.xml. Also, portlet specification does not standardizes how to wire the portlets, so, portal containers are free to choose convenient mechanisms to wire the portlets together. However, as per the portlet specification, portlet events are not as reliable means of communication as is JMS, since the specification does not mandate the portal containers to persist the portlet event data. So, in case of server failures, the portlet events can be lost. Summary In this blog, we discussed about the JSR 286 inter portlet communication features. First, we discussed about the public render parameters and how it works. Secondly, we discussed about the portlet events, and it's working. So, how to decide when to choose either of the above two portlets. I would use the following principle
In case, the receiver portlet, does not need to do any processing/businees logic, it is advisable to use public render parameters as they avoid the overhead for portlets event creation and wiring the portlets together, which is required in case of portlet events. As already discussed, wiring portlets together is portal container specific and is an addtional overhead. However, to allow receiver portlets to process the shared information and sending type safe values, we need to use portlet events.Overall, JSR 286 portlet coordination features make complex portal applications modular and manageable. Note: The source code of for portlet events can be downloaded from here.