JSR 286 : Portlet Events using Spring 3.0 Annotation and WebSphere Portal v 7.0
Sample implemented for this article allows users to enter first name and last name on one portlet and publish it as JSR 286 event. Subscribing portlet reads it and display on the screen. Ideal is to understand the mechanism, important aspects to keep in mind from the configuration front and uses of Spring Framework's annotation driven programming model.
Lets start with Event Configuration.
1. You need to provide event information into portlet.xml, remember if you have multiple war files then you will have to copy-paste the event definition across each portlet.xml.
<qname xmlns:publishName="http:eventSample/events">
publishName:event.publishName
<value-type>sample.valueobject.Namevalue-type>
2. You need to put publishing tag into portlet definition. This tag will go for the portlet publishing the event.
<supported-publishing-event>
<qname xmlns:publishName="http:eventSample/events">
publishName:event.publishName
3. You need to put subscription tag into portlet definition for the portlet/s intended to subscribe to the event.
<supported-processing-event>
<qname xmlns:publishName="http:eventSample/events">
publishName:event.publishName
Now at this point in time we are clear with the portlet.xml entries. Look at the structure of portlet.xml for the sample :
xml version="1.0" encoding="UTF-8"?>
<portlet-name>Publisher Portletportlet-name>
-----------------------------------
-----------------------------------
-----------------------------------
<supported-publishing-event>
<qname xmlns:publishName="http:eventSample/events">
publishName:event.publishName
<portlet-name>Subscriber Portletportlet-name>
-----------------------------------
-----------------------------------
-----------------------------------
<supported-processing-event>
<qname xmlns:publishName="http:eventSample/events">
publishName:event.publishName
<default-namespace>http://SpringEventSample/default-namespace>
<qname xmlns:publishName="http:eventSample/events">
publishName:event.publishName
<value-type>sample.valueobject.Namevalue-type>
Now look at the controller code for publishing and subscribing.
Event should be published as part of the action processing, following controller code shows how to publish information.
package springsample.publisher.controller;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
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.portlet.bind.annotation.ActionMapping;
import sample.valueobject.Name;
public class PublishController {
public String defaultLanding(Model model, RenderRequest rRequest,
RenderResponse rResponse) {
@ActionMapping(params="action=PublishEvent")
public void publishName(ActionRequest aRequest,ActionResponse aResponse){
name.setFirstName(aRequest.getParameter("firstName"));
name.setLasName(aRequest.getParameter("lastName"));
QName eventName = new QName( "http:eventSample/events",
"event.publishName");
aResponse.setEvent(eventName, name);
Now subscription is also very similar. Look at the following code , only catch here is when you want to pass information to rendering method, you will have to use similar mechanism as you do from processAction ie setting render parameter on EventResponse. In the example, I set the render parameter and read it on JSP directly.
package springsample.publisher.controller;
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.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.portlet.bind.annotation.EventMapping;
import sample.valueobject.Name;
public class SubscriberController {
public String defaultLanding(Model model, RenderRequest rRequest,
RenderResponse rResponse) {
@EventMapping(value = "event.publishName")
public void processName(EventRequest eventRequest,
EventResponse eventResponse) {
Name name = (Name) eventRequest.getEvent().getValue();
eventResponse.setRenderParameter("firstName", name.getFirstName());
eventResponse.setRenderParameter("lastName", name.getLasName());
Now when user enters first name and last name, it will display in on the second portlet. Information from first portlet to second portlet is passed using JSR 286 Event mechanism. Following is the screenshot :
The only catch here would when you deploy this application on WebSphere Portal, you will have to create a wire between the portlets otherwise you would see some crappy error message. This sample should work on all JSR 286 compliant servers.
As always you can download the source code of this sample app from here.