There are two ways to pass information from the action phase to the render phase. The first one is through render parameters. Within the implementation in the processAction method you can invoke the setRenderParameter to add a new parameter to the request that the render phase will be able to read:
actionResponse.setRenderParameter("parameter-name", "value");
From the render phase (in our case, the JSP), this value can be read using the regular parameter reading method:
renderRequest.getParameter("parameter-name");
It is important to be aware that when invoking an action URL, the paramet-ers specified in the URL will only be readable from the action phase (that is the processAction method). In order to pass parameter values to the render phase you must read them from the actionRequest and then invoke the setRenderParameter method for each parameter needed.
Tip: Liferay offers a convenient extension to the portlet specification through the MVCPortlet class to copy all action parameters directly as render parameters. You can achieve this just by setting the following init-param in your portlet.xml:
<init-param>
<name>copy-request-parameters</name>
<value>true</value>
</init-param>
I mentioned there was a second method and in fact it is a better method for what we are trying to do in our example. One final thing you should know about
Passing Information from the Action
Phase to the Render Phase 33
render parameters is that the portal remembers them for all later executions of the portlet until the portlet is invoked again with different parameters. That is, if a user clicks a link in our portlet and a render parameter is set, and then the user continues browsing through other portlets in the page, each time the page is reloaded the portal will render our portlet using the render parameters that we set. If we used render parameters in our example then the success message will be shown not only right after saving, but also every time the portlet is rendered until the portlet is invoked again without that render parameter.
The second method of passing information from the action phase to the render phase is not unique to portlets so it might be familiar to you: using the session. By using the session, your code can set an attribute in the actionRequest that is then read from the JSP. In our case the JSP would also immediately re-move the attribute from the session so that the message is only shown once.
Liferay provides a helper class and taglib to do this operation easily. In the pro-cessAction you need to use the SessionMessages class:
package com.liferay.samples;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.util.bridges.mvc.MVCPortlet;
public class MyGreetingPortlet extends MVCPortlet {
@Override
public void processAction(
ActionRequest actionRequest, ActionResponse actionResponse) throws IOException, PortletException {
PortletPreferences prefs = actionRequest.getPreferences();
String greeting = actionRequest.getParameter("greeting");
if (greeting != null) {
prefs.setValue("greeting", greeting);
prefs.store();
}
SessionMessages.add(actionRequest, "success");
super.processAction(actionRequest, actionResponse);
} }
34 Passing Information from the Action
Also, in the JSP you would need to add the liferay-ui:success JSP tag as shown below (note that you also need to add the taglib declaration at the top):
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<%@ page import="com.liferay.portal.kernel.util.ParamUtil" %>
<%@ page import="com.liferay.portal.kernel.util.Validator" %>
<%@ page import="javax.portlet.PortletPreferences" %>
<portlet:defineObjects />
<%
PortletPreferences prefs = renderRequest.getPreferences();
String greeting = (String)prefs.getValue(
"greeting", "Hello! Welcome to our portal.");
%>
<liferay-ui:success key="success" message="Greeting saved successfully!" />
<portlet:actionURL var="editGreetingURL">
<portlet:param name="jspPage" value="/edit.jsp" />
</portlet:actionURL>
<aui:form action="<%= editGreetingURL %>" method="post">
<aui:input label="greeting" name="greeting" type="text" value="<%=
greeting %>" />
<aui:button type="submit" />
</aui:form>
<portlet:renderURL var="viewGreetingURL">
<portlet:param name="jspPage" value="/view.jsp" />
</portlet:renderURL>
<p><a href="<%= viewGreetingURL %>">← Back</a></p>
After this change, redeploy the portlet, go to the edit screen and save it. You should see a nice message that looks like this:
Passing Information from the Action
Phase to the Render Phase 35
Illustration 1: The sample “My Greetings” portlet showing a success message
There is also an equivalent util class for notifying errors. This is commonly used after catching an exception in the processAction. For example.
try {
prefs.setValue("greeting", greeting);
prefs.store();
}
catch(Exception e) {
SessionErrors.add(actionRequest, "error");
}
And then the error, if it exists, is shown in the JSP using the liferay-ui:error tag:
<liferay-ui:error key="error" message="Sorry, an error prevented saving your greeting" />
When the error occurs you should see something like this in your portlet:
The first message is automatically added by Liferay. The second one is the one you entered in the JSP.