Liferay Struts Action Hook is another type of hook that can be used to override existing struts action and also we can add our own struts action. To follow this article you should know the basics of struts actions. Struts actions are defined as classes and they’re all connected in a struts-config.xml
file.In liferay source code the path of this file is /portal-web/docroot/WEB-INF/struts-config.xml. Before starting this tutorial you can have look to this file.
Override Existing Struts Action by Struts Action Hook
Whenever we login com.liferay.portlet.login.action.LoginAction is the action class generally we invoke. We are going to change it by Struts Action Hook. Follow the steps
1. Create Liferay Plugin Project of type Hook.
2. Modify liferay-hook.xml
<?xml version="1.0"?> <!DOCTYPE hook PUBLIC "-//Liferay//DTD Hook 6.2.0//EN" "http://www.liferay.com/dtd/liferay-hook_6_2_0.dtd"> <hook> Â Â Â <struts-action> Â Â Â Â Â Â Â <struts-action-path>/login/login</struts-action-path> Â Â Â Â Â Â Â <struts-action-impl>com.proliferay.demo.ExampleLoginAction</struts-action-impl> Â Â Â </struts-action> </hook>
3. ExampleLoginAction.java
package com.proliferay.demo; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.PortletConfig; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import com.liferay.portal.kernel.struts.BaseStrutsPortletAction; import com.liferay.portal.kernel.struts.StrutsPortletAction; /**  *  * @author Hamidul Islam  *  */ public class ExampleLoginAction extends BaseStrutsPortletAction{    @Override    public void processAction(StrutsPortletAction originalStrutsPortletAction,          PortletConfig portletConfig, ActionRequest actionRequest,          ActionResponse actionResponse) throws Exception {       /**       * This is the custom process action       * Once you try to login this method will be invoked       * We can write our own logic here       * Invoke the original struts action at the end       */             System.out.println("#############ExampleLoginAction###############");             originalStrutsPortletAction.processAction(               originalStrutsPortletAction, portletConfig, actionRequest,               actionResponse);    }    public String render(            StrutsPortletAction originalStrutsPortletAction,            PortletConfig portletConfig, RenderRequest renderRequest,            RenderResponse renderResponse)        throws Exception {             /**       * Our own render method       * This method is for rendering the view       * At the end call the original struts action       */             System.out.println("##########Rendering view############");        return originalStrutsPortletAction.render(            null, portletConfig, renderRequest, renderResponse);    } }
Note: Read the comments of the code
4. Deploy the Hook. Try to login. Check whether this action class is invoking or not.
Best Practice: While overriding existing struts action by Struts Action Hook override the method that takes the original Struts action as a parameter and execute that original Struts action.
Add Struts Action by Struts Action Hook
The way we overridden existing struts action we can also add new struts action. The process is same as above.In the above demonstration we have seen action associated with portlet. In this section we will demonstrate how to add struts action in portal level.
1. Add below in liferay-hook.xml
 <struts-action>        <struts-action-path>/portal/proliferay</struts-action-path>        <struts-action-impl>com.proliferay.demo.AddedAction</struts-action-impl>  </struts-action>
Note: Portal level struts action are invoked by adding /c/...in the path. For example if we invoke http://localhost:8080/c/portal/proliferay in the browser address bar then method of AddedAction class will be invoked.
2. AddedAction.java
package com.proliferay.demo; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.liferay.portal.kernel.struts.BaseStrutsAction; /**  *  * @author Hamidul Islam  *  */ public class AddedAction extends BaseStrutsAction {    public String execute(HttpServletRequest request,          HttpServletResponse response) throws Exception {             return "/portal/proliferay.jsp";    } }
Note 1: AddedAction class extends BaseStrutsAction but not BaseStrutsPortletAction. This is the way to add action class in portal level.
Note 2: The action class return proliferay.jsp under portal. So there should be proliferay.jsp in the portal directory. We can add this jsp by JSP Hook. Download the source code and check it.
Note 3: If you try access http://localhost:8080/c/portal/proliferay it will prompt for login. We can make this URL public by adding auth.public.paths=/portal/proliferay in portal.properties of the hook. Download the source code and check it.
3. Deploy the Hook and access http://localhost:8080/c/portal/proliferay. It should display proliferay.jsp
Remember!!!
1. While overriding existing portlet action our custom class should extends BaseStrutsPortletAction
2. While adding new struts action in portal level our custom class should extends BaseStrutsAction
Hi Hamidul,
Could you please help me for the following situation.
I have hook which overrides the login portlet.
Now whenever i redirect to a custom JSP like /html/portlet/login/success.jsp.
It redirects properly to the mentioned JSP page.It redirects to the link like localhost:8080/html/portlet/login/success.jsp
But i want this JSP to be rendered within the Login Portlet like localhost:8080/LoginPortletPath/success.jsp.
Which should be rendered inside the portlet.not the whole page.
Could you please help.
Regards
Shasradeep Nadar
Good job hamidul.
In your diagram spelling of Struts is wrong
Overriding Existing Strusts Action
Hi
Thanks for your articles, they are nice explained I like them a lot =) .
Nice article… thank you.
P.S. I think you forget to annotate with @Override the render method of ExampleLoginAction.
Hi,
when I add an action class and reference it in liferay-hook.xml, I have an error cannot be cast to org.apache.struts.action.Action.
Thanks
Nabil