WebSphere Portal Login URL

I wanted to create a JMeter Unit Test for my potlet, which is available only for the logged in user. As a part of that test i wanted to see if i can pass userid and password to fixed URL and it will login for me.

WebSPhere Portal has this URL which you can call with user name and password as query parameter when you do that it will automatically login into portal for you and take you to the home page.


/wps/portal/cxml/04_SD9ePMtCP1I800I_KydQvyHFUBADPmuQy?userid=&password=


On my local development box websphere portal is available at http://localhost:10040/wpcert/demo and i my userid is sunil and password is password, so i can directly go to the


http://localhost:10040/wpcert/demo/cxml/04_SD9ePMtCP1I800I_KydQvyHFUBADPmuQy?userid=sunil&password=password


I bookmarked this URL on my local so that i dont have to login everytime

Reading the portlet.xml file everytime

When i was playing with Portlet Event on WebSPhere Portal Server, i noticed that if you add new events in the portlet.xml file after deploying portlet, that event does not get picked up.

Ex. First i did add hello event in portlet.xml and deployed it, created a wire and then i did add greeting event in both source and target and deployed them on WPS. After that when i tried creating wire the new events were not showing up in the Portlet Wiring Tool portlet. Only way i could get it working was by first uninstalling and then reinstalling the portlet. So i started looking for solution for what i can do to avoid this reinstalling of portlet application for my new events to show up.

It seems that when we deploy portlet on WPS for first time then portal reads the portlet.xml and caches information like events, preferences,... After that when we update the portlet it does not read the portlet.xml. You can change this behavior by changing value of cleanup.deployment.descriptors property in DeploymentService.


#
# If you set this property to true, all existing settings are cleared and deleted,
# and only the new settings found in the portlet.xml are created.

# Default = false
#cleanup.deployment.descriptors = false


After changing value of cleanup.deployment.descriptors to true like this i could see my changes in portlet.xml getting reflected with uninstall-reinstalling portlet again.

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.

Passing Complex Events in WSRP

In the Passing complex objects in portlet events entry i talked about how you can pass complex/custom objects as event payload.

You can download the sample code for this project from here

  1. Contact

  2. EventSource

  3. EventTarget



But you will have to make some additional changes to your portlet if you want to pass these object between portlets installed on different severs using WSRP. In case when objects are hosted on different server then portal server will serialize the complex object using JAXB and then send it to consumer. I changed my existing Contact object like this to make it work in WSRP


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;
}
}


I had to annotate the Contact object by adding @XmlRootElement this. You will have to copy the contact.jar in shared library of both producer and consumer. Also make sure that Contact class has no-arg constructor.


When my Contact.java class did not had constructor i was getting error like this.


[5/19/10 9:48:13:456 PDT] 00000071 PropertyDispa E com.ibm.wps.propertybroker.dispatch.PropertyDispatcherImpl dispatchSourceEvents EJPKB1002E: The propertybroker encountered an error while dispatching the source event {http://wpcertification.blogspot.com}hello from portlet window Control@1598316356 (SourcePortlet, [ObjectIDImpl '7_VVILMKG1009800I2DO701500G7', NAVIGATION_NODE, VP: 0, [Domain: rel], DB: 0000-FFCB6A290C00240480140D1F100A00F0], [ObjectIDImpl '6_VVILMKG10G4K30I2A4E1UM2007', CONTENT_NODE, VP: 0, [Domain: rel], DB: 0000-FFCB6A290C00123A80148AB8E0AD00E0], 100 with value com.webspherenotes.portlet.events.Contact@212c212c.
com.ibm.portal.propertybroker.exceptions.CommunicationTargetDispatchException: EJPKB1001E: An Error occurred while dispatching to the communication target

process.{http://wpcertification.blogspot.com}hello
11_VVILMKG1009800I2DO701500O3

{http://wpcertification.blogspot.com}hello
com.ibm.wps.pe.pc.util.JAXBEventPayloadWrapper
{http://wpcertification.blogspot.com}hello


for window Control@1605918648 (TargetPortlet, [ObjectIDImpl '7_VVILMKG1009800I2DO70150040', NAVIGATION_NODE, VP: 0, [Domain: rel], DB: 0000-FFCB6A290C00240480140D1F100A0004], [ObjectIDImpl '6_VVILMKG10G4K30I2A4E1UM2007', CONTENT_NODE, VP: 0, [Domain: rel], DB: 0000-FFCB6A290C00123A80148AB8E0AD00E0], 200.
at com.ibm.wps.propertybroker.standard.filter.JsrEventActionDispatcherPluginImpl.buildTargetJsrEventInformation(JsrEventActionDispatcherPluginImpl.java:263)
at com.ibm.wps.propertybroker.standard.filter.JsrEventActionDispatcherPluginImpl.dispatchCommunicationTarget(JsrEventActionDispatcherPluginImpl.java:106)
at com.ibm.wps.propertybroker.dispatch.PropertyDispatcherImpl.dispatchCommunicationTarget(PropertyDispatcherImpl.java:658)
at com.ibm.wps.propertybroker.dispatch.PropertyDispatcherImpl.dispatchCommunicationTargets(PropertyDispatcherImpl.java:611)
at com.ibm.wps.propertybroker.dispatch.PropertyDispatcherImpl.dispatchPropertyValues(PropertyDispatcherImpl.java:256)
at com.ibm.wps.propertybroker.dispatch.PropertyDispatcherImpl.dispatchSourceEvent(PropertyDispatcherImpl.java:138)
at com.ibm.wps.pe.pc.waspc.services.information.WaspcInformationProviderImpl$PortletEventProviderImpl.add(WaspcInformationProviderImpl.java:373)
at com.ibm.ws.portletcontainer.PortletContainerImpl.publishEventsToEventProvider(PortletContainerImpl.java:431)
at com.ibm.ws.portletcontainer.PortletContainerImpl.doAction(PortletContainerImpl.java:215)
at com.ibm.ws.portletcontainer.PortletContainerInvokerCollaboratorChainImpl.doCollaborator(PortletContainerInvokerCollaboratorChainImpl.java:78)
at com.ibm.ws.portletcontainer.ext.ExtCollaborator.doAction(ExtCollaborator.java:55)
at com.ibm.ws.portletcontainer.PortletContainerInvokerCollaboratorChainImpl.doCollaborator(PortletContainerInvokerCollaboratorChainImpl.java:65)
at com.ibm.ws.portletcontainer.cache.CacheInvokerCollaborator.doAction(CacheInvokerCollaborator.java:76)
at com.ibm.ws.portletcontainer.PortletContainerInvokerCollaboratorChainImpl.doCollaborator(PortletContainerInvokerCollaboratorChainImpl.java:65)
at com.ibm.ws.portletcontainer.PortletContainerImpl.processPortletAction(PortletContainerImpl.java:152)
at com.ibm.ws.portletcontainer.pcinvoker.PortletInvokerImpl$1.run(PortletInvokerImpl.java:59)
at java.security.AccessController.doPrivileged(AccessController.java:246)
at com.ibm.ws.portletcontainer.pcinvoker.PortletInvokerImpl.invokeProcessAction(PortletInvokerImpl.java:55)
at com.ibm.wps.pe.pc.waspc.core.impl.PortletInvokerImpl$3.invoke(PortletInvokerImpl.java:115)
at com.ibm.wps.pe.pc.waspc.core.impl.PortletInvokerImpl.invoke(PortletInvokerImpl.java:175)
at com.ibm.wps.pe.pc.waspc.core.impl.PortletInvokerImpl.invokeProcessAction(PortletInvokerImpl.java:113)
at com.ibm.wps.pe.pc.waspc.event.ActionEvent.execute(ActionEvent.java:78)
at com.ibm.wps.pe.pc.waspc.event.EventQueueManager.processEventLoop(EventQueueManager.java:112)
at com.ibm.wps.pe.pc.waspc.PortletContainerImpl.performEvents(PortletContainerImpl.java:206)
at com.ibm.wps.pe.pc.PortletContainerImpl.performEvents(PortletContainerImpl.java:298)
at com.ibm.wps.engine.phases.WPActionPhase.processPortlets(WPActionPhase.java:2644)
at com.ibm.wps.engine.phases.WPActionPhase.execute(WPActionPhase.java:668)
at com.ibm.wps.state.phases.AbstractActionPhase.next(AbstractActionPhase.java:130)
at com.ibm.wps.engine.Servlet.callPortal(Servlet.java:855)
at com.ibm.wps.engine.Servlet.doGet(Servlet.java:617)
at com.ibm.wps.engine.Servlet.doPost(Servlet.java:888)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:763)
at com.ibm.wps.engine.Servlet.doFilter(Servlet.java:1257)
at com.ibm.wps.resolver.servlet.ContentHandlerCleanup.doFilter(ContentHandlerCleanup.java:648)
at com.ibm.wps.resolver.servlet.AbstractFilter.doFilter(AbstractFilter.java:93)
at com.ibm.wps.engine.Servlet.service(Servlet.java:1248)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1146)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1087)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:145)
at com.ibm.wps.engine.ExtendedLocaleFilter.doFilter(ExtendedLocaleFilter.java:113)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:130)
at com.ibm.wps.resolver.friendly.servlet.FriendlySelectionFilter.doFilter(FriendlySelectionFilter.java:191)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:130)
at com.ibm.wps.mappingurl.impl.URLAnalyzer.doFilter(URLAnalyzer.java:352)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:130)
at com.ibm.wps.engine.VirtualPortalFilter.doFilter(VirtualPortalFilter.java:88)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:130)
at com.ibm.wps.state.filter.StateCleanup.doFilter(StateCleanup.java:94)
at com.ibm.ws.webcontainer.filter.FilterInstanceWrapper.doFilter(FilterInstanceWrapper.java:190)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain.doFilter(WebAppFilterChain.java:130)
at com.ibm.ws.webcontainer.filter.WebAppFilterChain._doFilter(WebAppFilterChain.java:87)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:837)
at com.ibm.ws.webcontainer.filter.WebAppFilterManager.doFilter(WebAppFilterManager.java:680)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:588)
at com.ibm.ws.wswebcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:524)
at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3517)
at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:269)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:818)
at com.ibm.ws.wswebcontainer.WebContainer.handleRequest(WebContainer.java:1478)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:125)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:458)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:387)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:267)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminators(NewConnectionInitialReadCallback.java:214)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:113)
at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
at com.ibm.io.async.AsyncChannelFuture$1.run(AsyncChannelFuture.java:205)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1497)
Caused by: com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 1 counts of IllegalAnnotationExceptions
com.webspherenotes.portlet.events.Contact does not have a no-arg default constructor.
this problem is related to the following location:
at com.webspherenotes.portlet.events.Contact

at com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:66)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:389)
at com.sun.xml.bind.v2.runtime.JAXBContextImpl.(JAXBContextImpl.java:236)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:76)
at com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:79)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:618)
at javax.xml.bind.ContextFinder.newInstance(ContextFinder.java:210)
at javax.xml.bind.ContextFinder.find(ContextFinder.java:381)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:574)
at javax.xml.bind.JAXBContext.newInstance(JAXBContext.java:522)
at com.ibm.wsspi.portletcontainer.util.EventFactory.serializeJAXB(EventFactory.java:285)
at com.ibm.wsspi.portletcontainer.util.EventFactory.serializeJAXB(EventFactory.java:166)
at com.ibm.wps.propertybroker.standard.filter.JsrEventActionDispatcherPluginImpl.buildTargetJsrEventInformation(JsrEventActionDispatcherPluginImpl.java:226)
... 72 more

Passing Complex Objects using portlet events

In the Hello Portlet Events entry, i built a sample to demonstrate how you can pass simple String using as value of event from one portlet to another. But if you want to pass a custom/ complex object and source and target portlets are not packaged in the same .war file then you will have to follow some additional steps.

I built 2 sample portlets to demonstrate how you can pass complex object from one portlet to another. The EventSourcePortlet passes object of com.webspherenotes.portlet.events.Contact type to TargetSourcePortlet.

You can download the sample code for this project from here

  1. Contact

  2. EventSource

  3. EventTarget



I had to follow these steps


  1. I started by creating Contact Java project, this project has Contact.java class like this

    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 class is simple POJO class and it implements Serializable interface. That is because the setEvent() method takes object of Serializable type as argument for event value

  2. Compile the Contact java source into contact.jar and copy it into shared library of your portal. In case of WebSphere portal it will be WebSphere/PortalServer/shared/app

  3. Create EventSourcePortlet project and in that create EventSourcePortlet.java like this

    public class EventSourcePortlet extends javax.portlet.GenericPortlet {
    public void init() throws PortletException {
    super.init();
    }
    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    System.out.println("Entering SourcePortlet.doView()");
    response.setContentType("text/html");
    if (request.getPortletSession().getAttribute("contact") != null) {
    request.setAttribute("contact", request.getPortletSession()
    .getAttribute("contact"));
    }
    getPortletContext().getRequestDispatcher("/source.jsp").include(
    request, response);
    System.out.println("Exiting SourcePortlet.doView()");
    }
    public void processAction(ActionRequest request, ActionResponse response)
    throws PortletException, IOException {
    System.out.println("Entering SourcePortlet.processAction()");
    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 SourcePortlet.processAction()");
    }
    }

    The doView() method of the EventSourcePortlet is forwarding control to contact.jsp for rendering. The contact.jsp displays a simple form to user where user can input firstName, lastName and email.

    The processAction() method of EventSourcePortlet gets control when user enters values on the form and clicks submit. In this method, I am reading values submitted by user and then creating a Contact object and then setting and event with name equal to hello and value equal to the Contact object.


  4. Create EventTargetPortlet and inside that create EventTargetPortlet.java like this

    public class EventTargetPortlet extends javax.portlet.GenericPortlet {
    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    System.out.println("Entering TargetPortlet.doView()");
    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("Exiting TargetPortlet.doView()");
    }

    public void processEvent(EventRequest request, EventResponse response)
    throws PortletException, IOException {
    System.out.println("Entering TargetPortlet.processEvent");
    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 TargetPortlet.processEvent");
    }
    }

    The processEvent() method of the EventTargetPortlet get control whenever it receives event, in this method it is reading the Contact object that was sent as event payload and then setting it as attribute in PortletSession.
    In the doView() method it reads the Contact object from PortletSession and prints those values

  5. This is how the portlet.xml file for the EventSourcePortlet looks like

    <?xml version="1.0" encoding="UTF-8"?>
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    id="com.webspherenotes.portlet.event.EventSourcePortlet.1a884b6b82">
    <portlet>
    <portlet-name>EventSourcePortlet</portlet-name>
    <display-name xml:lang="en">EventSourcePortlet</display-name>
    <display-name>EventSourcePortlet</display-name>
    <portlet-class>com.webspherenotes.portlet.event.EventSourcePortlet</portlet-class>
    <init-param>
    <name>wps.markup</name>
    <value>html</value>
    </init-param>
    <expiration-cache>0</expiration-cache>
    <supports>
    <mime-type>text/html</mime-type>
    <portlet-mode>view</portlet-mode>
    </supports>
    <supported-locale>en</supported-locale>
    <resource-bundle>com.webspherenotes.portlet.event.nl.EventSourcePortletResource</resource-bundle>
    <portlet-info>
    <title>EventSourcePortlet</title>
    <short-title>EventSourcePortlet</short-title>
    <keywords>EventSourcePortlet</keywords>
    </portlet-info>
    <supported-publishing-event>
    <name>hello</name>
    </supported-publishing-event>
    </portlet>
    <default-namespace>http://wpcertification.blogspot.com</default-namespace>
    <event-definition>
    <name>hello</name>
    <value-type>com.webspherenotes.portlet.events.Contact</value-type>
    </event-definition>
    </portlet-app>

    As you can see the value-type of the event is com.webspherenotes.portlet.events.Contact to indicate that we want to send object of Contact class as event payload

Hello Portlet Events

The Portlet Specification 2.0 has concept of Events, that can be used for portlet to portlet communication. I built this sample HelloEventsPortlet to demonstrate how to create simple portlet events communication

The HelloEventsPortlet application has two portlets SourcePortlet, which will display Action URL to the user in VIEW mode and when user clicks on the ActionURL it will set hello event in the processAction method, the TargetPortlet will act as consumer for the event and in the processEvent method it will read value of the event and set it as render parameter and display that value to the user in VIEW mode markup. Follow these steps to create events portlet


  • First create SourcePortlet.java like this


    package com.webspherenotes.portlet.events;

    import java.io.IOException;

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

    public class SourcePortlet extends GenericPortlet{

    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    System.out.println("Entering SourcePortlet.doView()");
    response.setContentType("text/html");
    getPortletContext().getRequestDispatcher("/source.jsp").include(request, response);
    System.out.println("Exiting SourcePortlet.doView()");
    }

    public void processAction(ActionRequest request, ActionResponse response)
    throws PortletException, IOException {
    System.out.println("Entering SourcePortlet.processAction()");
    response.setEvent("hello", "Hello event from the SourcePortlet");
    System.out.println("Exiting SourcePortlet.processAction()");
    }

    }

    The SourcePortlet has doView() and processAction() methods, in doView() method it is forwarding control to source.jsp for generating markup, the source.jsp generates a simple ActionURL.
    In the processAction() method it is calling response.setEvent("hello", "Hello event from the SourcePortlet"), which is used for publishing hello event.


  • This is how my TargetPortlet.java looks like

    package com.webspherenotes.portlet.events;

    import java.io.IOException;

    import javax.portlet.Event;
    import javax.portlet.EventPortlet;
    import javax.portlet.EventRequest;
    import javax.portlet.EventResponse;
    import javax.portlet.GenericPortlet;
    import javax.portlet.PortletException;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;

    public class TargetPortlet extends GenericPortlet implements EventPortlet{

    protected void doView(RenderRequest request, RenderResponse response)
    throws PortletException, IOException {
    System.out.println("Entering TargetPortlet.doView()");
    response.setContentType("text/html");
    response.getWriter().println("Hello from TargetPortlet.doView() " + request.getParameter("helloEvent"));
    System.out.println("Exiting TargetPortlet.doView()");
    }

    public void processEvent(EventRequest request, EventResponse response)
    throws PortletException, IOException {
    System.out.println("Entering TargetPortlet.processEvent");
    Event event= request.getEvent();
    System.out.println("Event Name " + event.getName());
    String eventValue =(String)event.getValue();
    System.out.println("Event Value " + eventValue);
    response.setRenderParameter("helloEvent", eventValue);

    System.out.println("Exiting TargetPortlet.processEvent");
    }

    }

    The TargetPortlet is implementing EventPortlet to indicate that it can act as consumer of event. The TargetPortlet has doView() and processEvent() methods, in doView() it is simply reading value of helloEvent render parameter and displaying it to user.

    The portlet container will call processEvent() method to give TargetPortlet chance to consume the event, it will get called before the render phase. You can call EventRequest.getEvent()method inside the processEvent() method to get the Event object and once you have the event object you can call its getName() and getValue() methods to read name and value of the event. After reading the value of event i am setting it as render parameter for the portlet.


  • This is how my portlet.xml file looks like

    <?xml version="1.0" encoding="UTF-8"?>
    <portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd"
    version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd">
    <portlet>
    <portlet-name>SourcePortlet</portlet-name>
    <display-name>Events Source Portlet</display-name>
    <portlet-class>com.webspherenotes.portlet.events.SourcePortlet</portlet-class>
    <expiration-cache>0</expiration-cache>
    <supports>
    <mime-type>text/html</mime-type>
    <portlet-mode>view</portlet-mode>
    <portlet-mode>edit</portlet-mode>
    </supports>
    <portlet-info>
    <title>Event Source Portlet</title>
    <short-title>Event Source Portlet</short-title>
    <keywords>Event Source Portlet</keywords>
    </portlet-info>
    <supported-publishing-event>
    <name>hello</name>
    </supported-publishing-event>

    </portlet>
    <portlet>
    <portlet-name>TargetPortlet</portlet-name>
    <display-name>Events Target Portlet</display-name>
    <portlet-class>com.webspherenotes.portlet.events.TargetPortlet</portlet-class>
    <expiration-cache>0</expiration-cache>
    <supports>
    <mime-type>text/html</mime-type>
    <portlet-mode>view</portlet-mode>
    <portlet-mode>edit</portlet-mode>
    </supports>
    <portlet-info>
    <title>Event Target Portlet</title>
    <short-title>Event Target Portlet</short-title>
    <keywords>Event Target Portlet</keywords>
    </portlet-info>
    <supported-processing-event>
    <name>hello</name>
    </supported-processing-event>

    </portlet>
    <default-namespace>http://wpcertification.blogspot.com</default-namespace>
    <event-definition>
    <name>hello</name>
    <value-type>java.lang.String</value-type>
    </event-definition>

    </portlet-app>

    There are three components in the portlet.xml

    1. event-definition: Element is declared at the portlet application level and it defines name of the event and the type of the event. In my case name of the event is hello and type is java.lang.Style

    2. supported-publishing-event: Element is used for declaring what all events can be published by this portlet

    3. supported-processing-event: Element is used for defining what all events can be consumed by this portlet



  • After developing this portlet deploy it in WebSphere Portal server and add them to a portal page

  • Now create a wire between consumer and producer using Portlet Wiring Portlet like this




Now you can test this portlet by clicking on the Action URL in the Source Portlet, you will notice that the TargetPortlet is displaying the value of event to user

What are Portlet Events

Portlet events are intended to allow portlets to react to actions or state changes not directly related to an interaction of the user with the portlet. Events could be either portal or portlet container generated or the result of a user interaction with other portlets. The portlet event model is a loosely coupled, brokered model that allows creating portlets as stand-alone portlets that can be wired together with other portlets at runtime. In response to an event a portlet may publish new events that should be delivered to other portlets and thus may trigger state changes on these other portlets.

In order to receive events the portlet must implement the EventPortlet interface in the javax.portlet package. The portlet container will call the processEvent method for each event targeted to the portlet with an EventRequest and EventResponse object. Events are targeted by the portal / portlet container to a specific portlet window in the current client request.

Events are a life cycle operation that occurs before the rendering phase. The portlet may issue events via the setEvent method during the action processing which will be processed by the portlet container after the action processing has finished. As a result of issuing an event the portlet may optionally receive events from other portlets or container events. A portlet that is not target of a user action may optionally receive container events, e.g. a portlet mode changed event, or events from other portlets, e.g. an item was added to the shopping cart event.

Handling multiple resource requests in Spring Portlet

The Handling Resource request in Spring MVC Portlet, demonstrates how to make a resource request to the Spring Portlet MVC Framework portlet, that portlet has only one Controller class, but in reality you will want to have more than one Controller classes for handling different resource request

I did create a MultipleResourceRequests portlet to demonstrate how you can have different Controller classes for handling different resource requests inside your Spring Portlet. My sample portlet has 4 Controller first is ViewModeController which is used for handling render request for VIEW mode and three different controllers Resource1Controller, Resource2Controller and Resource3Controller for handling resource requests. The Spring Portlet MVC Framework makes use value of action parameter to route request to different Controller, we will use different values of action parameters for routing resource requests to one of our ResourceController

This is how my ViewModeController.java looks like

package com.webspherenotes.portlet;

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;

public class ViewModeController extends AbstractController{

public ModelAndView handleRenderRequest(RenderRequest request,
RenderResponse response) throws Exception {
System.out.println("Entering ViewModeController.handleRenderRequest()");
ModelAndView modelAndView = new ModelAndView("view");
System.out.println("Exiting ViewModeController.handleRenderRequest()");
return modelAndView;
}

}


The ViewModeController has only handleRenderRequest, which gets invoked when the portlet gets render request and inside this method i am forwarding control to view.jsp for generating markup. This is how my view.jsp looks like


<%@page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1" session="false"%>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>

<portlet:defineObjects />

<portlet:resourceURL var="resource1Url" >
<portlet:param name="action" value="resource1" />
</portlet:resourceURL>
<portlet:resourceURL var="resource2Url" >
<portlet:param name="action" value="resource2" />
</portlet:resourceURL>
<portlet:resourceURL var="resource3Url" >
<portlet:param name="action" value="resource3" />
</portlet:resourceURL>

<script type="text/javascript">
dojo.addOnLoad( function () { dojo.parser.parse( "<portlet:namespace/>portletWidgetContainer" ); } );
dojo.require("dijit.form.Button");
dojo.require("dojo.parser");
</script>

<div id="<portlet:namespace/>portletWidgetContainer">
<button dojoType="dijit.form.Button" id="btn1">Resource1
<script type="dojo/method" event="onClick">
dojo.xhrGet({
url: "<%=resource1Url%>",
load: function(data, ioargs){
dojo.byId("resourceResponse").innerHTML = data;
},
error: function(error,ioargs){
alert(error);
}
});
</script>
</button><br/>
<button dojoType="dijit.form.Button" id="btn2">Resource2
<script type="dojo/method" event="onClick">
dojo.xhrGet({
url: "<%=resource2Url%>",
load: function(data, ioargs){

dojo.byId("resourceResponse").innerHTML = data;
},
error: function(error,ioargs){
alert(error);
}
});
</script>
</button><br/>
<button dojoType="dijit.form.Button" id="btn3">Resource3
<script type="dojo/method" event="onClick">
dojo.xhrGet({
url: "<%=resource3Url%>",
load: function(data, ioargs){
dojo.byId("resourceResponse").innerHTML = data;
},
error: function(error,ioargs){
alert(error);
}
});
</script>
</button><br/>
<div id="resourceResponse" />
</div>


The view.jsp is using Dojo and Dijit to display three different buttons. When you click on this button it is making a resourceURL call and while making resourceURL call it is setting value of action parameter as either resource1, resource2 or resource3

One the Spring Portlet gets control it will look at value of action parameter to figure out the Controller that should be used for handling this request. It does by finding the entry for value of action parameter in portletModeParameterMap

<?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.ViewModeController" />
<bean id="resource1Controller" class="com.webspherenotes.portlet.Resource1Controller" />
<bean id="resource2Controller" class="com.webspherenotes.portlet.Resource2Controller" />
<bean id="resource3Controller" class="com.webspherenotes.portlet.Resource3Controller" />
<bean id="parameterMappingInterceptor"
class="org.springframework.web.portlet.handler.ParameterMappingInterceptor" />
<bean id="portletModeParameterHandlerMapping"
class="org.springframework.web.portlet.handler.PortletModeParameterHandlerMapping">
<property name="order" value="1" />
<property name="interceptors">
<list>
<ref bean="parameterMappingInterceptor" />
</list>
</property>
<property name="portletModeParameterMap">
<map>
<entry key="view">
<map>
<entry key="view">
<ref bean="viewController" />
</entry>
<entry key="resource1">
<ref bean="resource1Controller" />
</entry>
<entry key="resource2">
<ref bean="resource2Controller" />
</entry>
<entry key="resource3">
<ref bean="resource3Controller" />
</entry>

</map>

</entry>
</map>
</property>
</bean>
<bean id="portletModeHandlerMapping"
class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="order" value="2" />
<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 sample portlet configuration set ViewModeController as default controller for the portlet and then maps Resource1Controller to resource1 and so on. This is how my Resource1Controller looks like


package com.webspherenotes.portlet;

import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

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

public class Resource1Controller extends AbstractController implements ResourceAwareController{

public ModelAndView handleResourceRequest(ResourceRequest arg0,
ResourceResponse arg1) throws Exception {
System.out.println("Entering Resource1Controller.handleResourceRequest()");
ModelAndView modelAndView = new ModelAndView("resource1");
System.out.println("Exiting Resource1Controller.handleResourceRequest()");
return modelAndView;
}
}


The Resource1Controller implements only handleResourceRequest method, that means it can only handle resource request. Inside the handleResourceRequest method it is forwarding control to resource1.jsp for generating markup

Handling Resource request in Spring MVC Portlet

Starting from Version 3.0.1, Spring Framework support some of the new features introduced in the Portlet Specification 2.0 (JSR 286). One of the new features in the Portlet Specification 2.0, is ability to make resource request.

The Spring Portlet MVC Framework 3.0.* has concept of ResourceAwareController interface that you can implement in your Controller class to indicate that your Controller can be used for handling resource request. You can download the sample code from here

I built this simple ServeResource portlet to demonstrate how to handle resource request in Spring Portlet MVC Framework. The sample portlet supports only VIEW mode and it has only one ViewController class for handling all the requests


package com.webspherenotes.mvc.spring.action;

import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

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

public class ViewController extends AbstractController implements ResourceAwareController{
protected ModelAndView handleRenderRequestl(RenderRequest request,
RenderResponse response) throws Exception {
System.out.println("Entering ViewController.handleRenderRequest()");
ModelAndView modelAndView = new ModelAndView("hello");
System.out.println("Exiting ViewController.handleRenderRequest()");
return modelAndView;
}
public ModelAndView handleResourceRequest(ResourceRequest arg0,
ResourceResponse arg1) throws Exception {
System.out.println("Entering ViewController.handleResourceRequest()");
ModelAndView modelAndView = new ModelAndView("helloresource");
System.out.println("Exiting ViewController.handleResourceRequest()");
return modelAndView;
}
}


The ViewController implements ResourceAwareController interface and as a result it has implement
handleResourceRequest() method which gets called whenever a resource call is made to the portlet.

  1. handleRenderRequest: This method will get called to handle render request for the portlet in the VIEW mode. In my sample portlet i am working control to hello.jsp for generating markup

  2. handleResourceRequest: This method will get called to handle resource request for the portlet. Inside this method you will get access to ResourceRequest and ResourceResponse object and after processing the request, you can return object of ModelAndView type which will be used for forwarding control to JSP. In my sample portlet i am forwarding control to helloresource.jsp for generating markup for resource request



This is how my hello.jsp, looks like. This jsp has one "Resource Call" button and when you click on that button, it makes use of JavaScript to make a HTTP Get call to portlet:resourceURL, and once the response is returned it is displaying that response as alert on the page


<%@page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" session="false"%>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>
<portlet:defineObjects />
<h1>Hello from doView</h1>
<script type="text/javascript">
function createXMLHttpRequestObject() {
var xmlHttp;
try {
xmlHttp = new XMLHttpRequest();
} catch (e) {
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHttp");
} catch (e) {
}
}
if (!xmlHttp)
alert("Error creating the XMLHttpRequest object.");
else
return xmlHttp;
}
var xmlHttp = createXMLHttpRequestObject();
function makeResourceCall(){
if (xmlHttp){
try{
xmlHttp.open("GET", "<portlet:resourceURL/>", true);
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(null);
}catch (e){
alert("Can't connect to server:\n" + e.toString());
}
}
}
function handleRequestStateChange(){
if (xmlHttp.readyState == 4){
if (xmlHttp.status == 200){
alert(xmlHttp.responseText);

}
}
}
</script>
<input type="button" onclick="JavaScript:makeResourceCall()" value="Resource Call" />


The helloresource.jsp is pretty simple, it is just returning following text

This is response of ServeResourcePortlet.serveResource() call

Process for installing and uninstalling fix

Follow these steps, If you want to apply a ifix to the WebSphere Portal Server


  • Setup the Update Installer for portal.

  • Copy the fix related jar in the /software/IBM/WebSphere/PortalServer/update/fixes directory

  • Then install the fix by executing following command

    ./updatePortal.sh -fix -install -fixes PM13802 -fixDir /software/IBM/WebSphere/PortalServer/update/fixes -installDir /software/IBM/WebSphere/PortalServer

    This command will install PK13802 on your portal server



This command can be used to uninstall existing fix from the portal server

./updatePortal.sh -fix -uninstall -fixes PM13802 -fixDir /apps/ibm/websphere/portalserver/update/fixes -installDir /apps/ibm/websphere/portalserver

Handling Multiple Actions in Spring Portlet MVC Framework

In the Handling actions in Spring Portlet MVC Framework entry, we looked at the sample of how to handle action request inside your portlet. But that portlet had only one controller. In most of the real world scenarios you will want to break your portlet into multiple Controllers where a different Controller class will be responsible for handling different actions.

In this entry we will look at sample of how you can use multiple Controllers in one Mode and how to forward control to these controllers based on URL parameter. The MultipleActionsPortlet will have 4 Controllers for VIEW mode. ViewModeController will be the default Controller, which will get control when you call portlet for first time, It will have Action1Controller, Action2Controller and Action3Controller, depending on value of the action parameter. Each of these Controllers simply forward control to different JSPs. You can download sample code from here.

This is how the ViewModeController.java looks like

package com.webspherenotes.portlet;

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;

public class ViewModeController extends AbstractController{

public void handleActionRequest(ActionRequest request,
ActionResponse response) throws Exception {
System.out.println("Entering ViewModeController.handleActionRequest()");
System.out.println("Exiting ViewModeController.handleActionRequest()");
}

public ModelAndView handleRenderRequest(RenderRequest request,
RenderResponse response) throws Exception {
System.out.println("Entering ViewModeController.handleRenderRequest()");
ModelAndView modelAndView = new ModelAndView("view");
System.out.println("Exiting ViewModeController.handleRenderRequest()");
return modelAndView;
}


}


The ViewModeController is very simple, only thing that it does is forward control to view.jsp for generating markup. This is how the view.jsp looks like

<%@page language="java" contentType="text/html; %>
<%@taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet"%>

<portlet:defineObjects />

<h1>view.jsp</h1>
<table>
<tr>
<td>
<a href='<portlet:actionURL>
<portlet:param name="action" value="action1" />
</portlet:actionURL>'>Action 1</a>
</td>
</tr>
<tr>
<td>
<a href='<portlet:actionURL>
<portlet:param name="action" value="action2" />
</portlet:actionURL>'>Action 2</a>
</td>
</tr>
<tr>
<td>
<a href='<portlet:actionURL>
<portlet:param name="action" value="action3" />
</portlet:actionURL>'>Action 3</a>
</td>
</tr>
</table>


The view.jsp is generating 3 different actionURL's with different values for action parameter. The Spring Portlet MVC framework reads the value of action parameter to decide which Controller class will get control for handling the URL.

I did create three similar ActionControllers for handling other 3 actions, This is how the Action1Controller looks like

package com.webspherenotes.portlet;

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;

public class Action1Controller extends AbstractController{

public void handleActionRequest(ActionRequest request,
ActionResponse response) throws Exception {
System.out.println("Entering Action1Controller.handleActionRequest()");
System.out.println("Exiting Action1Controller.handleActionRequest()");
}

public ModelAndView handleRenderRequest(RenderRequest request,
RenderResponse response) throws Exception {
System.out.println("Entering Action1Controller.handleRenderRequest()");
ModelAndView modelAndView = new ModelAndView("action1");
System.out.println("Exiting Action1Controller.handleRenderRequest()");
return modelAndView;
}

}


The handleActionRequest of Action1Controller does not do anything only thing that it does in handleRenderRequest is to forward control to action1.jsp for rendering markup.

The most important part in handling multiple actions is the Spring Configuration, this is how my Spring configuration 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.ViewModeController" />
<bean id="action1Controller"
class="com.webspherenotes.portlet.Action1Controller" />
<bean id="action2Controller"
class="com.webspherenotes.portlet.Action2Controller" />
<bean id="action3Controller"
class="com.webspherenotes.portlet.Action3Controller" />


<bean id="parameterMappingInterceptor"
class="org.springframework.web.portlet.handler.ParameterMappingInterceptor" />
<bean id="portletModeParameterHandlerMapping"
class="org.springframework.web.portlet.handler.PortletModeParameterHandlerMapping">
<property name="order" value="1" />
<property name="interceptors">
<list>
<ref bean="parameterMappingInterceptor" />
</list>
</property>
<property name="portletModeParameterMap">
<map>
<entry key="view">
<map>
<entry key="view">
<ref bean="viewController" />
</entry>
<entry key="action1">
<ref bean="action1Controller" />
</entry>
<entry key="action2">
<ref bean="action2Controller" />
</entry>
<entry key="action3">
<ref bean="action3Controller" />
</entry>

</map>
</entry>
</map>
</property>
</bean>


<bean id="portletModeHandlerMapping"
class="org.springframework.web.portlet.handler.PortletModeHandlerMapping">
<property name="order" value="2" />
<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>




As you can see, we have defined two new bean definitions in the SpringContactManagPortlet-portlet.xml file.

  1. parameterMappingInterceptor. The parameterMappingInterceptor is used to forward the value of the action request parameter from ActionRequest to RenderRequest, so that Spring Portlet MVC Framework uses the same controller for handling both the action request and the render request. If you dont use this interceptor you will have to manually copy value of action parameter in handleActionRequest as render parameter

  2. portletModeParameterHandlerMapping. portletModeParameterHandlerMapping is an advanced implementation of HandlerMapping that uses the portlet mode as well as the value of the action request parameter to resolve the handler for the request. In the sample code, we have more than one handler in View mode so we use portletModeParameterHandlerMapping. The portletModeParameterHandlerMapping bean has the portletModeParameterMap property, which is a map of all the portlet modes that your portlet supports. This map takes key value pairs with the name of the portlet mode as the key. Value is another map that takes the value of the action request parameter as the key and the reference to the controller that handles its request as its value.



We also have the old org.springframework.web.portlet.handler.PortletModeHandlerMapping bean which is mapping ViewModeController as default Controller for the VIEW mode, its required for handling the default request or the request which does not have action parameter. It has property order equal to 2 to demonstrate that this HandleMapping bean should be used only if the portletModeParameterHandlerMapping is not able to map request to Controller

Finding out unique name of the portlet that is being rendered

In the Getting name of the page where your portlet is getting rendered, so i wanted to also build a sample to demonstrate how to get the unique name of the portlet that is being rendered.

This might not be of much use in Local portlet, but if your portlet is getting consumed using WSRP and unique name of the portlet on producer and consumer is different then you can use this SPIUtil.java class to get uniquename of the portlet that is being rendered


package com.webspherenotes.jsr286.filters;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ibm.portal.ModelException;
import com.ibm.portal.ObjectID;
import com.ibm.portal.content.ContentModel;
import com.ibm.portal.content.ContentNode;
import com.ibm.portal.content.ContentPage;
import com.ibm.portal.content.LayoutContainer;
import com.ibm.portal.content.LayoutControl;
import com.ibm.portal.content.LayoutModel;
import com.ibm.portal.content.LayoutNode;
import com.ibm.portal.model.ContentModelHome;
import com.ibm.portal.model.NavigationSelectionModelHome;
import com.ibm.portal.model.NavigationSelectionModelProvider;
import com.ibm.portal.model.PortletModelHome;
import com.ibm.portal.navigation.NavigationNode;
import com.ibm.portal.navigation.NavigationSelectionModel;
import com.ibm.portal.portletmodel.PortletDefinition;
import com.ibm.portal.portletmodel.PortletModel;
import com.ibm.portal.portletmodel.PortletWindow;

public class SPIUtil {

private static final Logger logger = LoggerFactory.getLogger(SPIUtil.class);

private NavigationSelectionModelHome navigationSelectionModelHome;
private ContentModelHome contentModelHome;
private PortletModelHome portletModelHome;

public String getPortletName(PortletRequest renderRequest, PortletResponse renderResponse){
try {
if (navigationSelectionModelHome != null) {
NavigationSelectionModelProvider provider =
navigationSelectionModelHome.getNavigationSelectionModelProvider();
NavigationSelectionModel model =
provider.getNavigationSelectionModel((ServletRequest)renderRequest, (ServletResponse)renderResponse);
ContentModel contentModel =(ContentModel)contentModelHome.getContentModelProvider().getContentModel((ServletRequest)renderRequest, (ServletResponse)renderResponse);

NavigationNode navigationNode = (NavigationNode) model.getSelectedNode();

ContentNode contentNode = navigationNode.getContentNode();
ContentPage contentPage =(ContentPage) contentModel.getLocator().findByID(contentNode.getObjectID());

LayoutModel layoutModel = contentModel.getLayoutModel(contentPage);
List portletList = getAllChildPortlets((LayoutNode)layoutModel.getRoot(), layoutModel);
String nameSpaceStr = renderResponse.getNamespace();
String nameSpacePortletId = nameSpaceStr.substring(3);

nameSpacePortletId = nameSpacePortletId.substring(0,nameSpacePortletId.length()-1);

for(int i = 0 ; i < portletList.size() ; i++){
LayoutControl container = (LayoutControl)portletList.get(i);
String currentWindowObjectId = getObjectIDStr(container.getObjectID());
if(nameSpacePortletId.equals(currentWindowObjectId)){
String portletName =getPortletName((ServletRequest)renderRequest, (ServletResponse)renderResponse, contentPage, container);
return portletName;
}
}
}
} catch (ModelException e) {
logger.error("Error in SPIUtil.getPortletName() " + e.getMessage(),e);
e.printStackTrace();
}
return null;
}

public void init(){
logger.debug("Entering SPIUtil.init()");
try {
InitialContext context = new InitialContext();
navigationSelectionModelHome = (NavigationSelectionModelHome) context
.lookup(NavigationSelectionModelHome.JNDI_NAME);
contentModelHome = (ContentModelHome) context
.lookup(ContentModelHome.JNDI_NAME);
portletModelHome = (PortletModelHome)context.lookup(PortletModelHome.JNDI_NAME);
} catch (NamingException e) {
logger.error("Error in SPIUtil.init() " + e.getMessage(),e);
}
logger.debug("Exiting SPIUtil.init()");
}

private List getAllChildPortlets(LayoutNode subtreeRoot,
LayoutModel lm) throws ModelException {
List aList = new LinkedList();
if (subtreeRoot instanceof LayoutContainer) {
Iterator itr = lm.getChildren(subtreeRoot);
while (itr.hasNext()) {
Object o = itr.next();
Iterator itr2 = getAllChildPortlets((LayoutNode) o, lm)
.iterator();
while (itr2.hasNext()) {
Object o1 = itr2.next();
aList.add(o1);
}
}
} else {
aList.add(subtreeRoot);
}
return aList;
}

private static String getObjectIDStr(ObjectID objectID){
String temp = objectID.toString();
int firstInd = temp.indexOf("'");
String result = temp.substring(firstInd+1, temp.indexOf("'", firstInd+1 ));
return result;
}

private String getPortletName(ServletRequest request, ServletResponse response, ContentPage contentPage,
LayoutControl layoutControl ){
logger.debug("Entering SPIUtil.getPortletName()");

try {
PortletModel portletModle = portletModelHome.getPortletModelProvider().getPortletModel(contentPage,request,response);
PortletWindow portletWindow = portletModle.getPortletWindow(layoutControl);
PortletDefinition portletDefinition = portletModle.getPortletDefinition(portletWindow);
logger.debug("Exiting SPIUtil.getPortletName()");
return portletDefinition.getObjectID().getUniqueName();
} catch (ModelException e) {
logger.error("Error in SPIUtil.getPortletName() " + e.getMessage(),e);
}
return null;
}

}


In order to use this class you will have to call its init method from the init method of your portlet then call its getPortletName method to get name of the portlet being displayed

Getting name of the page where your portlet is getting rendered

Knowing name of the page where your portlet is getting rendered is one of the very common requirement, i know as per portlet specification your portlet should not be aware about where it is getting rendered but in reality there are requirements that portlet needs to behave differently based on the position where it is getting rendered.

The WebSphere Portal Server has concept of NavigationSelectionModel SPI that you can use to know about the current page.This SPI is used by the theme to know the page which should be displayed to the user. I built a PageNameFilter that makes use of the NavigationSelectionModel to find out where the page is getting rendered and passing it to the portlet as value of com.webspherenotes.filter.pageName request attribute, so that it works on both local portlet as well as cases when the portlet is getting consumed as WSRP (in case of WSRP, it will give you name of the page where portlet is getting consumed)


package com.webspherenotes.portlet.filter;

import java.io.IOException;
import java.util.Locale;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletResponse;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ibm.portal.ModelException;
import com.ibm.portal.content.ContentNode;
import com.ibm.portal.model.NavigationSelectionModelHome;
import com.ibm.portal.model.NavigationSelectionModelProvider;
import com.ibm.portal.navigation.NavigationNode;
import com.ibm.portal.navigation.NavigationSelectionModel;

public class PageNameFilter implements RenderFilter{
private static final Logger logger = LoggerFactory.getLogger(PageNameFilter.class);
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("Entering PageNameFilter.doFilter()");
String pageName = getPageTitle(request, response);
System.out.println("Page Name inside PageNameFilter " + pageName);
PageNameRenderRequestWrapper pageNameRequestWrapper = new PageNameRenderRequestWrapper(request);
pageNameRequestWrapper.setPageName(pageName);
filterChain.doFilter(pageNameRequestWrapper, response);
logger.debug("Exiting PageNameFilter.doFilter()");
}

private String getPageTitle(PortletRequest request, PortletResponse response){
try {
if (navigationSelectionModelHome != null) {
NavigationSelectionModelProvider provider =
navigationSelectionModelHome.getNavigationSelectionModelProvider();
NavigationSelectionModel model =
provider.getNavigationSelectionModel((ServletRequest)request, (ServletResponse)response);
NavigationNode navigationNode = (NavigationNode) model.getSelectedNode();
ContentNode contentNode = navigationNode.getContentNode();
if( contentNode.getObjectID().getUniqueName() != null){
logger.debug("The portlet is getting rendered on " + contentNode.getObjectID().getUniqueName());
}else{
logger.debug("The portlet is getting rendered on " + contentNode.getObjectID());
}
String pageTitle = contentNode.getTitle(request.getLocale());
if(pageTitle == null){
pageTitle = contentNode.getTitle(new Locale("en"));
if(pageTitle == null){
pageTitle = contentNode.getObjectID().getUniqueName();
if(pageTitle == null)
pageTitle = contentNode.getObjectID().toString();
}
}
return pageTitle;
}
} catch (ModelException e) {
logger.error("Error in PageNameFilter.getPageTitle() " + e.getMessage(),e);
}
return null;
}

private NavigationSelectionModelHome navigationSelectionModelHome;
public void init(FilterConfig filterConfig) throws PortletException {
try {
InitialContext context = new InitialContext();
navigationSelectionModelHome = (NavigationSelectionModelHome) context
.lookup(NavigationSelectionModelHome.JNDI_NAME);
} catch (NamingException e) {
logger.error("Error in PageNameFilter.init() " + e.getMessage(),e);
}
}
public void destroy() {
}
}


The PageNameFilter implements RenderFilter and in the doFilter() method it is passing control to getPageTitle method to get title of the page in the current locale or English. The getPageTitle, method is making use of the NavigationSelectionModel and callings its model.getSelectedNode() to first get the users current page and then reading the contentNode of the page from it.

I had to create PageNameRenderRequestWrapper that will override the actual RenderRequest and pass pageName as request attribute. This is how my PageNameRenderRequestWrapper looks like

package com.webspherenotes.portlet.filter;

import java.util.Enumeration;
import java.util.Vector;

import javax.portlet.RenderRequest;

public class PageNameRenderRequestWrapper extends javax.portlet.filter.RenderRequestWrapper{
private String pageName;
public static final String PAGENAME_ATTRIBUTE ="com.webspherenotes.filter.pageName";

public PageNameRenderRequestWrapper(RenderRequest request) {
super(request);
}

public Object getAttribute(String name) {
if(name.equals(PAGENAME_ATTRIBUTE)){
return pageName;
}
return super.getAttribute(name);
}

public Enumeration getAttributeNames() {
Enumeration originalAttributeEnum = super.getAttributeNames();
Vector wrappedEnum = new Vector();
while(originalAttributeEnum.hasMoreElements()){
wrappedEnum.add(originalAttributeEnum.nextElement());
}
wrappedEnum.add(PAGENAME_ATTRIBUTE);
return wrappedEnum.elements();
}

public String getPageName() {
return pageName;
}

public void setPageName(String pageName) {
this.pageName = pageName;
}



}


Inside the portlet you can read com.webspherenotes.filter.pageName request attribute to get name of the page where portlet is getting rendered

Query String Filter

Before couple of days i built a Getting Query String of portal URL from inside the portlet to demonstrate how you can read query string appended to the portal URL inside your portlet. That solution works by getting access to underlying HttpServletRequest object and reading query string from it. The QueryStringPortlet portlet developed in that blog entry works when accessed locally on the same portal server but it does not work if you consume that portlet on some other server using WSRP.

I built QueryStringFilter that will read the query parameters added to the portal URl and set them as normal render parameter, then i applied to the WSRP Proxy portlet and it works


import javax.servlet.http.HttpServletRequestWrapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class QueryStringFilter implements RenderFilter{
private static final Logger logger = LoggerFactory.getLogger(PageNameFilter.class);
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("Entering QueryStringFilter.doFilter()");
HttpServletRequest httpServletRequest = getHttpServletRequest(request);
System.out.println("Request parameter map " + httpServletRequest.getParameterMap());
QueryStringRenderRequestWrapper queryStringRequestWrapper = new QueryStringRenderRequestWrapper(request,httpServletRequest.getParameterMap());
filterChain.doFilter(queryStringRequestWrapper, response);
logger.debug("Exiting QueryStringFilter.doFilter()");
}
public void destroy() {
}
public void init(FilterConfig filterChain) throws PortletException {
}
private HttpServletRequest getHttpServletRequest(PortletRequest request){
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
while(httpServletRequest instanceof HttpServletRequestWrapper){
HttpServletRequestWrapper httpServletRequestWrapper =
(HttpServletRequestWrapper)httpServletRequest;
httpServletRequest = (HttpServletRequest)httpServletRequestWrapper.getRequest();
}
return httpServletRequest;
}
}


The QueryStringFilter implements RequestFilter and in the doFilter() method i am reading underlying HttpServletRequest object and reading its parameters.

I also built this QueryStringRenderRequestWrapper that takes the query parameter from underlying HttpServletRequest object and forwards them as normal render parameter to the WSRP Proxy portlet


package com.webspherenotes.portlet.filter;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import javax.portlet.RenderRequest;
import javax.portlet.filter.RenderRequestWrapper;

public class QueryStringRenderRequestWrapper extends RenderRequestWrapper{
Map queryParameterMap ;
public QueryStringRenderRequestWrapper(RenderRequest request, Map queryParameterMap) {
super(request);
this.queryParameterMap = queryParameterMap;
}
public String getParameter(String name) {
System.out.println("Getparameter " + name);
String[] value = queryParameterMap.get(name);
System.out.println("Getparameter value " + value);
if(value != null)
return value[0];
return super.getParameter(name);
}
public Map getParameterMap() {
System.out.println();
Map oldParamMap = super.getParameterMap();
Map newParamMap = new HashMap();
Iterator oldParamIt = oldParamMap.keySet().iterator();
while(oldParamIt.hasNext()){
String paramName = oldParamIt.next();
String[] paramValue = super.getParameterValues(paramName);
newParamMap.put(paramName, paramValue);
}
Iterator queryParamIt = queryParameterMap.keySet().iterator();
while(queryParamIt.hasNext()){
String paramName = queryParamIt.next();
String[] paramValue = queryParameterMap.get(paramName);
newParamMap.put(paramName, paramValue);
}
return newParamMap;
}
public Enumeration getParameterNames() {
Enumeration oldParameters = super.getParameterNames();
Vector newParameter = new Vector();
while(oldParameters.hasMoreElements()){
String paramName = oldParameters.nextElement();
newParameter.add(paramName);
}
Iterator queryParamIt = queryParameterMap.keySet().iterator();
while(queryParamIt.hasNext()){
newParameter.add(queryParamIt.next());
}
System.out.println("Get parameterNames " + newParameter);
return newParameter.elements();
}
public String[] getParameterValues(String name) {
System.out.println("getParameterValues " + name);
String[] value = queryParameterMap.get(name);
if(value != null)
return value;
return super.getParameterValues(name);
}
}


The QueryStringRenderRequestWrapper class overrides RenderRequestWrapper and overrides its parameter related methods to inject some additional parameters that it got from the underlying HttpServletRequest

Debug/Log Portlet Filter

One of the nicest way to learn about how the portlet containers work is by looking at what type type of data is stored in PortletRequest and underlying HttpServletRequest, including data stored in PortletSession, HttpSession and PortletPreferences. So i built this DebugPortletFilter that you can copy in your project and apply to your portlet.

This Filter will be helpful even if your working with say a MVC framework like Spring Portlet MVC framework and your not sure about what request parameters or attributes are getting stored


package com.webspherenotes.portlet.filter;

import java.io.IOException;
import java.util.Enumeration;
import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequest;
import javax.portlet.PortletSession;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.filter.FilterChain;
import javax.portlet.filter.FilterConfig;
import javax.portlet.filter.RenderFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DebugPortletFilter implements RenderFilter,ActionFilter,ResourceFilter{
private static final Logger logger = LoggerFactory.getLogger(DebugPortletFilter.class);
public void doFilter(RenderRequest request, RenderResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("****************** Entering render phase *********************");
printPortletRelatedInfo(request);
printHttpServletRequestRelatedInfo(request);
filterChain.doFilter(request, response);
logger.debug("****************** Exiting render phase *********************");
}
public void doFilter(ResourceRequest request, ResourceResponse response,
FilterChain filterChain) throws IOException, PortletException {
logger.debug("****************** Entering resource phase *********************");
printPortletRelatedInfo(request);
printHttpServletRequestRelatedInfo(request);
filterChain.doFilter(request, response);
logger.debug("****************** Exiting resource phase *********************");
}
public void doFilter(ActionRequest request, ActionResponse response
FilterChain filterChain) throws IOException, PortletException {
logger.debug("****************** Entering action phase *********************");
printPortletRelatedInfo(request);
printHttpServletRequestRelatedInfo(request);
filterChain.doFilter(request, response);
logger.debug("****************** Exiting action phase *********************");
}

public void destroy() {
}

public void init(FilterConfig arg0) throws PortletException {
logger.debug("Inside DebugPortletFilter.init()");
}

private void printHttpServletRequestRelatedInfo(PortletRequest portletRequest){
logger.debug(" Information stored at HttpServlet level ");
HttpServletRequest httpServletRequest = getHttpServletRequest(portletRequest);
printHttpServletRequestParameter(httpServletRequest);
printHttpServletRequestAttribute(httpServletRequest);
printHttpSessionAttribute(httpServletRequest);
}
private void printPortletRelatedInfo(PortletRequest portletRequest){
logger.debug(" Information stored at portlet level ");
logger.debug( "Portlet Mode " + portletRequest.getPortletMode());
logger.debug( "Window State " + portletRequest.getWindowState());
logger.debug( "Window ID " + portletRequest.getWindowID());
printPortletRequestParameter(portletRequest);
printPortletRequestAttribute(portletRequest);
printPortletPreferences(portletRequest);
printPortletSessionInfo(portletRequest);
}
private void printPortletRequestParameter(PortletRequest portletRequest){
logger.debug(" Printing Portlet Parameters ");
Enumeration paramEnum = portletRequest.getParameterNames();
while(paramEnum.hasMoreElements()){
String paramName = paramEnum.nextElement();
String paramValue = portletRequest.getParameter(paramName);
logger.debug(paramName + " -> " + paramValue);
}
}
private void printPortletRequestAttribute(PortletRequest portletRequest){
logger.debug(" Printing Portlet Attributes ");
Enumeration attributeEnum = portletRequest.getAttributeNames();
while(attributeEnum.hasMoreElements()){
String attrName = attributeEnum.nextElement();
Object attrValue = portletRequest.getAttribute(attrName);
logger.debug(attrName + " -> " + attrValue );
}
}
private void printPortletPreferences(PortletRequest portletRequest){
logger.debug(" Printing PortletPreferences ");
PortletPreferences pref = portletRequest.getPreferences();
Enumeration prefEnum = pref.getNames();
while(prefEnum.hasMoreElements()){
String prefName = prefEnum.nextElement();
String prefValue = pref.getValue(prefName, "");
logger.debug(prefName +" -> " + prefValue);
}
}
private void printPortletSessionInfo(PortletRequest portletRequest){
logger.debug(" Printing PortletSession attributes ");
PortletSession session = portletRequest.getPortletSession();
Enumeration attribEnum = session.getAttributeNames();
while(attribEnum.hasMoreElements()){
String attrName = attribEnum.nextElement();
Object attrValue = session.getAttribute(attrName);
}
}
private HttpServletRequest getHttpServletRequest(PortletRequest request){
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
while(httpServletRequest instanceof HttpServletRequestWrapper){
HttpServletRequestWrapper httpServletRequestWrapper =
(HttpServletRequestWrapper)httpServletRequest;
httpServletRequest = (HttpServletRequest)httpServletRequestWrapper.getRequest();
}
return httpServletRequest;
}
private void printHttpServletRequestParameter(HttpServletRequest httpServletRequest){
logger.debug(" Printing HttpServletRequest parameter ");
Enumeration paramEnum = httpServletRequest.getParameterNames();
while(paramEnum.hasMoreElements()){
String paramName = paramEnum.nextElement();
String paramValue = httpServletRequest.getParameter(paramName);
logger.debug(paramName +" -> " + paramValue);
}
}
private void printHttpServletRequestAttribute(HttpServletRequest httpServletRequest){
logger.debug(" Printing HttpServletRequest attributes ");
Enumeration attrEnum = httpServletRequest.getAttributeNames();
while(attrEnum.hasMoreElements()){
String attrName = attrEnum.nextElement();
Object attrValue = httpServletRequest.getAttribute(attrName);
logger.debug(attrName + " -> " + attrValue);
}
}
private void printHttpSessionAttribute(HttpServletRequest httpServletRequest){
logger.debug(" Printing HttpSession attributes ");
HttpSession httpSession = httpServletRequest.getSession();
Enumeration attrEnum = httpSession.getAttributeNames();
while(attrEnum.hasMoreElements()){
String attrName = attrEnum.nextElement();
Object attrValue = httpSession.getAttribute(attrName);
logger.debug(attrName + " -> " + attrValue);
}
}
}


The DebugPortletFilter is implementing only RenderFilter, ActionFilter and ResourceFilter in all three methods it first prints all the portlet related information first and then it finds out the underlying HttpServletRequest object and prints the information related to it

You can apply the filter to your portlet by adding a filter declaration and mapping in your portlet.xml like this

<filter>
<filter-name>DebugPortletFilter</filter-name>
<filter-class>com.webspherenotes.portlet.filter.DebugPortletFilter</filter-class>
<lifecycle>RENDER_PHASE</lifecycle>
</filter>
<filter-mapping>
<filter-name>DebugPortletFilter</filter-name>
<portlet-name>DemoPortlet</portlet-name>
</filter-mapping>


Important Note Please be aware that the DebugPortletFilter generates huge amount of log information so use it only during development