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