Passing information from Action to Render Phase

Portlet specification defines various phases of portlet like render, action, serve-resource, event etc. Passing information from one phase to another(e.g passing information from action to render) is common scenario. When portlet completes the action phase, portal container will call its render phase (along with render phase of all portlet on same page).

Many a  times, you need to pass some information from action to render phase. For example, you are adding student details in DB.

To achieve this you need to create html form (with student details like name, standard DOB etc) with action URL. When user submit the form, these data (student information) will be available in action method where you perform CRUD operation to add student.

As per portlet specification, soon after action phase completes, portal container will trigger its render phase(by calling render method).

Assume that you want to show success message like “<<NAME OF STUDENT>> is added successfully” in portlet JSP (view.jsp).

For this student name should be available in render method. But you are getting student name (along with other information) in action method. So you need to pass student name from action method to render method.

I will be showing how to pass data from action to render phase by creating Liferay MVC Portlet. I took plugin project name as action-to-render and -portlet will be appended by Liferay IDE while creating plugin project.

I gave portlet class as com.opensource.techblog.portlet.ActionToRenderPortlet. After this the project structure looks like below screenshot.

Action to Render Phase - Project Structure

 

Add following code in view.jsp

Explanation

  • To understand how and from where to pass the information from action to render, I mimic the code to add student here.
  • So in this jsp, I have created one html form with action URL. In this html form, I am taking student name and standard.
  • When user submit this form, these information (name and standard) will be sent to action method to add student infomration in DB.

Now add following code in ActionToRenderPortlet class

Explanation

  • I have added action method which will be called when user submit the form (triggered through action URL bind to that form)
  • In this action method, I am reading request parameter name (student name) and standard. (I used ParamUtil class to read the request parameters)
  • The comment – “code to add student here” would be actual code to save student detail in DB. To make it simple, I haven’t put actual code. Our main goal is to see how to pass information from render to action phase.
  • In render method, I am reading studentName parameter and storing it in request attribute so that I can use it in view.jsp (through EL – expression language) to show success message with student name.
  • Portal will call render phase (method) after completion of action phase(method). I am reading  name(student name) parameter in action method which will not be available to render method by default. (at this point try yourself reading name(student name) request param in render method and you will get null /empty value).
  • In liferay we can pass information from action to render by different approaches / mechanisms.

Various mechanisms to pass information from Action to Render Phase

There are many ways to pass information from action to render phase. In this article, we will see each of them.

Approach:-1 By setting render parameter in actionResponse object

In this approach, you can pass information from action to render by setting it in render parameter in action method. Let’s do it practically. Add following code at the end of action method (after the comment)

Explanation

  • What we are doing is passing the value of parameter (which we already read from ActionRequest object and stored in variable studentName) into ActionResponse object by calling it’s setRenderParameter method.
  • This method is overloaded and it has following variants.
    • actionResponse.setRenderParameter(key, value) :- will be used to pass key and its value.
    • actionResponse.setRenderParameter(key, values[]) :- will be used to pass key and multiple values
    • actionResponse.setRenderParameters(Map<Key,values[]>) :- will be used to pass map of keys with its multiple values.
    • Here all parameters type would be of String
    • Note: You can access these parameter in render method by same key name that you passed in action method.
  • Pros
    • It’s very easy to use
  • Cons
    • For each separate parameter that you want to pass from action to render phase, you have to make separate actionResponse.setRenderParameter method call.
    • Since it’s parameter, you only can pass object of type String from render to action phase

Approach:-2 By setting init parameter ‘copy-request-parameters’ in portlet.xml file.

This approach talks about sending infromation from action to render by just doing configuraiton change. Add following init parameter in portlet.xml file

Explanation

  • What does this mean ? We are instructing portal to pass all parameter from action to render phase for that portlet. In other words, by default all render parameter would be available to render method as well for that portlet.
  • Try yourself by first removing all actionResponse.setRenderParameter and then put above code in portlet.xml. You will observe that all parameter that are available in action method are also available in render method and you no need to do any extra things.
  • Pros
    • You no need to make separate actionResponse.setRenderParameter call for each parameter.
  • Cons
    • Since it’s parameter, you only can pass object of type String from render to action phase
    • You need to pay special attention while using this approach.
      • When you set copy-request-parameters to true for any portlet, then the portal will remember all such parameter of that portlet for any further execution.
      • What does this mean ? Let’s understand this by example. Assume that there are 2 portlets placed on page. Out of them one we already seen above, I am calling it portlet-1. Assume that second portlet has just one link (render URL). When user clicks on this link, portal will call render method of second portlet along with render method of first portlet (portlet 1) as well.
      • But for portlet 1 (just we seen above to add student details), portal will remember the parameter which were added in action method of portlet 1 so it will print success message every time user click on link on second portlet (portlet-2)
      • When user manually refresh the page or do any direct interaction with portlet-1 then only it will remove those render parameter.
      • So in case if you don’t wish to retain such render parameter in render method while interacting with other portlet, then you need to manually call actionResponse.setRenderPamater method for each such parameter instead of setting copy-request-parameters value in portlet.xml file.

Approach:-3 passing information by setting it in request attribute.

In this approach, you need to simply add your information in request scope to pass it from action to render phase. For example, add following code in action method.

Explanation:

  • we can set the information in request attribute by calling actionRequest.setAttribute(KEY,VALUE).
  • As stated in this blog, portal will call render method just after it complete execution of action method. So if you wish to access your information, you need to simply call renderRequest.getAttribute(KEY). You need to pass same KEY which you used while adding it in request attribute in action method.
  • to understand it properly, I am passing standard in request attribute. If you wish to read it in render method, you need to call renderRequest.getAttribute(“standard”).
  • Pros
    • You can pass any object (not only String) from action to render method.
    • It’s very simple to use. Any parameter which are stored in request parameter will be available in JSP as well. so you can directly access them by EL (Expression Language)
  • Cons
    • For each object you wish to pass from action to render, you need to make separate call for actionRequest.setAttribute method.

Summing UP

  • Passing information across portlet phase is a common scenario. As per portlet specification, portal will call render method soon after execution of action method completes.
  • You can pass information from action to render method by
    • adding parameter by calling actionResponse.setRenderParameter
    • setting init parameter copy-request-parameters to true in portlet.xml file
    • setting information in request attribute by calling actionRequest.setAttribute method.
  • You can refer this link for more information.

Download Source – Liferay 6.2

Share This Post

Post Comment

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