Invoking Actions with MVC Portlet
A portlet’s Action phase applies state changes. You can bind your portlet’s action-handling methods to UI components using portlet action URLs. They are portlet:actionURL
JSP tags that map the user’s request to a portlet method for performing an action.
Here you’ll learn how to invoke and examine an example portlet that uses action URLs three different ways.
Deploy an MVC Portlet that Handles Actions
The example MVC Portlet has three portlet action URLs that map to separate portlet methods.
Start a new Liferay instance by running
docker run -it -m 8g -p 8080:8080 liferay/portal:7.4.3.120-ga120
Sign in to Liferay at http://localhost:8080. Use the email address test@liferay.com and the password test. When prompted, change the password to learn.
Then, follow these steps to deploy the portlet and trigger its actions:
-
Download and unzip the example.
curl https://resources.learn.liferay.com/dxp/latest/en/building-applications/developing-a-java-web-application/using-mvc/liferay-t9u3.zip -O
unzip liferay-t9u3.zip
-
Build and deploy the example.
cd liferay-t9u3
./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
noteThis command is the same as copying module JARs to
/opt/liferay/osgi/modules
on the Docker container. -
Confirm the deployment in the Docker container console.
STARTED com.acme.t9u3.web_1.0.0
-
Add the T9U3 Portlet widget from the Samples category to a widget page. The T9U3 Portlet appears.
The portlet has three links:
- Do Something
- Do Something Else
- Do Something More
Clicking each link invokes a different action-handling method. For learning purposes, each method logs a message that identifies itself.
-
Click Do Something. The portlet logs the
doSomething
method’s invocation.[T9U3Portlet:28] Invoke #doSomething(ActionRequest, ActionResponse)
-
Click Do Something Else. The portlet logs the
doSomethingElse
method’s invocation.[T9U3Portlet:36] Invoke #doSomethingElse(ActionRequest, ActionResponse)
-
Click Do Something More. The portlet logs the
doSomethingMore
method’s invocation.[T9U3Portlet:45] Invoke #doSomethingMore(ActionRequest, ActionResponse)
These actions are trivial, but they demonstrate different ways to map UI components to portlet action-handling methods. Next you’ll learn how they work.
Examine the Portlet’s Action-Handling Methods
The T9U3Portlet
class is a standard MVCPortlet
that has three action-handling methods.
@Component(
property = {
"com.liferay.portlet.display-category=category.sample",
"javax.portlet.display-name=T9U3 Portlet",
"javax.portlet.init-param.view-template=/view.jsp"
},
service = Portlet.class
)
public class T9U3Portlet extends MVCPortlet {
public void doSomething(
ActionRequest actionRequest, ActionResponse actionResponse) {
if (_log.isInfoEnabled()) {
_log.info("Invoking #doSomething(ActionRequest, ActionResponse)");
}
}
public void doSomethingElse(
ActionRequest actionRequest, ActionResponse actionResponse) {
if (_log.isInfoEnabled()) {
_log.info(
"Invoking #doSomethingElse(ActionRequest, ActionResponse)");
}
}
@ProcessAction(name = "nameForTheDoSomethingMoreMethod")
public void doSomethingMore(
ActionRequest actionRequest, ActionResponse actionResponse) {
if (_log.isInfoEnabled()) {
_log.info(
"Invoking #doSomethingMore(ActionRequest, ActionResponse)");
}
}
private static final Log _log = LogFactoryUtil.getLog(T9U3Portlet.class);
}
The @Component
annotation marks the class as an OSGi Declarative Services Component that provides the Portlet
service. The properties make the portlet available in the Sample widget category, name the portlet T9U3 Portlet, and set the portlet’s default view template to /view.jsp
.
Each method takes an ActionRequest
and ActionResponse
parameter. The ActionRequest
provides the method information and the ActionResponse
provides a means for the method to pass along information. Each example method identifies itself with a log message.
The JSP (discussed next) maps to the example methods using portlet action URLs. The first two methods are the same except for their names. The last method stands out because of its @ProcessAction(name = "nameForTheDoSomethingMoreMethod")
annotation. Portlet action URLs can map to a method via a @ProcessAction
annotation name instead of the method name. By using the ProcessAction
name, for example, you can change the method name or assign the annotation to a different method without breaking the portlet action URL. Examining the JSP’s portlet action URLs makes this easier to understand.
Examine the JSP
The view.jsp
binds UI components to the portlet’s action-handling methods using portlet action URLs. Here’s the view.jsp
code:
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:actionURL name="doSomething" var="actionURL" />
<h4>T9U3 Portlet</h4>
<p>
<a href="<%= actionURL %>">Do Something</a>
</p>
<p>
<a href="<portlet:actionURL name="doSomethingElse" />">Do Something Else</a>
</p>
<p>
<a href="<portlet:actionURL><portlet:param name="javax.portlet.action" value="nameForTheDoSomethingMoreMethod" /></portlet:actionURL>">Do Something More</a>
</p>
The first line makes the Portlet 2.0 tag library available via the portlet
prefix. This JSP binds actions to UI components using the tag library’s portlet:actionURL
tag. Examine each action URL.
Example 1: Referencing an Action URL by its Variable
The view.jsp
declares the following portlet action URL.
<portlet:actionURL name="doSomething" var="actionURL" />
A portlet:actionURL
’s name
attribute maps to the doSomething
portlet method. The var
attribute assigns the portlet action URL to an arbitrary variable. This JSP binds the action URL to a hyperlink labeled Do Something
by referencing the actionURL
variable.
<a href="<%= actionURL %>">Do Something</a>
Clicking this link invokes the portlet’s doSomething
method. You can bind the action URL to multiple UI components by referencing the action URL’s variable.
Example 2: Declaring an Action URL in a UI Component
The JSP declares another action URL directly in an anchor component.
<a href="<portlet:actionURL name="doSomethingElse" />">Do Something Else</a>
The component declares an action URL that binds the action to the portlet’s doSomethingElse
method. It’s a more compact way of mapping an action URL.
Example 3: Referencing a Portlet Action Name
In the last anchor, the JSP declares an action URL that maps to an action-processing method associated with the nameForTheDoSomethingMoreMethod
portlet action name.
JSP action URL:
<a href="<portlet:actionURL><portlet:param name="javax.portlet.action" value="nameForTheDoSomethingMoreMethod" /></portlet:actionURL>">Do Something More</a>
Portlet method:
@ProcessAction(name = "nameForTheDoSomethingMoreMethod")
public void doSomethingMore(
ActionRequest actionRequest, ActionResponse actionResponse) {
if (_log.isInfoEnabled()) {
_log.info(
"Invoking #doSomethingMore(ActionRequest, ActionResponse)");
}
}
The portlet parameter called nameForTheDoSomethingMoreMethod
provides looser coupling between the action URL and method. For example, it frees you to change the method name or to assign the @ProcessAction(name = "nameForTheDoSomethingMoreMethod")
annotation to a different method.
What’s Next
Now that you know how to use action URLs, you can concentrate on writing action methods. Alternatively, you could investigate using MVCActionCommand classes. Or if you’re ready to explore handling other portlet phases, look at using MVCRenderCommand and MVCResourceCommand classes.