Liferay is a Gartner Magic Quadrant Leader for the Sixth Year! Find out why

Struts Action Hook Tips

Link to the official documentation about Struts Action Hook: Overriding and adding Struts actions

STRUTS ACTION HOOK

To extend the CreateAccountAction ,  there are different types of hook to achieve  . Here we are going to discuss about Struts Action Hook.
 
Steps 1 : Add the struts action path and your custom implementation file in liferay-hook.xml :
 
<struts-action>
<struts-action-path>/login/create_account</struts-action-path> 
<struts-action-impl>com.liferay.login.hook.action.CustomCreateAccountAction</struts-action-impl>
</struts-action>
 
Step 2: Create custom implemetation file [CustomCreateAccountAction] in above mentioned location . [com.liferay.login.hook.action]
 
public class CustomCreateAccountAction extends BaseStrutsPortletAction{
 
public CustomCreateAccountAction() {
// TODO Auto-generated constructor stub
}
 
@Override
public void processAction(StrutsPortletAction originalStrutsPortletAction,
PortletConfig portletConfig, ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {
// TODO Auto-generated method stub
System.out.println("inside the process actionwhile creating the account>>>");
super.processAction(originalStrutsPortletAction, portletConfig, actionRequest,
actionResponse);
}
 
@Override
public String render(StrutsPortletAction originalStrutsPortletAction,PortletConfig portletConfig,
RenderRequest renderRequest, RenderResponse renderResponse)
throws Exception {
// TODO Auto-generated method stub
System.out.println("inside the render action while creating the account>>>");
return super.render(portletConfig, renderRequest, renderResponse);
}
}
 
 
Step 3: deploy.
 
Done. But sometime you might confuse when we need to extend BaseStrutsPortletAction and BaseStrutsAction.
 
Struts action interfaces:
 
com.liferay.portal.kernel.struts.StrutsAction
com.liferay.portal.kernel.struts.StrutsPortletAction
 
The StrutsAction interface is for regular Struts actions, like /c/portal/update_email_address, from the portal
The StrutsPortletAction interface is used for similar Struts actions from portlets.
 
Note: If you use BaseStrutsAction, you should override "execute" method:
 
public class SampleStrutsAction extends BaseStrutsAction {  
@Override 
public String execute(StrutsAction originalStrutsAction, HttpServletRequest request, HttpServletResponse response) throws Exception {  
System.out.println("SampleLayoutStrutsAction.execute() - " + request.getRequestURI());  
return originalStrutsAction.execute(request, response); 
}  
}
 
 

Exceptions :

 

1. "Cannot be Cast" Exception

Some time if you get an exception like "ActionAdapter cannot be cast to PortletActionAdapter" or "PortletActionAdapter cannot be cast to ActionAdapter"
 
To resolve that:
 
) ActionAdapter cannot be cast to PortletActionAdapter :
 
    you have implemneted BaseStrutsAction instead of BaseStrutsPortletAction
 
2) PortletActionAdapter cannot be cast to ActionAdapter :
 
    you have implemneted BaseStrutsPortletAction instead of BaseStrutsAction
 

2.  "Forward Does not exist" Exception

If you get an exception like this , then In render method of custom implementation file [CustomCreateAccountAction ] before return statement, 

we need to change that behavier by setting renderRequest.setAttribute(WebKeys.PORTLET_DECORATE, Boolean.TRUE); 
 
use this :
 
String ret = originalStrutsPortletAction.render(null, portletConfig, renderRequest, renderResponse);
 renderRequest.setAttribute(WebKeys.PORTLET_DECORATE, Boolean.TRUE);
 return ret;
 
 
instead of ,
 
return originalStrutsPortletAction.render(null, portletConfig, renderRequest, renderResponse);
 

3.  If It doesn't redirect to Original Path

After successfully implementing struts action hook, If it doesn't redirect to it's original path, you need to use originalStrutsPortletAction in processAction method.
 
 For example after creating the user , if it stays in same create account page instead of login page which is default behaviour, then use like this :
 
originalStrutsPortletAction.processAction(portletConfig, actionRequest, actionResponse);
 
instead of,
 
super.processAction(originalStrutsPortletAction, portletConfig, actionRequest,actionResponse);
 
if any queries , please contact gnaniyar@gmail.com 
 
- Gnaniyar Zubair
gnaniyar@gmail.com
0 Attachments
28699 Views
Average (1 Vote)
The average rating is 5.0 stars out of 5.
Comments
Threaded Replies Author Date
Hi guys, I need to do exactly this, and I was... S . March 18, 2013 8:41 AM
thanku for good information Babu Reddy K V June 18, 2013 12:06 AM
Hi, really helpful. But I am trying to do a... Sandra del Moral Lazo October 4, 2013 7:09 AM

Hi guys,

I need to do exactly this, and I was so happy when I found the article. I get a message "Forward does not exist", but for me is not clear exactly where (in which file) I have to make the described changes .

Thanks for your help!
Posted on 3/18/13 8:41 AM.
thanku for good information
Posted on 6/18/13 12:06 AM.
Hi, really helpful.
But I am trying to do a strut for the search. I saw that in the url appears: 'struts_action=/search/search' then I supose that the path is '/search/seach'. But it doesn't work. I follow all the steps. And this is the code of liferay-hook and portal.properties, the other files are like in your article.

liferat-hook.xml
<hook>
<portal-properties>portal.properties</portal-properties>
<struts-action>
­ <struts-action-path>/search/search</struts-action-path>
<struts-action-impl>c­om.segmentationProject.searchAction.struts.SearchAction</struts-action-impl>
</struts-action>
</hook>

portal.properties:
auth.public.paths=/search/search
Any idea?

Thanks
Posted on 10/4/13 7:09 AM.