Render and Action methods in Spring MVC portlet in Liferay

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

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

Define multiple render and action methods


In last blog
(Spring MVC Portlet in Liferay) we have created 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 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 solution is that, we can define independent chunk of code in separate method and call it in default render() method. The issue in this approach is we will end up in defining multiple if-else condition and have to set different flag value.

Spring MVC Portlet address this issue effectively by allowing us to define multiple render and action methods. This help us to divide render logic in 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

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 match 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 similar concept that we have seen for default Render method in previous blog (the returning string represent 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 following code.

 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 in the page with JSTL. We also passed portlet parameter called action and its value is “renderOne”
  • Then I have added header – This is Default Render Jsp.
  • If you notice, I kept same value of action parameter in render URL with the value of action key for renderOneMethod method in 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 its time to see our work. Build and deploy the portlet. We already place the portlet on liferay page. So just refresh it to see the changes. You can notice that the defaultRender jsp get render and generate output as per 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 below screenshot.
Multiple render and action methods in Spring MVC portlet - render1-method
If you want, you can put 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 with similar way we have created the above Render method. Add the code in defaultRender.jsp so that it will looks like below snippet.



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 controller class with action key and set its value as “actionOne” so that it can be call when this actionURL is clicked from JSP.
  • At the end we had created 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 same as renderURL. When we hit the submit button, the respective action method will be called who’s action key value is matched with the action parameter value in  <portlet:action> tag.
Next, we will create action method as per below snippet in controller class.

Explanation:-

  • We have created action method with annoation @ActionMapping and its param attribute is “action=actionOne”. It means this action method have 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 parameter through Liferay utility class(ParamUtil).
  • At the last, I am printing the request parameter through logger. You can create logger in Liferay by creating class level static variable with the help of Liferay utility class LogFactoryUtil as shown in below snippet.

  • 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 get executed what is the output. And the answer is it will execute default Render method.
Now its time to see this in action. Deploy the portlet and you will see the portlet get rendered as per below screenshot.
Multiple render and action methods in Spring MVC portlet - action-method-1
Give any value in 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 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 log in default render method to understand it more clear.

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

As per portlet specification, render method will be called soon after action method completes its execution. In case of Spring MVC Portlet, default render method will be called after completion of action method.This is default behavior.
Spring MVC portlet framework provides a way to execute specific render method instead of default render after completion of action method.
 
Let’s see how to achieve this. Create one render method as per below snippet.

Explanation:-

  • we created 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 action method, we would like to call this newly define render method instead of 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.


Explanation:-

  • The only change we have done is added last line code response.setRenderParameter(“action”, “renderAfterAction”);
  • This will tell controller that after executing the action method, set render parameter action to “renderAfterAction“.
  • It means, the action method wants to execute specific render method with value of action key set to  renderAfterAction
  • So after executing this action method it will execute testRenderMethod (who’s value of action key is renderAfterAction)
Note:- setRenderParameter method is available only for object of type ActionResponse.
 
Deploy the folder and it will show defaultRender jsp. Give the name as “Nilang” and click on Submit button. You will see the render method renderAfterAction get execute as per below screen shot.
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 get executed, control goes to testRenderMethod method. Its done. you can try some more Actions and Render method combination 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 index page ‘A Complete Liferay Guide‘ to browse all topics about liferay.

Share This Post

94 Comments - Write a Comment

  1. 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

    Reply
    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

      Reply
  2. 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

    Reply
    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

      Reply
    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

      Reply
  3. 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

    Reply
    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

      Reply
  4. 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

    Reply
  5. 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?

    Reply
  6. 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.

    Reply
    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.

      Reply
    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

      Reply
  7. 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.

    Reply
    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.

      Reply
    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.

      Reply
  8. 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 ,

    Reply
  9. 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.

    Reply
    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

      Reply
    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.

      Reply
  10. 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!

    Reply
  11. 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.

    Reply
    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

      Reply
    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

      Reply
    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

      Reply
  12. 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

    Reply
  13. 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

    Reply
  14. 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

    Reply
  15. 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.

    Reply
    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?

      Reply
    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

      Reply

Post Comment