oo

MVC Render Command

MVC Render Commands are classes that handle which page to render. They are invoked by MVCPortlet render URLs and requests. If your render logic is simple you can implement all of it in your portlet class. If your render logic is complex or you want clean separation between render paths, use MVC Render Commands.

Invoke an MVC Render Command

Here you’ll deploy an example portlet that renders views using MVC render commands.

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:

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

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

    You've added the A4P1 Portlet to a page.

  5. Invoke an MVC render command to visit the Baker view by clicking Go to Baker. A4P1BakerMVCRenderCommand logs invoking its render method and renders the Baker view.

    [A4P1BakerMVCRenderCommand:26] Invoking #render(RenderRequest, RenderResponse)
    

    You're rendering the Baker view.

  6. Invoke the other MVC render command and revisit the Able view by clicking Go to Able. A4P1AbleMVCRenderCommand logs invoking its render method and renders the Able view again.

    [A4P1AbleMVCRenderCommand:26] Invoking #render(RenderRequest, RenderResponse)
    

You’ve seen MVC Render Commands in action. Now learn how they work.

Examine the Portlet

A4P1Portlet is a minimal MVCPortlet.

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

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

"javax.portlet.name=com_acme_a4p1_web_internal_portlet_A4P1Portlet"

The portlet renders /a4p1/able.jsp by default.

Note

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

The portlet’s MVC Render Command classes are next.

Examine the MVCRenderCommand Classes

MVC Render Command classes can implement MVCRenderCommand directly. A4P1AbleMVCRenderCommand directly implements MVCRenderCommand. Here is A4P1AbleMVCRenderCommand:

@Component(
	property = {
		"javax.portlet.name=com_acme_a4p1_web_internal_portlet_A4P1Portlet",
		"mvc.command.name=/a4p1/able"
	},
	service = MVCRenderCommand.class
)
public class A4P1AbleMVCRenderCommand implements MVCRenderCommand {

	@Override
	public String render(
		RenderRequest renderRequest, RenderResponse renderResponse) {

		if (_log.isInfoEnabled()) {
			_log.info("Invoking #render(RenderRequest, RenderResponse)");
		}

		return "/a4p1/able.jsp";
	}

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

}

A4P1AbleMVCRenderCommand is a Component that provides an MVCRenderCommand service. The component properties apply the A4P1AbleMVCRenderCommand to the portlet named com_acme_a4p1_web_internal_portlet_A4P1Portlet and map A4P1AbleMVCRenderCommand to the MVC command name /a4p1/able.

Note

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

    @Component(
        property = {
            "javax.portlet.name=com_acme_a4p1_web_internal_portlet_A4P1Portlet",
            "javax.portlet.name=com_acme_a4p1_web_internal_portlet_A4P2Portlet",
            "mvc.command.name=/a4p1/download"
        },
        service = MVCRenderCommand.class
    )

When the portlet receives a request parameter that specifies the MVC command name /a4p1/able, A4P1AbleMVCRenderCommand’s render method executes. This render method logs a message that identifies itself and then returns the path of the view to render.

A4P1BakerMVCRenderCommand is similar to A4P1AbleMVCRenderCommand except its MVC command name is /a4p1/baker and its render method returns the view path /a4p1/baker.jsp.

These example MVC Render Commands provide trivial functionality for demonstration purposes. Implement your MVC Render Command’s render method using logic required to render your views.

The example URLs trigger the MVC Render Commands.

Examine the Portlet Render URLs

The able.jsp and baker.jsp files indirectly link to each other using portlet render URLs. Here is able.jsp:

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

<h4>A4P1 Portlet</h4>

<h5>Able</h5>

<portlet:renderURL var="bakerURL">
	<portlet:param name="mvcRenderCommandName" value="/a4p1/baker" />
</portlet:renderURL>

<a href="<%= bakerURL %>">Go to Baker</a>

The portlet:renderURL tag is available from the portlet taglib and is assigned the prefix portlet. This render URL declares the mvcRenderCommandName portlet parameter value /a4p1/baker—this is A4P1AbleMVCRenderCommand’s MVC command name. The variable bakerURL references this render URL.

The hyperlink <a href="<%= bakerURL %>">Go to Baker</a> binds the render URL to an action. When a user clicks on the hyperlink, the portlet sends the RenderRequest to A4P1BakerMVCRenderCommand because its mvc.command.name component property value /a4p1/baker matches the mvcRenderCommandName parameter value.

baker.jsp is similar to able.jsp except its portlet render URL mvcRenderCommandName parameter value is /a4p1/able. Each JSP’s portlet:renderURL tag maps to an MVC Render Command by assigning the MVC Render Command’s mvc.command.name property value to the tag’s mvcRenderCommandName portlet parameter.

able.jsp Portlet Render URL Parameter A4P1BakerMVCRenderCommand Component Property
<portlet:param name="mvcRenderCommandName" value="/a4p1/baker" /> mvc.command.name=/a4p1/baker
baker.jsp Portlet Render URL Parameter A4P1AbleMVCRenderCommand Component Property
<portlet:param name="mvcRenderCommandName" value="/a4p1/able" /> mvc.command.name=/a4p1/able

What’s Next

Now you know how to implement render logic in MVC Render Command classes. Next, you can act on resources such as files using MVC Resource Command classes.