oo

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.112-ga112

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:

  1. 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
    
  2. Build and deploy the example.

    cd liferay-t9u3
    
     ./gradlew deploy -Ddeploy.docker.container.id=$(docker ps -lq)
    
    note

    This command is the same as copying module JARs to /opt/liferay/osgi/modules on the Docker container.

  3. Confirm the deployment in the Docker container console.

    STARTED com.acme.t9u3.web_1.0.0
    
  4. Add the T9U3 Portlet widget from the Samples category to a widget page. The T9U3 Portlet appears.

    You've added the T9U3 Portlet to a page.

    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.

  5. Click Do Something. The portlet logs the doSomething method’s invocation.

    [T9U3Portlet:28] Invoke #doSomething(ActionRequest, ActionResponse)
    
  6. Click Do Something Else. The portlet logs the doSomethingElse method’s invocation.

    [T9U3Portlet:36] Invoke #doSomethingElse(ActionRequest, ActionResponse)
    
  7. 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.