The JSR 286 specification helps define inter portlet communication in two ways. Before we get into the details of it, lets see what interportlet communication is.
Interportlet communication as the name itself suggests, is a way in which two independent portlets can communicate with each other. The simple example to it might be, consider 2 portlets, a Quick search portlet and a Search results portlet. You search for something in Quick search portlet and the Search results portlet displays the result.Now let see how does JSR 286 supports IPC.
Event Support : Portlet events are based on a simple model called publish subscribe communication model. The fundamental here is that, one portlet publishes the event without bothering who will subscribe to it and another portlet subscribes to this event without knowing who the publisher is. So the main advantage of this approach is that, it is loosely coupled. The two portlets are developed as stand alone portlets which get wired only at runtime.
The objects which these portlets use to communicate with each other are called payloads.The JSR 286 specification permits portlets to communicate complex Java objects as event payloads, as long as these payloads are Java and JAXB XML serializable.
Events are a life cycle operation which gets triggered before rendering phase. The portlet can issue an event via setEvent method in the action processing phase which will be processed by the portlet container after the action processing has finished.
How events are declared
· Declare the events in the portlet.xml
Set the event definition at the portlet application level. This specifies the event name and the object type.
<portlet-app ...>
<portlet>
. . .
. . .
</portlet>
<event-definition>
<qname xmlns:x="http:search.com/address">x:Address</qname>
<value-type>com.org.address </value-type>
</event-definition>
</portlet-app>
public class Address implements Serializable {
public Address() {
}
private String street;
private String city;
private String country
· In the portlet section, specify the event name defined above for those portlets that want to publish this event.
<portlet>
<description>SearchPortlet</description>
<portlet-name> SearchPortlet </portlet-name>
.................
<supported-publishing-event>
<qname xmlns:x=" http:search.com/address">x:Address</qname>
</supported-publishing-event>
</portlet>
· Call the setEvent method to publish the event in the processAction method.
public class SearchPortlet extends GenericPortlet {
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException,IOException {
QName qname = new QName("http:search.com/address " , "Address");
Address add = new Address();
//set values in address
response.setEvent(qname, add);
}
}
How events are processed
In order to receive events the portlet must implement the EventPortlet interface in he javax.portlet package. The portlet container will call the processEvent method for each event targeted to the portlet with an EventRequest and EventResponse object.
· In the portlet section, specify the event name defined above for those portlets that want to process this event.
<portlet>
<description>SearchResultsPortlet</description>
<portlet-name> SearchResultsPortlet </portlet-name>
<supported-processing-event>
<qname xmlns:x=" http:search.com/address">x:Address</qname>
</supported-processing-event>
</portlet>
· Process the event in the portlet that has specified as supported-processing-event in the portlet
public class SearchResultsPortlet 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
}
}
}
Advantages of portlet events over public render parameters:
1) 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.
2) 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.
3) 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.
4) Portlet specification does not standardizes how to wire the portlets, so, portal containers are free to choose convenient mechanisms to wire the portlets together.
Disadvantages of portlet events over public render parameters:
1) 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.
Public render parameters : From a programming perspective, a public render parameter is handled almost identically to an ordinary (private) render parameter: The portlet can set and read this parameter using the same API methods that JSR 168 introduced for private render parameters. From a programmer's point of view, the important difference is that a public render parameter is declared in the portlet.xml deployment descriptor and therefore becomes an external interface of the portlet.
So basically in PRP, its about sharing the render state between portlets.
Lets see how to set a public render parameter in a portlet
Set the public render parameters at the portlet application level.
<public-render-parameter>
<identifier>id1</identifier>
<qname xmlns:x="http://sun.com/params">x:param1</qname>
</public-render-parameter>
<public-render-parameter>
<identifier>id2</identifier>
<qname xmlns:x="http://sun.com/params">x:param2</qname>
</public-render-parameter>
2. Specify the render parameter the portlet would like to share in the portlet section.<portlet>
<portlet-name>PortletA</portlet-name>
<supported-public-render-parameter>id1</supported-public-render-parameter>
<supported-public-render-parameter>id2</supported-public-render-parameter>
<portlet>
<portlet>
<portlet-name>PortletB</portlet-name>
<supported-public-render-parameter>id1</supported-public-render-parameter>
</portlet>
<portlet>
<portlet-name>PortletC</portlet-name>
<supported-public-render-parameter>id2</supported-public-render-parameter>
<portlet>
Now, since the public render parameters are encoded in the URL, the values that can be shared between portlets are restricted to String and String arrays. Since, public render parameters are available only in the render method, the information shared by the portlets should be used for rendering the view rather than for processing the shared information.Advantages of Public Render Parameters
- They do not usually require explicit coding but only a declaration in the portlet.xml deployment descriptor.
- They are limited to simple string values.
- They do not require explicit administration to set up coordination.
- They cause no performance overhead as the number of portlets sharing information grows.
- They are updated by URL changes such as jumping to a bookmark.
- They can be set from links encoded in portal themes and skins.
- They can be set on a link, created with product specific APIs, that leads from one portlet to another portlet on a different page.
Disadvantages of Public Render Parameters
- Cannot send or receive complex information.
- Do not allow fine-grained control by setting up different sorts of wires between portlets which is possible through Portlet events
Thanks Vinay. This is very helpful
ReplyDeleteI have a question. Suppose I need to update another portlet when a public render parameter is changed. How can I handle this??
I believe, if we are using portlet events then automatically processEvent of the subscriber portlet will be invoked on change of source object. Please let me know
-
Sri