Generally request parameter values are immutable once
the request process is started. Some time we may get some requirement that force
you to add or modify the request parameter values. Assume scenario once we
submit the form to the controller we would like to modify or add the parameter
values before it reach the controller.
Http
Servlet Request Wrapper is the way to modify the request
parameter values. We will use Http
Servlet Request Wrapper with servlet filter combination so that we can
modify or add new parameter values.
Example
Scenario
Assume the example scenario that when user login into
the Liferay portal before it reach struts controller we would like to change
the redirect parameter value.
Note:
This just scenario I chosen to explain the concept.
We will use Http
Servlet Request Wrapper with servlet filter combination to achieve this concept.
In Liferay we will use Hook plugin to implement the concept.
In Liferay login mechanism when user submit the user
name and password then it will submitted to /login/login struts controller path. Before it reach struts
controller (LoginAction.java) we would
like to change the redirect parameter value in the filter using Http Servlet Request Wrapper concept.
Steps
to Implementation
- Create Liferay Hook
- Create Custom Http Servlet Request Wrapper
- Create Servlet Filter Class and modify the request parameter values
- Configure Servlet Filter in liferay-hook.xml
- Configure Struts path in liferay-hook.xml
- Create Struts Action Hook for Login Action and observe the modified parameter value
Create
Liferay Hook
Creating hook using Liferay IDE is very straight
forward way and its easy. Follow below articles to create Liferay hook plugin.
Create
Custom Http Servlet Request Wrapper
We need to create custom Http Servlet Request Wrapper and the following is custom Http Servlet Request Wrapper. This
class is responsible for modify or add request parameters.
| 
package
  com.liferaysavvy.requestwrapper; 
import
  java.util.Collections; 
import
  java.util.Enumeration; 
import
  java.util.Map; 
import
  java.util.TreeMap; 
import javax.servlet.http.HttpServletRequest; 
import
  javax.servlet.http.HttpServletRequestWrapper; 
public class
  AddModifyRequestParamValueWrappedRequest extends
  HttpServletRequestWrapper 
{ 
private final
  Map<String, String[]> modifiableParameters; 
private
  Map<String, String[]> allParameters = null; 
/** 
*
  Create a new request wrapper that will merge additional parameters into 
*
  the request object without prematurely reading parameters from the 
*
  original request. 
* 
* @param
  request 
* @param
  additionalParams 
*/ 
public
  AddModifyRequestParamValueWrappedRequest(final
  HttpServletRequest request, 
final
  Map<String, String[]> additionalParams) 
{ 
super(request); 
modifiableParameters = new
  TreeMap<String, String[]>(); 
modifiableParameters.putAll(additionalParams); 
} 
@Override 
public
  String getParameter(final String name) 
{ 
String[]
  strings = getParameterMap().get(name); 
if (strings != null) 
{ 
return strings[0]; 
} 
return super.getParameter(name); 
} 
@Override 
public
  Map<String, String[]> getParameterMap() 
{ 
if (allParameters == null) 
{ 
allParameters = new
  TreeMap<String, String[]>(); 
allParameters.putAll(super.getParameterMap()); 
allParameters.putAll(modifiableParameters); 
} 
//Return
  an unmodifiable collection because we need to uphold the interface contract. 
return
  Collections.unmodifiableMap(allParameters); 
} 
@Override 
public
  Enumeration<String> getParameterNames() 
{ 
return
  Collections.enumeration(getParameterMap().keySet()); 
} 
@Override 
public
  String[] getParameterValues(final
  String name) 
{ 
return
  getParameterMap().get(name); 
} 
} | 
Create
Servlet Filter Class and modify the request parameters
Now we will implement servlet filter and we will Custom Servlet Request Wrapper to
modify parameter values or we can also add new parameters. Once request parameters are modifies then we will give this
object to doFilter(--) method to do subsequent process.
| 
package
  com.liferaysavvy.requestwrapper; 
import
  java.io.IOException; 
import
  java.util.Map; 
import
  java.util.TreeMap; 
import
  javax.servlet.Filter; 
import
  javax.servlet.FilterChain; 
import
  javax.servlet.FilterConfig; 
import
  javax.servlet.ServletException; 
import
  javax.servlet.ServletRequest; 
import
  javax.servlet.ServletResponse; 
import
  javax.servlet.http.HttpServletRequest; 
import
  com.liferay.portal.kernel.log.Log; 
import
  com.liferay.portal.kernel.log.LogFactoryUtil; 
import
  com.liferay.portal.kernel.util.ParamUtil; 
public class
  ChangeRequestParamFilter implements
  Filter { 
@Override 
public void
  destroy() { 
logger.info("ChangeRequestParamFilter"); 
} 
@Override 
public void
  doFilter(ServletRequest servletRequest, 
ServletResponse
  servletResponse, FilterChain filterChain) 
throws
  IOException, ServletException { 
logger.info("inside
  ChangeRequestParamFilter doFilter "); 
HttpServletRequest
  httpServletRequest = (HttpServletRequest) servletRequest; 
/*Getting
  actual Redirect Param Value*/ 
String
  actuallRedirectValue = ParamUtil.getString(httpServletRequest,"redirect"); 
logger.info("Actual
  Redirect Param Value:" + actuallRedirectValue); 
/*
  Modifying redirect param value and also adding new parameter to
  request object*/ 
Map<String,
  String[]> modifyAddParamValueMap = new
  TreeMap<String, String[]>(); 
String[]
  redirectParamArray = new
  String[1]; 
redirectParamArray[0]
  = "http://localhost:8080/web/guest/custom-portlet-workflow"; 
modifyAddParamValueMap.put("redirect", redirectParamArray); 
modifyAddParamValueMap.put("newParam",new
  String[]{"Hello I am New Param value"}); 
HttpServletRequest
  wrappedRequest = new
  AddModifyRequestParamValueWrappedRequest( 
httpServletRequest, modifyAddParamValueMap); 
filterChain.doFilter(wrappedRequest, servletResponse); 
} 
@Override 
public void
  init(FilterConfig filterConfig) { 
logger.debug("Called
  ChangeRequestParamFilter init(" + filterConfig + ")"); 
} 
private static final Log
  logger = LogFactoryUtil 
.getLog(ChangeRequestParamFilter.class); 
} | 
Configure
Servlet Filter in liferay-hook.xml
Use following configuration in liferay-hook.xml file 
| 
<servlet-filter> 
<servlet-filter-name>ChangeRequestParamFilter</servlet-filter-name> 
<servlet-filter-impl>com.liferaysavvy.requestwrapper.ChangeRequestParamFilter</servlet-filter-impl> 
<init-param> 
<param-name>hello</param-name> 
<param-value>world</param-value> 
</init-param> 
</servlet-filter> 
<servlet-filter-mapping> 
<servlet-filter-name>ChangeRequestParamFilter</servlet-filter-name> 
<url-pattern>/web/guest/home/*</url-pattern> 
<dispatcher>REQUEST</dispatcher> 
<dispatcher>FORWARD</dispatcher> 
</servlet-filter-mapping> | 
Note:
From the above configuration Filter will be execute
when we request server with /web/guest/home/*
path.
Configure
Struts path in liferay-hook.xml
We are going to see resulted values in Custom Login
Action struts action for /login/login
path so we need to configure the path in liferay-portlet.xml
file.
| 
<struts-action> 
<struts-action-path>/login/login</struts-action-path> 
<struts-action-impl>com.liferaysavvy.requestwrapper.CustomLoginStrutsPortletAction</struts-action-impl> 
</struts-action> | 
Create
Struts Action Hook for Login Action and observe the modified parameter value
Finally we will see the modified or newly added parameter
values in Custom Login Action Struts action class.
| 
package
  com.liferaysavvy.requestwrapper; 
import
  javax.portlet.ActionRequest; 
import
  javax.portlet.ActionResponse; 
import
  javax.portlet.PortletConfig; 
import
  javax.portlet.RenderRequest; 
import
  javax.portlet.RenderResponse; 
import
  javax.portlet.ResourceRequest; 
import
  javax.portlet.ResourceResponse; 
import
  javax.servlet.ServletRequest; 
import javax.servlet.http.HttpServletRequest; 
import
  com.liferay.portal.kernel.log.Log; 
import
  com.liferay.portal.kernel.log.LogFactoryUtil; 
import
  com.liferay.portal.kernel.struts.BaseStrutsPortletAction; 
import
  com.liferay.portal.kernel.struts.StrutsPortletAction; 
import com.liferay.portal.kernel.util.ParamUtil; 
import
  com.liferay.portal.util.PortalUtil; 
public class
  CustomLoginStrutsPortletAction extends
  BaseStrutsPortletAction { 
@Override 
public void
  processAction(StrutsPortletAction originalStrutsPortletAction, 
PortletConfig
  portletConfig, ActionRequest actionRequest, 
ActionResponse
  actionResponse) throws
  Exception { 
ServletRequest
  servletRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(actionRequest)); 
String
  modifiedRedirectValue = servletRequest.getParameter("redirect"); 
String
  newParamValue = servletRequest.getParameter("newParam"); 
logger.info("Modified
  Redirect Value:"+modifiedRedirectValue); 
logger.info("Nee
  Parameter Value:"+newParamValue); 
originalStrutsPortletAction.processAction(portletConfig, actionRequest, 
actionResponse); 
} 
@Override 
public
  String render(StrutsPortletAction originalStrutsPortletAction, 
PortletConfig
  portletConfig, RenderRequest renderRequest, 
RenderResponse
  renderResponse) throws
  Exception { 
return originalStrutsPortletAction.render(portletConfig, renderRequest, 
renderResponse); 
} 
@Override 
public void
  serveResource(StrutsPortletAction originalStrutsPortletAction, 
PortletConfig
  portletConfig, ResourceRequest resourceRequest, 
ResourceResponse
  resourceResponse) throws
  Exception { 
originalStrutsPortletAction.serveResource(portletConfig, 
resourceRequest, resourceResponse); 
} 
private static Log
  logger = LogFactoryUtil 
.getLog(CustomLoginStrutsPortletAction.class); 
} | 
Observation
Deploy hook into Liferay portal server
Drag and Drop Liferay sign in portlet in home page 
Site page URL should be as follows http://localhost:8080/web/guest/home
The
following screen shows home page with sign in portlet
I have used /web/guest/home
is filter path that is why Sign In portlet should be placed into home page so
that filter will be executed when you login into portal.
Once you have done sign in process in Liferay portal then
filter gets called and we can see redirect
param value is empty later Custom Login Action will be executed there you
can see redirect value that is modified in the filter. These are all will be
printed in the server console.
This how we can observed modified parameter values in
Login Action class.
Server
Console
| 
20:52:30,377
  INFO  [http-bio-8080-exec-159][ChangeRequestParamFilter:31] inside ChangeRequestParamFilter doFilter  
20:52:30,378
  INFO  [http-bio-8080-exec-159][ChangeRequestParamFilter:36] Actual Redirect Param Value: 
20:52:30,396
  INFO  [http-bio-8080-exec-159][CustomLoginStrutsPortletAction:29] Modified Redirect Value: http://localhost:8080/web/guest/custom-portlet-workflow 
20:52:30,396 INFO 
  [http-bio-8080-exec-159][CustomLoginStrutsPortletAction:30]
  New Parameter Value: Hello I am New Param value | 
Server Console
Note:
I just showed this example to understand how to modify
or add new parameters in request object. This may or may not be the real time
scenario but we can understand the concept from the example.
Get
Source code from following locations
Author
 

 
 
 Posts
Posts
 
 
