MVC Render Command

If you’re here, that means you know that MVCRenderCommands are used to respond to portlet render URLs, and you want to know how to create and use MVC render commands. If you just want to learn about Liferay’s MVC Portlet framework in general, that information is in a separate article.

First, configure your view layer and use the <portlet:renderURL> to create the render URL in your JSP. For example, the following render URL invokes an MVC render command named /hello/edit_entry. This might direct the user to a page with a form for editing.

<portlet:renderURL var="editEntryURL">
    <portlet:param name="mvcRenderCommandName" value="/hello/edit_entry" />
    <portlet:param name="entryId" value="<%= String.valueOf(entry.getEntryId()) %>" />
</portlet:renderURL>

The <portlet:param> named mvcRenderCommandName declares the render URL. The <portlet:param> named entryId declares a variable to hold the portlet render URL object. Assign that variable to a UI component such, as a button or menu item. When the user triggers the UI component, the *MVCRenderCommand class that matches the render URL processes the render request and response.

What is it you want to do when a particular portlet render URL is invoked? By implementing the MVCRenderCommand interface and overriding its render method, you can perform your own logic to render JSPs. Some *MVCRenderCommands, such as the one below, always render the same JSP.

public class BlogsViewMVCRenderCommand implements MVCRenderCommand {

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

        return "/blogs/view.jsp";
    }

}

Other *MVCRenderCommands render JSPs based on conditions:

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

    try {
        ActionUtil.getEntry(renderRequest);
    }
    catch (Exception e) {
        if (e instanceof NoSuchEntryException ||
            e instanceof PrincipalException) {

            SessionErrors.add(renderRequest, e.getClass());

            return "/hello/error.jsp";
        }
        else {
            throw new PortletException(e);
        }
    }

    return "/hello/edit_entry.jsp";
}

In the method above, if no exceptions are thrown on invoking ActionUtil.getEntry, the method renders /hello/edit_entry.jsp. If a NoSuchEntryException is thrown, it renders /hello/error.jsp. If any other exception is thrown, the method re-throws it as a PortletException.

To respond to a particular render URL, your MVCRenderCommand must be an OSGi Declarative Services Component (e.g., annotated with @Component) that specifies these properties:

  • javax.portlet.name
  • mvc.command.name

Here’s an example of these two properties:

 "javax.portlet.name=" + HelloWorldPortletKeys.HELLO_WORLD,
 "mvc.command.name=/hello/edit_entry"

The portlet name, in this case, is defined by the constant HelloWorldPortletKeys.HELLO_WORLD. The mvc.command.name is set to /hello/edit_entry, which seems to indicate the MVC render command is related to editing entries–just a hunch.

The Component must also publish to the OSGi runtime as a MVCRenderCommand.class service. Here’s a basic Component that specifies the example properties and publishes itself as an MVCRenderCommand.class service:

@Component(
    immediate = true,
    property = {
       "javax.portlet.name=" + HelloWorldPortletKeys.HELLO_WORLD,
       "mvc.command.name=/hello/edit_entry"
    },
    service = MVCRenderCommand.class
)
public class EditEntryMVCRenderCommand implements MVCRenderCommand {
    ...
}

The mvc.command.name value /hello/edit_entry matches the value of portlet:renderURL’s mvcRenderCommand parameter shown earlier. That render URL invokes this *MVCRenderCommand class. In fact, any render URL of JSPs in this portlet (HelloWorldPortletKeys.HELLO_WORLD) whose mvcRenderCommand is /hello/edit_entry invokes this *MVCRenderCommand.

To make an MVCRenderCommand respond to multiple portlets, add them to your @Component as javax.portlet.name properties assigned to the portlet names. Likewise, to make it respond to multiple render URLs, add them as mvc.command.name properties. If you’re really feeling wild, you can specify multiple portlets and multiple command URLs in the same command component, like this:

@Component(
    immediate = true,
    property = {
       "javax.portlet.name=" + HelloWorldPortletKeys.HELLO_MY_WORLD,
       "javax.portlet.name=" + HelloWorldPortletKeys.HELLO_WORLD,
       "mvc.command.name=/hello/edit_super_entry",
       "mvc.command.name=/hello/edit_entry"
    },
    service = MVCRenderCommand.class
)

As you can see, MVC render commands are easy to implement and can respond to multiple command names for multiple portlets.

Creating an MVC Portlet

MVC Resource Command

MVC Action Command

MVC Command Overrides

« MVC Action CommandMVC Resource Command »
Was this article helpful?
0 out of 0 found this helpful