oo

MVC Action Command

MVC Action Commands handle actions as separate classes. With Action Commands, you can organize action logic in MVCPortlets that have many actions. Action URLs in the portlet’s JSPs invoke a designated MVC Action Command class.

You’ll deploy an example portlet that uses MVC Action Commands and then examine it.

Invoke a Portlet’s MVC Action Commands

The example portlet’s two actions log messages that indicate the MVC Action Command class and method being invoked.

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-l6y9.zip -O
    
    unzip liferay-l6y9.zip
    
  2. Build and deploy the example.

    cd liferay-l6y9
    
    ./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.l6y9.web_1.0.0
    
  4. Add the L6Y9 Portlet widget from the Samples category to a widget page. The L6Y9 Portlet appears.

    You've added the L6Y9 Portlet to a page.

    The links invoke methods in different MVCActionCommand classes. For learning purposes, the methods log messages identifying themselves.

  5. Click Do L6Y9 Able. DoL6Y9AbleMVCActionCommand logs invoking its doProcessAction method.

    [DoL6Y9AbleMVCActionCommand:26] Invoke #doProcessAction(ActionRequest, ActionResponse)
    
  6. Click Do L6Y9 Baker. DoL6Y9BakerMVCActionCommand logs invoking its doProcessAction method.

    [DoL6Y9BakerMVCActionCommand:26] Invoke #doProcessAction(ActionRequest, ActionResponse)
    

You’ve seen MVC Action Commands in action. Now see how they work.

Examine the Portlet

L6Y9Portlet is a minimal MVCPortlet.

@Component(
	property = {
		"com.liferay.portlet.display-category=category.sample",
		"javax.portlet.display-name=L6Y9 Portlet",
		"javax.portlet.init-param.view-template=/view.jsp",
		"javax.portlet.name=com_acme_l6y9_web_internal_portlet_L6Y9Portlet"
	},
	service = Portlet.class
)
public class L6Y9Portlet extends MVCPortlet {
}

The @Component javax.portlet.name property sets the portlet’s name.

"javax.portlet.name=com_acme_l6y9_web_internal_portlet_L6Y9Portlet"

The portlet renders /view.jsp by default.

Note

MVCActionCommands bind to a portlet by the portlet’s name (e.g., the portlet component javax.portlet.name property value).

The example portlet renders view.jsp by default. Next you’ll see how the JSP invokes the MVC Action Command classes.

Examine the Portlet Action URLs

The portlet’s view.jsp file renders links for invoking the portlet’s MVC Action Commands.

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>

<h4>L6Y9 Portlet</h4>

<p>
	<a href="<portlet:actionURL name="/l6y9/do_l6y9_able" />">Do L6Y9 Able</a>
</p>

<p>
	<a href="<portlet:actionURL name="/l6y9/do_l6y9_baker" />">Do L6Y9 Baker</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. Each tag maps the UI component to an MVC command by assigning the MVC Action Command’s mvc.command.name property value to the tag’s name attribute.

view.jsp Portlet Action URL DoL6Y9AbleMVCActionCommand Component Property
<portlet:actionURL name="/do_l6y9_able" /> mvc.command.name=/l6y9/do_l6y9_able
view.jsp Portlet Action URL DoL6Y9BakerMVCActionCommand Component Property
<portlet:actionURL name="/do_l6y9_baker" /> mvc.command.name=/l6y9/do_l6y9_baker

Clicking on the Do L6Y9 Able link, for example, invokes DoL6Y9AbleMVCActionCommand’s doProcessAction method.

Examine the MVCActionCommand Classes

MVC Action Command classes can implement MVCActionCommand directly or by extending BaseMVCActionCommand. DoL6Y9AbleMVCActionCommand extends BaseMVCActionCommand.

@Component(
	property = {
		"javax.portlet.name=com_acme_l6y9_web_internal_portlet_L6Y9Portlet",
		"mvc.command.name=/l6y9/do_l6y9_able"
	},
	service = MVCActionCommand.class
)
public class DoL6Y9AbleMVCActionCommand extends BaseMVCActionCommand {

	@Override
	protected void doProcessAction(
		ActionRequest actionRequest, ActionResponse actionResponse) {

		if (_log.isInfoEnabled()) {
			_log.info(
				"Invoking #doProcessAction(ActionRequest, ActionResponse)");
		}
	}

	private static final Log _log = LogFactoryUtil.getLog(
		DoL6Y9AbleMVCActionCommand.class);

}

DoL6Y9AbleMVCActionCommand is a Component that provides an MVCActionCommand service. DoL6Y9AbleMVCActionCommand’s component properties apply the component to the portlet that has the property javax.portlet.name=com_acme_l6y9_web_internal_portlet_L6Y9Portlet and map the component to an MVC command named /do_l6y9_able. When a user triggers an action bound to that command name, DoL6Y9AbleMVCActionCommand’s doProcessAction method executes. For demonstration purposes, the doProcessAction method above logs a message that identifies itself.

Note

You can associate an MVCActionCommand component with multiple portlets by declaring separate javax.portlet.name properties for each portlet:

@Component(
    property = {
        "javax.portlet.name=com_acme_l6y9_web_internal_portlet_L6Y9Portlet",
        "javax.portlet.name=com_acme_l6y9_web_internal_portlet_L6Y0Portlet",
        "mvc.command.name=/l6y9/download"
    },
    service = MVCActionCommand.class
)

DoL6Y9BakerMVCActionCommand is similar to DoL6Y9AbleMVCActionCommand except its names contain Baker or baker instead Able or able.

Next see how the portlet’s JSP maps UI component actions to the commands.

What’s Next

Now that you know how to use MVC Action Commands, you may want to check out MVC Render Commands and MVC Resource Commands. If you want to start localizing your app’s content, see Using Localized Messages. If you’re ready to start developing model, persistence, and service layers, visit Service Builder.