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/loginpath so we need to configure the path in liferay-portlet.xmlfile.
<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/homeis 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
0 comments:
Post a Comment