Render and Action methods in Spring MVC portlet in Liferay

Spring MVC Portlet in Liferay provides a facility to define multiple render and action methods. Liferay MVC portlet however allows one render method and multiple action methods.

In this article, we will see how to write multiple render and action methods in the Spring MVC portlet created in Liferay. This article is an addendum to my previous blog Spring MVC Portlet in Liferay So Please refer to it to understand how to create a Spring MVC portlet.

Define multiple render and action methods


In the last blog
(Spring MVC Portlet in Liferay) we have created the default render method. We will continue the same example in that blog and will see the following things.

  • Create Render method with “action” as key
  • call Action method with “action” as key with Default Render method
  • call Action method with “action” as key with Specific Render method

Create Render method with “action” as key

We have seen how to create a default render method which will be called on page refresh. In some situation, the logic in render method become complex and needs to be divided in multiple small methods.

One of the solutions is that we can define an independent chunk of code in a separate method and call it in the default render() method. The issue in this approach is we will end up defining multiple if-else conditions and have to set different flag values.

Spring MVC Portlet address this issue effectively by allowing us to define multiple render and action methods. This helps us to divide render logic into multiple methods. Each render method can be called with render URL by passing different action KEY.

Let us do it practically.
 
Add following code in MyFirstSpringMVCTestController  class
@RenderMapping(params = "action=renderOne")
public String renderOneMethod(RenderRequest request, RenderResponse response, Model model){
  return "render1";
 }

Explanation:-

  • This method having @RenderMapping annotation with params attribute. 
  • The value of params  is action=renderOne. It means this render method will be called when we create RenderURL from JSP and pass action parameter with value renderOne
  • In another word, the key of this render method(value of action) should be matched with the value of action request parameter that we pass in renderURL
  • This method return string “render1″. It means it will render “render1.jsp“. This is a similar concept that we have seen for the default Render method in a previous blog (the returning string represents the JSP name).
  • Method name can be anything you want.
Create JSP file called render1.jsp at the same path (WEB-INF/jsp)where we have created defaultRender.jsp and add the following code.
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:renderURL var="renderOneMethodURL">
	<portlet:param name="action" value="renderOne"/>
</portlet:renderURL>

<h1>This is Default Render Jsp</h1>
<a href="${renderOneMethodURL}">Call RenderOne method</a>
 Explanation:-
  • First, we have added portlet taglib reference which used to create render URL.
  • Next, I have created renderURL with the help of <portlet:renderURL> tag. We have given var name so that it can be referred anywhere on the page with JSTL. We also passed a portlet parameter called action and its value is “renderOne”
  • Then I have added a header – This is Default Render Jsp.
  • If you notice, I kept the same value of action parameter in render URL with the value of action key for renderOneMethod method in the annotation. It means this renderURL will call the render method (in spring controller) having action key matching with action parameter value in render URL.
Now it’s time to see our work. Build and deploy the portlet. We already place the portlet on the Liferay page. So just refresh it to see the changes. You can notice that the defaultRender jsp gets render and generate output as per the below screenshot.
Multiple render and action methods in Spring MVC portlet - default-render-method

Now click on link Call RenderOne method and you will notice that the rende1.jsp get displayed as per the below screenshot.
Multiple render and action methods in Spring MVC portlet - render1-method
If you want, you can put a logger at each method to see the flow of execution.

Call Action method with “action” as key with Default Render method

We can create the Action method in a similar way we have created the above Render method. Add the code in defaultRender.jsp so that it will look like the below snippet.

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:renderURL var="renderOneMethodURL">
	<portlet:param name="action" value="renderOne"/>
</portlet:renderURL>

<portlet:actionURL var="actionOneMethodURL">
	<portlet:param name="action" value="actionOne"/>
</portlet:actionURL>

<h1>This is Default Render Jsp</h1>
<a href="${renderOneMethodURL}">Call RenderOne method</a>
<form action="${actionOneMethodURL}" method="post">User Name: <input name="userName" type="text" />
<input type="submit" /></form><span style="font-family: inherit;">

Explanation:-

  • We have now created actionURL with the help of portlet:actionURL tag. I set var = actionOneMethodURL. This means it can be refer by ${actionOneMethodURL} anywhere in jsp.
  • We also have passed action parameter with value “actionOne”
  • We will create the action method in the controller class with action key and set its value as “actionOne” so that it can be called when this actionURL is clicked from JSP.
  • In the end, we had created an HTML form with one input text and submit button. The action of the form will be actionURL created by <portlet:action> tag.
  • Here the concept will be the same as renderURL. When we hit the submit button, the respective action method will be called whose action key value is matched with the action parameter value in  <portlet:action> tag.
Next, we will create an action method as per the below snippet in the controller class.
@ActionMapping(params = "action=actionOne") 
 public void actionOneMethod(ActionRequest request, ActionResponse response) {
  String userName=ParamUtil.get(request, "userName", "");
  log.info("userName is==>"+userName);
 }

Explanation:-

  • We have created an action method with annotation @ActionMapping and its param attribute is “action=actionOne”. It means this action method has key action and its value is actionOne
  • So this method will be called by actionURL who’s action parameter value is “actionOne”.
  • Method name can be anything you want.
  • In this method, I am accessing request parameters through the Liferay utility class(ParamUtil).
  • At the last, I am printing the request parameter through a logger. You can create a logger in Liferay by creating a class level static variable with the help of the Liferay utility class LogFactoryUtil as shown below snippet.
private static Log log = LogFactoryUtil.getLog(MyFirstSpringMVCTestController.class);
  • We have to pass class reference in which we are defining logger in getLog method
  • You can notice that we not returning anything. I mean the return type of this method is void.
  • So you may wonder after this method gets executed what is the output. And the answer is it will execute the default Render method.
Now it’s time to see this in action. Deploy the portlet and you will see the portlet get rendered as per the below screenshot.
Multiple render and action methods in Spring MVC portlet - action-method-1
Give any value in the text box, say Nilang, and click on Submit button. You will notice that the same JSP (defaultRender.jsp) will be displayed. You can check the logs and confirm that control goes to the action method and execute the logs and then execute the default render method. Below is the snapshot of logs.
Multiple render and action methods in Spring MVC portlet - log
 
You can put a log in the default render method to understand it more clear.

Call Action method with “action” as key with Specific Render method

As per portlet specification, the render method will be called soon after the action method completes its execution. In the case of Spring MVC Portlet, the default render method will be called after completion of the action method. This is the default behavior.
Spring MVC portlet framework provides a way to execute a specific render method instead of default render after completion of the action method.
 
Let’s see how to achieve this. Create one render method as per the below snippet.
@RenderMapping(params = "action=renderAfterAction") 
 public String testRenderMethod(RenderRequest request, RenderResponse response){
  log.info("In renderAfterAction method");
  return "renderAfterAction";
 }

Explanation:-

  • we created a new render method with its key action set to renderAfterAction. Also we are returning “renderAfterAction“. Means it will search for renderAfterAction.jsp file under /WEB-INF/jsp folder.
  • After completion of the action method, we would like to call this newly define render method instead of the default render method.
Create new jsp file renderAfterAction under /WEB-INF/jsp folder and just enter one line content in it like “<h1>This is Render After Action JSP </h1>

Modify action method as per below code snippet.

@ActionMapping(params = "action=actionOne") 
 public void actionOneMethod(ActionRequest request, ActionResponse response) {
  String userName=ParamUtil.get(request, "userName", "");
  log.info("userName is==>"+userName);
  response.setRenderParameter("action", "renderAfterAction");
 }

Explanation:-

  • The only change we have done is added last line code response.setRenderParameter(“action”, “renderAfterAction”);
  • This will tell the controller that after executing the action method, set render parameter action to “renderAfterAction“.
  • It means, the action method wants to execute a specific render method with a value of the action key set to  renderAfterAction
  • So after executing this action method it will execute testRenderMethod (whose value of action key is renderAfterAction)
Note:- setRenderParameter method is available only for objects of type ActionResponse.
 
Deploy the folder and it will show defaultRender JSP. Give the name “Nilang” and click on Submit button. You will see the render method renderAfterAction get execute as per the below screenshot.
Multiple render and action methods in Spring MVC portlet - render-after-action
You also can notice the log to understand the flow as per below screenshot.
log2
You can notice that after the action method gets executed, control goes to the testRenderMethod method. It’s done. you can try some more Actions and Render method combinations to get more dipper knowledge.

Summing Up

  • Spring MVC Portlet supports multiple render and action methods.
  • Multiple render and action methods are useful to define multiple render and action logic.
  • Liferay MVC Portlet supports one render and multiple action methods while spring MVC portlet allow to define multiple render and action methods.

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

Recommended For You

About the Author: Nilang

Nilang Patel is a technology evangelist who loves to spread knowledge and helping people in all possible ways. He is an author of two technical books - Java 9 Dependency and Spring 5.0 Projects.

96 Comments to “Render and Action methods in Spring MVC portlet in Liferay”

  1. I am referring to this article now and trust me , this was the most helpful article on portlet/JSP/Controller interaction . Thanks a ton Nilang.

  2. I am new in liferay, and here, I find responses to all my questions, very informtive and well explained. YOU SAVE ME MAN!!!!

    1. Hi Bilel,

      Glad to hear that you get help from my blog and welcome to Techblog. Feel free to ask questions / give suggestions.

      Regards
      Nilang

  3. Hi Nilang,

    I followed the above steps and was able to run the spring-mvc-potlet without any issues but I am little confused here , and when I click on the ” Call RenderOne method ” in defualiter.jsp nothing is happening , I mean the flow should goto render1.jsp which is not happenning.

    What to place in place of ” renderOneMethodURL ” in defaultRender.jsp in the case of ” Create Render method with “action” as key “,

    Please suggest me , how to overcome the issue.

    Regards
    Satish

    1. Hi Satish,

      You are correct. I missed to add renderURL and action URL in default.jsp. I have updated it. Pls follow this blog again and do necessary changes. Do let me know if you still face any issue.

      Feel free to ask questions / give suggestions.

      Regards
      Nilang

  4. Hi Nilang,
    thank you great work!!
    I followed your post for using springMvc portlet, but I need some explanation, on how to get back to the defaultrender from the render1 , here is my code snippet “excuse me I’m novice in portlet”:
    ****************MyFirstSpringMVCPortlet.java

    @Controller(value = “MyFirstSpringMVCPortlet”)
    @RequestMapping(“VIEW”)
    public class MyFirstSpringMVCPortlet {
    @RenderMapping
    public String handleRenderRequest(RenderRequest request,
    RenderResponse response, Model model) {
    return “defaultRender”;
    }

    @RenderMapping(params = “action=renderOne”)
    public String renderOneMethod(RenderRequest request,
    RenderResponse response, Model model) {
    return “render1”;
    }

    }
    *********************************default render.jsp

    This is Default Render Jsp
    Call RenderOne method

    ************************************render1.jsp

    homepage

    1. Hi Yougui,
      Welcome to tech blog. Render methods are meant for doing logic and populate the data which will be then shown on JSP. after each render method, next flow will be of JSP. so in your case, in your renderOneMethod, you are returning “render1” means it will show render1.jsp. (You should have that jsp) and the flow will be completed.
      Now if you want to call default render method from render1.jsp then you have to create renderURL without passing and action attribute it. Then it will call default render method.

      If you are expecting to call default render just after renderOneMethod then its not possible. If you want to reuse some logic, then put it in some different private method and call it wherever required.

      Hope this explanation clarify your doubts. Feel free to ask questions / give suggestion.

      Regards
      Nilang

  5. Hi Nilang,

    Could you please explain ResourceURL in liferay and also what is the purpose of using ResourceURL?

    1. Hi Madhav,

      Resource url as its name suggest used to get resource from Liferay server. It’s basically a life cycle which was added from Portlet 2.0(JSR-286) specification. Resource URL generally called in Ajax request. Portlet will not call any other phase after completion of serve resource.

      It’s used to download File, Json Output or any other ajax response. Hope this give some brief about resource URL. I am going to write full fledge article on this.

      Regards
      Nilang

  6. Hi Nilang,

    at first, thank you for great job by making such articles.

    Just one note – it is neccessary to add requires-namespaced-parameters tag with value ‘false’ to liferay-portlet.xml. Otherwise request parameters won’t be passed to the controller in Liferay 6.2.

    Tadeáš Svoboda

    1. Hi
      Thanks for appreciation and welcome to Tech blog. You are correct, from liferay 6.2 onwards, liferay make mandate to have namespace for each request parameter. If we not place the namespace, we will not get the request parameter. To handle this default behavior, we need to place requires-namespaced-parameter value to false in lifeary-portlet.xml file.

      Feel free to ask questions / give such suggestions

      Regards
      Nilang

  7. Hi Nilang,

    at first, thank you for great job by making such articles.

    Just one note – it is neccessary to add requires-namespaced-parameters tag with value ‘false’ to liferay-portlet.xml. Otherwise request parameters won’t be passed to the controller in Liferay 6.2.

    Tadeáš Svoboda

  8. Hi Nilang. Very use tutorial, all is clear. But i have some trouble. At the end step 2 “Create Action method with “action” as key with Default Render method” in my log-console:”11:57:14,382 INFO [http-bio-8080-exec-4][MyFirstSpringMVCTestController:38] userName is==>”
    userName is empty. Can u help with that trouble?

  9. Thank u for this useful tutorial,
    But I want to ask u about this code source:
    @ActionMapping(params = “action=actionOne”)
    public void actionOneMethod(ActionRequest request, ActionResponse response) {
    String userName=ParamUtil.get(request, “userName”, “”);
    log.info(“userName is==>”+userName);
    }
    My Eclipse don’t know params attribute.

    1. Hi Mohammed,

      Welcome to tech blog and thanks for appreciation. Soon I am going to publish separate blog on CRUD operation. So stay tuned and follow Tech blog.

      Regards
      Nilang

    1. Even after adding that value to the “liferay-portlet.xml” I’m still getting a error on our DEV LR 6.2 server.

      xml file:

      portal-portlet-gsa
      /icon.png
      false
      false

      gsa_save_search
      /icon.png
      false
      false
      gsa_save_search-portlet

      ……

      Error:

      18:08:29,014 ERROR [http-bio-80-exec-55][PortletServlet:116] javax.portlet.PortletException: Request processing failed
      javax.portlet.PortletException: Request processing failed
      at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:545)
      at org.springframework.web.portlet.FrameworkPortlet.doDispatch(FrameworkPortlet.java:471)
      at javax.portlet.GenericPortlet.render(GenericPortlet.java:233)

      ………………….

      at org.springframework.web.portlet.DispatcherPortlet.doRenderService(DispatcherPortlet.java:768)
      at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:523)
      … 101 more
      18:08:29,021 ERROR [http-bio-80-exec-55][render_portlet_jsp:132] null
      java.lang.NullPointerException
      at com.gsa.portal.portlet.controller.GSASearchController.homeGSASearch(GSASearchController.java:114)
      at javax.portlet.GenericPortlet.render(GenericPortlet.java:233)
      at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:103)
      at com.liferay.portlet.ScriptDataPortletFilter.doFilter(ScriptDataPortletFilter.java:55)
      at com.liferay.portlet.FilterChainImpl.doFilter(FilterChainImpl.java:100)
      at com.liferay.portal.kernel.portlet.PortletFilterUtil.doFilter(PortletFilterUtil.java:64)

      Any thoughts on how I can resolve this?

      Thanks.

  10. I had to insert <portlet:namespace/> in front of the name attribute’s value or I wouldn’t receive any form data at all.

    I’m using liferay-portal-6.2.0-ce-ga1.

    1. Hi Cuno de Boer,

      You are correct. Starting from 6.2 liferay had mandate to have portlet name space by default. If you want to disable this behavior, you need to set flag in liferay-portlet.xml file. I don’t remember the exact element name but it should be sth like “portlet-namespace”. I will check and let you know the exact name

      Regards
      Nilang

  11. hi nilang,

    my actionmapping method is being called twice for a single request, If i changed my custome theme to classic theme, its working fine. how to resolve this. help me out.

    1. Hi Avinash,

      Sorry for late respond…..
      just make sure you haven’t put the javascript on submit button and in that javascript function, if you are returing the form, then the actionmapping method may get twice. Just change the type as button instead of submit of button in form.

    2. This problem is due to any of the image or resource that is not present in your theme, and your browser tries to fetch that image by sending request twice. Hence calling your action mapping multiple times.

  12. Hi Nilang,
    Thanks your article, that is help me very much in my work.
    I have a problem with parameter in url of liferay portal such as :
    1. I have a link with parameter type=”checknow” to process checking any server. After click the link,the controller receive parameter type=”checknow” process it and return a model with view to “home.jsp” page.
    The view is show home page but the url still have parameter type=”checknow”. So if user press F5 to refresh the home page the controller is still receive parameter type=”checknow”.
    Please help me to reset parameter correct with view “home.jsp” page.
    Thanks ,

    1. Thanks Nilang, I have solution to resolve by the way to redirect to home page.
      Thanks and best regards,
      Unclekim

  13. Hey Nilang, Great article and fairly good for a novice as myself however I have done I think as you have outlined above to build out my first Spring portlet but having issues once building. The build is successful but I am not able to see or pick the portlet from within liferay samples. What can I check to try and resolve this particular issue.

    1. Hi,

      Can you please check whether the portlet is deployed properly. You can check the server log. If there is any issue by which the portlet is not deployed, then it won’t be available for deployment.

      Regards
      Nilang

  14. Hi Nilang,

    Thanks for the post. I have a question please. If I want to return to defaultRender page from render1 page, what is the best way to do it?

    Cheers,

    Charles

    1. Hi Charles,

      First of all welcome to Tech blog. Actually in Spring MVC portlet, there is one default render method which doesn’t have any action defined. so let say you are on render1.jsp page and you want to execute the default render method. So you have to create the render url without passing any action parameter. This will drive you to default render method.

      Regard
      Nilang.

  15. Man, you got skills..
    I appreciate your work and thanks a lot for sharing this with all of us.

    Please find time to write a blog to connect to MySql Database and corresponding data transfer ASAP.

    God bless ya dude!

  16. Hello can you please give me the way to remove /-/ from the url? I have already shortened the url to “http://localhost:8080/web/standorman/blogs/-/blogs/application-development-in-liferay”. But i want the url to be “http://localhost:8080/web/standorman/blogs/application-development-in-liferay”.
    Please help i am in urgent need of this.

    1. Hi

      At first point, I would say it should not be possible. Liferay consider and find the page by url. if the url (as per you say) is http://localhost:8080/web/standorman/blogs/application-development-in-liferay, then it will try looking the page (with name) “application-development-in-liferay” under page standorman–>blogs.

      In case of friendly url, liferay only know that the rest part after ‘/-/’, is friendly url and will be mapped from router.xml file.

      But I will look into the matter, if its possible by any mean.

      Regards
      Nilang

    1. Hi Mitesh,

      sorry for late responding. You can pass the object the similar way you are doing with normal Spring MVC (non portlet context). You can define

      return new ModelAndView(“jspName”);

      Let me know if you have any query. Also join this blog to stay updated.

      Regards
      Nilang

  17. You can put the portlet in Theme. I will explain this in separate blog. For making Ajax call in Theme, I didn’t get. Can you please let me know your exact requirement ?

    Regards
    Nilang I Pate

    1. Sure Nivas,

      Just see the Followers sections, Just above the TAG CLOUD. From this section, you can find the button (in blue color) called Joint this site. Click on it and fill the required information. That’s all.

      Regards
      Nilang

  18. Hi Nivas,

    First of all Welcome to Tech Blog and Heartly Thanks for Appreciation !!!. Sure I will write the blog showing how to make Ajax call from Spring MVC portlet. In short, you have to write resource method (just like action and render) in controller which you can call from Ajax call ( made through jQuery in jsp). I will show this in more detail in separate blog.

    It will be good for you if you join this blog to get latest updates.

    Have a happy Learning….!!!

    Regards
    Nilang

  19. Hi Nilang,

    I am searching for this kind of tutorial for some much long time and finally found it here.It helped a lot to understand annotations in spring mvc porlet. Please come up with more blogs.
    Thanks for this useful article.

    can you say me how to use ajax in spring mvc portlet in liferay.??

    thanks in advance

  20. Hi Swarpa,

    First of all heartly thanks for appreciation. I am going to write another blog on how to save the data to DB. Liferay is providing very good tool (framework) to create Service (in Spring) and Persistance(in Hibernate) layer.

    So requesting you to please join this blog to stay update. I will send you mail once I add the blog for saving infomration to DB.

    Regards
    Nilang

  21. Hi Nilang,

    Very Very Thanks for giving the great information.I am following your guide lines and able to give the username and retrieving it in controller class.I need to save this information in database.Can you give me any idea or any sample link will be appreciated.

    Once again thanks for your valuable information.

    1. Hey Nilang,
      I am using your guidelines to create the portlet.
      I want to know if i can utilize the getCommand() ( @ModelAttribute ) in the liferay portlet . Is it possible to use the same..
      As you know the @ModelAttribute is used to get the data of the form in the controller class. I want to use the same functionality because i am having a very large form on the client side & i need to get the values of the form without writing a lot of code and fetching the parameters from the request…
      Is there any other possibility if I cant use this?

    2. Hi Danish,
      Definitely you can you @ModelAttribute. It will work without any problem since we are using the Spring MVC (in portlet context).

      Let me know if you facing any trouble in achieving the same.

      Regards
      Nilang

Leave a Reply

Your email address will not be published. Required fields are marked *

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