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.
- parameterMappingInterceptor. The
parameterMappingInterceptor
is used to forward the value of the action request parameter fromActionRequest
toRenderRequest
, 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 inhandleActionRequest
as render parameter - portletModeParameterHandlerMapping.
portletModeParameterHandlerMapping
is an advanced implementation ofHandlerMapping
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 useportletModeParameterHandlerMapping
. TheportletModeParameterHandlerMapping
bean has theportletModeParameterMap
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
Just what i was looking for!
ReplyDeleteExcelent post
Please how this could determine, that the parameter action was used. I dont see it here. Thanx
ReplyDeleteThanks for info....
ReplyDeleteSEO Company in Bangalore