Handling portlet events in Spring Portlet MVC Framework

The Spring Portlet MVC Framework has concept of EventAwareController that can be implemented by your Controller class to indicate that it can handle events.

I built two sample portlets one is SpringSourcePortlet and other is SpringTargetPortlet to demonstrate how you can send and receive events in Spring Portlet MVC framework application. You can download the sample code from here

  1. Contact

  2. SpringSourcePortlet

  3. SpringTargetPortlet



I followed these steps to create my sample application

  • First create Contact.java in separate Java project like this

    package com.webspherenotes.portlet.events;

    import java.io.Serializable;
    import javax.xml.bind.annotation.XmlRootElement;

    @XmlRootElement
    public class Contact implements Serializable{
    private static final long serialVersionUID = -1637774642655976822L;
    private String firstName;
    private String lastName;
    private String email;
    public Contact(){
    }
    public Contact(String firstName, String lastName, String email) {
    super();
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    }
    public String getFirstName() {
    return firstName;
    }
    public void setFirstName(String firstName) {
    this.firstName = firstName;
    }
    public String getLastName() {
    return lastName;
    }
    public void setLastName(String lastName) {
    this.lastName = lastName;
    }
    public String getEmail() {
    return email;
    }
    public void setEmail(String email) {
    this.email = email;
    }
    }


    The Contact.java implements Serializable object and has @XmlRootElement annotation to indicate that this object can be passed either locally or using WSRP

  • Create SpringSourcePortlet using Spring Portlet MVC Framework. In that create ViewModeController.java like this

    package com.webspherenotes.portlet.spring;

    import javax.portlet.ActionRequest;
    import javax.portlet.ActionResponse;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;

    import org.springframework.web.portlet.ModelAndView;
    import org.springframework.web.portlet.mvc.AbstractController;

    import com.webspherenotes.portlet.events.Contact;

    public class ViewModeController extends AbstractController{

    public void handleActionRequest(ActionRequest request,
    ActionResponse response) throws Exception {
    System.out.println("Entering ViewModeController.handleActionRequest");
    String fName = request.getParameter("fName");
    String lName = request.getParameter("lName");
    String email = request.getParameter("email");
    Contact contact = new Contact(fName, lName, email);
    response.setEvent("hello", contact);
    request.getPortletSession().setAttribute("contact", contact);
    System.out.println("Exiting ViewModeController.handleActionRequest");
    }

    public ModelAndView handleRenderRequest(RenderRequest request,
    RenderResponse response) throws Exception {
    System.out.println("Entering ViewModeController.handleRenderRequest");
    response.setContentType("text/html");
    ModelAndView modelAndView = new ModelAndView("source");
    if (request.getPortletSession().getAttribute("contact") != null) {
    modelAndView.addObject("contact", request.getPortletSession()
    .getAttribute("contact"));
    }
    System.out.println("Exiting ViewModeController.handleRenderRequest");
    return modelAndView;
    }
    }


    The handleRenderRequest() method of the ViewModeController, forwards control to source.jsp for generating markup. The source.jsp displays a form to user.

    The handleActionRequest() method of ViewModeController gets called when user enters values on Contact form and clicks submit. Inside this method i am reading values submitted by user, then creating a Contact object and passing it as value of the event.

  • This is how my SpringSourcePortlet-portlet.xml file looks like

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <bean id="viewController"
    class="com.webspherenotes.portlet.spring.ViewModeController" />
    <bean id="portletModeHandlerMapping"
    class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
    <property name="order" value="1" />
    <property name="portletModeMap">
    <map>
    <entry key="view">
    <ref bean="viewController" />
    </entry>
    </map>
    </property>
    </bean>
    <bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass">
    <value>org.springframework.web.servlet.view.JstlView</value>
    </property>
    <property name="prefix">
    <value>/WEB-INF/jsp/</value>
    </property>
    <property name="suffix">
    <value>.jsp</value>
    </property>
    </bean>
    </beans>

    The SpringSourcePortlet has only one controller class which is ViewModeController and it is set as a default VIEW mode controller

  • Next create SpringTargetPortlet and inside that create ViewModeController.java like this

    package com.webspherenotes.portlet.spring;

    import javax.portlet.Event;
    import javax.portlet.EventRequest;
    import javax.portlet.EventResponse;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;

    import org.springframework.web.portlet.ModelAndView;
    import org.springframework.web.portlet.mvc.AbstractController;
    import org.springframework.web.portlet.mvc.EventAwareController;

    import com.webspherenotes.portlet.events.Contact;

    public class ViewModeController extends AbstractController implements EventAwareController{
    public ModelAndView handleRenderRequest(RenderRequest request,
    RenderResponse response) throws Exception {
    System.out.println("Entering ViewModeController.handleRenderRequest");
    response.setContentType("text/html");
    Contact contact = (Contact) request.getPortletSession().getAttribute(
    "contact");
    if (contact != null) {
    response.getWriter().println(
    "First Name " + contact.getFirstName() + "
    Last Name "
    + contact.getLastName() + "
    Email "
    + contact.getEmail());
    } else {
    response.getWriter().println("Contact not found in session ");
    }
    System.out.println("Entering ViewModeController.handleRenderRequest");
    return new ModelAndView();
    }


    public void handleEventRequest(EventRequest request, EventResponse response)
    throws Exception {
    System.out.println("Entering ViewModeController.handleEventRequest");
    Event event = request.getEvent();
    System.out.println("Event Name " + event.getName());
    Contact contact = (Contact) event.getValue();
    System.out.println("Contact First Name " + contact.getFirstName());
    System.out.println("Contact Last Name " + contact.getLastName());
    System.out.println("Contact Email " + contact.getEmail());
    request.getPortletSession().setAttribute("contact", contact);
    System.out.println("Exiting ViewModeController.handleEventRequest");
    }

    }

    The ViewModeController.java implements EventAwareController interface to indicate that it can be used for handling events. It has a handleEventRequest method that will get called when it receives event. Inside this method we get access to EventRequest and EventResponse object. I am reading Contact object which was passed as event payload and setting it as attribute in the PortletSession.

    The handleRenderRequest() method reads the value of Contact object from the PortletSession and then displays those values to the user

  • This is how the SpringTargetPortlet-portlet.xml file of SpringTargetPortlet looks like

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
    <bean id="viewController"
    class="com.webspherenotes.portlet.spring.ViewModeController" />
    <bean id="portletModeHandlerMapping"
    class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
    <property name="order" value="1" />
    <property name="portletModeMap">
    <map>
    <entry key="view">
    <ref bean="viewController" />
    </entry>
    </map>
    </property>
    </bean>
    <bean id="viewResolver"
    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass">
    <value>org.springframework.web.servlet.view.JstlView</value>
    </property>
    <property name="prefix">
    <value>/WEB-INF/jsp/</value>
    </property>
    <property name="suffix">
    <value>.jsp</value>
    </property>
    </bean>
    </beans>

    The SpringTargetPortlet has only one ViewModeController and it is set as default controller for the VIEW mode.

1 comment:

Ye said...

Thanks very much, exactly what I am looking for!