Portlet Action method invocation in Liferay

Portlet action method executes action phase of portlet. It’s not required to override any method to define action method in portlet. Portlet action method is called by its super class (LiferayPortlet) through reflection.

actionURL(in JSP) is used to call portlet action method. You can define multiple action methods in portlet. One actionURL can point only one portlet action method. To call different portlet action methods, separate actionURL needs to be created.  In short, there will be one to one mapping between actionURL(in JSP) and portlet action method.

In my previous blog, we saw how portlet action method can be defined and how it’s called. In this article, you will learn how portlet action method is invoked internally.

First you need to create liferay MVC Portlet. I gave portlet name as TestActionMethodPortlet under com.opensource.techblog.portlet package. I have defined one portlet action method as per below code snippet.

Explanation

  • This is our portlet action method. It takes actionRequest and actionResponse as parameter.
  • ProcessAction annotation is used to map this portlet action method to action URL (Created in JSP).
  • It’s not necessary to define this annotation. But then in that case you need to give action method name same as name attribute of actionURL in JSP.

Add following code in view.jsp

Explanation

  • I have create actionURL by portlet:actionURL tag. name attribute of this tag is same as name attribute of @ProcessAction annotation of portlet action method. So this actionURL is used to calls portlet action method (sampleActionMethod).
  • I have set actionURL to form’s action attribute so on submitting this html form, it will call portlet action method – sampleActionMethod.

To define the portlet action method, I haven’t override any method from parent class. Then how and when it’s called ? Before answering the question, let’s see the portlet class hierarchy

Portlet Action method in Liferay - Portlet Class Hierarchy

 

Explanation

  • Our custom portlet (TestActionMethodPortlet) extends MVCPortlet.
  • MVCPortlet extends LiferayPortlet which extends GenericPortlet.
  • GenericPortlet implements Portlet interface. GenericPortlet and Portlet interface are included in default implementation(portlet.jar file). Rest all classes are provided by liferay.

Portlet action method invocation

When actionURL is called, the invocation of portlet action method will be as per below diagram.

calling of action method - Portlet action method invocation

 

Explanation

  • MVCPorltet is parent class of our custom portlet class (TestActionMethodPortlet) and LiferayPortlet is parent class of MVCPortlet. Both these classes (MVCPorltet and LiferayPortlet) are provided by Liferay.
  • You need to configure Liferay source into Eclipse to get source of above classes.

Step: 1

  • When actionURL is clicked, Liferay will call processAction() method of MVCPortlet which internally call processAction method of its super class(LiferayPortlet)

Step: 2

  • processAction internally calls callActionMethod of same(LiferayPortlet) class.
  • Following is few lines of code of callActionMethod.

Explanation 

  • First, it reads the value of request parameter (ActionRequest.ACTION_NAME = ‘javax.portlet.action’) in actionName local variable.
  • Value of this request parameter is equal to the name attribute of action URL tag that you have defined in view.jsp.
  • In try block it uses this value (as string) to calls the action method (that you have defined in your custom portlet) by java reflection.
  • Now you understand that why it’s required to
    • either keep action method name same as name attribute of action URL in JSP or
    • keep name attribute of @processAction annocation same as name attribute of action URL in JSP (In case if you have defined action method with annotation).
  • If you observe the actionURL generated by portlet:actionURL tag in JSP, it looks like below snippet.

 Observation

  • You can observe that the value of javax.portlet.action is equals to “actionMethod1” (the name attribute of actionURL.( _testactionmethod_WAR_testactionmethodportlet_  (which is portletId) is appended before javax.portlet.action)
  • value of this parameter will be considered as portlet action method and it’s called through reflection in callActionMethod of LiferayPortlet.
  • That is the reason, you need to either
    • keep the action method name same as name attribute of action URL (by portlet:actionURL tag)
    • or give name attribute of @ProcessAction annotation same as name attribute of action URL (by portlet:actionURL tag).

 Note:- in case if no matching action method is found, then it will throw following exception.

 

Summing UP

  • Portlet action method executes action phase of portlet.
  • You no need to override any method to define portlet action method.
  • When actionURL is clicked, MVCPortlet’s processAction method will be called. This method will call processAction method of LiferayPortelt.
  • processAction method internally calls callActionMethod of same class (LiferayPortlet).
  • Our custom portlet action method is called through java reflection in callActionMethod of LiferayPortelt.
  • You may refer this link to know about portlet action phase

I would recommend looking at index page ‘A Complete Liferay Guide‘ to browse all topics about liferay.

Share This Post

Post Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.