© The Author(s), under exclusive license to APress Media, LLC, part of Springer Nature 2022
A. Prakash, S. I. BashaHands- On Liferay DXPhttps://doi.org/10.1007/978-1-4842-8563-3_3

3. Portlet Module Development

Apoorva Prakash1   and Shaik Inthiyaz Basha2
(1)
BANGALORE, India
(2)
Nellore, AP, India
 

Portlets are the body and soul of any portal system and Liferay DXP is no different. Without a portlet, custom functionalities cannot be added to any portal. The Liferay portlet enables you to utilize features defined in the portlet specifications, and the cherries on top are the additional features Liferay provides to maximize the utilization of the framework. LiferayMVC is the most implemented portlet type and provides a lot of flexibility to developers. In this chapter, you get some hands-on experience with portlet development basics.

Introduction to Portlets

A portlet is nothing but a web component that is reusable and consists of a view (HTML/JSP page) and a controller (in Liferay, it’s called a controller class). A portlet can also have a model (in the form of classes), which is used when you connect the portlet to a database table. The model, view, and controller working together act as a web component, which can process a login to the controller and model classes and can send information to the portlet’s UI. However, you don’t always need a controller and model in a portlet; a static portlet can also render an HTML/JSP page.

Without portlets, you have minimal information on the page, i.e., the header, footer, and navigation menu. To show information on a page and to add dynamic capability, you need to add portlets. Administrators can add these portlets to a page by simple drag-and-drop techniques. You can see this with the sample layout shown in Figure 3-1.

A picture depict a layout view of a portal page. It includes the header of the portal marked above and at the end of the page, the portal menu and portlets 1, 2, and 3.

Figure 3-1

Portal page layout view

Figure 3-1 shows a sample page where the header and footer of the portal are static, and three portlets are added to the page. This is an example; you can have as many portlets as needed on a single page.

A single portlet can be added more than once; these are called instantiable portlets. Portlets can also communicate with each other. This mechanism is called inter-portlet communication (IPC). The display part of the portlets is highly customizable using CSS, and client-side dynamic functionalities can also be added using JavaScript and jQuery.

To summarize, portlets provide a means of presenting data from one or more sources in a manageable way. A portlet forms a section of the page to be rendered to the end user, making it very useful because several different portlets can be placed on a single page. The end user gets an immersive experience on a single page, whereas it is being rendered separately and from multiple sources.

This section has explained portlet basics; in the next section, you learn about portlet specifications.

Portlet Specifications

Portals and portlets have standards, which essentially define their behavior across all available and upcoming platforms. The first set of standards was introduced in 2003, called the Java Portlet Specification 1.0 or JSR-168. The second set of standards was published in 2008 and was referred to as the Java Portlet Specification 2.0, or JSR-286. The 2.0 specifications were processed on the foundation of JSR-168. JSR-286 ensured backward compatibility while introducing new features, such as inter-portlet communication (IPC), filters and listeners, and more. The latest Java Portlet Specification—3.0 (JSR-362)—was introduced in 2017. It continues the evolution and has added features such as resource dependencies and the Explicit Render state. We do not go into detail about these specifications as they are worthy of a separate book, but if you’re interested, you can read about them on the web in detail.

This section has explained the basics of portlet specifications; in the next section, you learn about the portlet lifecycle.

Portlet Lifecycle

As the name suggests, a lifecycle represents the transition of state of anything, and it is no different in the case of a portlet. A portlet instance changes various states, from initialization and destruction, and this is referred to as the portlet lifecycle. The portlet container manages the state transition, which in this case is Liferay DXP portal. Oftentimes, people confuse servlet lifecycles with servlets, but there are significant differences between them. A portlet needs a portlet container just like a servlet requires a servlet container. A servlet container has three states—init(), service(), and destroy(). Similarly, a portlet lifecycle has the following stages:
  • init(): This is the first stage of the portlet lifecycle and is invoked by the portlet container when it is needed to initialize the portlet. The init() method is used for the same. A portlet is initialized only when deployed in the portlet container; the container destroys the existing portlet (if any are available), and then init() is called to initialize it.

  • render(): Once the portlet is deployed and initialized, it is ready to be added it to the page. When it is added to the page, the default UI of the portlet is rendered for the end user. To render the default view (or any view per se), render() is invoked. Internally, this method will process the configured HTML/JSP and return the HTML content to the portlet for showing the UI to the end user.

  • processAction: This method is invoked when the Action URL is used in a portlet. As the name suggests, this is used to process any action for the end user, such as clicking a button or hyperlink, and generally, these actions are CRUD operations.

  • processEvent(): This method was introduced in the Portlet Specifications 2.0 (JSR 286). This is mainly used for inter-portlet communication, also introduced in the same JSR 286 standards. This method is invoked on an event raised by another portlet. You learn more about IPC in a later part of the book.

  • serveResource(): This method was also introduced in the Portlet Specifications 2.0 (JSR 286) and is used for AJAX request handling. It is invoked when a Liferay resource URL is processed.

  • destroy(): This is the last method of a portlet lifecycle and is executed when the portlet is undeployed from the portlet container. This method ensures that the portlet is removed from the portlet container and is no longer available on the portal so cannot be added to the page.

Figure 3-2 shows the portlet lifecycle graphically.

A flow diagram illustrate circuition of a portlet. It includes portlet, init, render, process action, process event, serve resource, and destroy.

Figure 3-2

Portlet lifecycle

Figure 3-3 shows the flow within a portlet and several types of requests.

A diagram illustrates request processing within a portlet. It includes processing of init, render, process action, resource action, and destroy

Figure 3-3

Different types of requests in a portlet

This section has explained the portlet lifecycle; in the next section, you learn about portlet modes and window states.

Portlet Modes and Window States

Another difference portlets have from servlets is portlet modes, which are distinct modes and window states.

Portlet Mode

The portlet mode of a portlet helps identify its function so that it can render different content based on the actions they perform. These portlets have dedicated features provided in different portlet modes to enhance accessibility. Each defined portlet mode must have a controller class and view. There are three main portlet modes:
  • View mode: This is the default mode of any portlet and is the most commonly used mode. This mode is used to access the portlet’s default/main functionality.

  • Edit mode: This is a portlet’s configuration mode used to customize the portlet's default view or behavior. You can use this mode when you want to let users perform actions in Edit mode so that customization can be done.

  • Help mode: This mode provides helpful information to the end users.

Liferay DXP also has a few additional window states—About, Config, Edit Default, Edit Guest, Print, and Preview Mode.

Window States

A portlet window state is a way to control the area of space that a portlet takes up on a page. An easy way to understand this is to consider how you can resize, maximize, minimize, and restore an Explorer window in Microsoft Windows, assuming each state can have a different display view attached to it. The JSR Portlet Specification Standard mentions three portlet states; however, Liferay provides additional window states for more flexibility:
  • Normal Window State: This is the default window state of a portlet and allows a portlet to be present with other visible portlets on the same page.

  • Maximized Window State: This window state is rendered; when it expands on a complete page of the portal, other portlets are not rendered, and only the portlet in a maximized window state is visible on the entire page.

  • Minimized Window State: This allows only the title bar of the portlet to be visible on the page.

This section has explained portlet modes and window states; in the next section, you learn the basics of Java standard portlets.

Java Standard Portlets

Java standard portlets are nothing but portlets made with JSR standards. These standard portlets are also referred to as generic portlets. The GenericPortlet class (javax.portlet.GenericPortlet) provides the default implementation for the portlet interface; an abstract class to be subclassed to create portlets. It is mandatory for a GenericPortlet subclass to use either an annotation or to override at least one method. Possible annotations or methods to override can be one of the following:
  • Annotation: @ProcessAction, @ProcessEvent, and @RenderMode

  • Methods to override: processAction, doView, doEdit, doHelp, init, and destroy

Listing 3-1 shows a Java standard portlet. It is extending GenericPortlet by overriding all its default methods. This example counts the render and action requests of a portlet with the help of two customized methods.
package com.apress.handsonliferay.portlet;
import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.EventRequest;
import javax.portlet.EventResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
public class HelloApressPortlet extends GenericPortlet {
        private static int myRenderCount = 0;
        private static int myActionCount = 0;
        @Override
        public void render(RenderRequest request, RenderResponse response) throws PortletException, IOException {
                synchronized (this) {
                        myRenderCount++;
                }
                response.getWriter().print("<form action="+response.createActionURL()+">"
                                +"<p> Show the Render Count <b>"+myRenderCount+"</b></p>"
                                +"<p> Show the Action Count <b>"+myActionCount+"</b></p>"
                                +"<input type='submit'/></form>");
        }
        @Override
        public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException {
                synchronized (this) {
                        myActionCount++;
                }
        }
        @Override
        public void processEvent(EventRequest request, EventResponse response) throws PortletException, IOException {
                // TODO Auto-generated method stub
                super.processEvent(request, response);
        }
        @Override
        protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
                // TODO Auto-generated method stub
                super.doView(request, response);
        }
        @Override
        protected void doEdit(RenderRequest request, RenderResponse response) throws PortletException, IOException {
                // TODO Auto-generated method stub
                super.doEdit(request, response);
        }
        @Override
        protected void doHelp(RenderRequest request, RenderResponse response) throws PortletException, IOException {
                // TODO Auto-generated method stub
                super.doHelp(request, response);
        }
        @Override
        public void init() throws PortletException {
                // TODO Auto-generated method stub
                super.init();
        }
}
Listing 3-1

HelloApressPortlet Class Extending GenericPortlet

In this example, if you observed the render method, you created an ActionURL using the createActionURL method. These URLs are called portlet URLs. In the example, a portlet URL will reference the instance of the portlet in the portal page. (There will be different PortletURLs even if the same portlet class is being used in more than one portlet.)

The portlet creates PortletURL objects that represent portlet URLs. The portlet itself can use one of two methods on the RenderResponse class to create these PortletURL objects. The portlet container is responsible for creating these URLs, as it parsed the portlet URL into parameters for the portlet request.
  • createActionURL: This method creates the action URL for forms or links that will be used to process the actions on the portlets.

  • createRenderURL: This method creates the render URLs for tasks that don't contain the portlet’s state modifications.

You can also add PortletURL to your content with no parameters, and you can set your parameters on a PortletURL by invoking the following method.
setParameter(name, value)

A Closer Look at HelloApressPortlet

You learned about the other methods in the portlet lifecycle section. Notice that there are different types of requests/responses in Listing 3-1. This section discusses each request and response in detail:
  • RenderRequest: Represents the request sent to the portlet to handle a render. The RenderRequest object is created by the portlet container and then is handed over to the portlet’s render() method as an argument.

  • RenderResponse: Defines an object to assist a portlet in sending a response to the portal. The RenderResponse object is created by the portlet container and then handed over to the portlet’s render() method as an argument.

  • ActionRequest: Represents the request sent to the portlet to handle an action. The ActionRequest object is created by the portlet container and then handed over to the portlet’s processAction() method as an argument.

  • ActionResponse: Represents the response for an action request. The ActionResponse object is created by the portlet container and then handed over to the portlet’s processAction() method as an argument.

  • EventRequest: Represents the request sent to the portlet to handle an event. It extends the PortletRequest interface to provide event request information to portlets.

  • EventResponse: Represents the portlet response to an event request.

In the portlet specifications, you have some predefined constants for the portlet level resource bundle. Here are the details about those constants:
  • javax.portlet.title: The title should be displayed in the title bar of this portlet. Only one title per locale is allowed. Note that this title may be overridden by the portal or programmatically by the portlet.

  • javax.portlet.short-title: A short version of the title that may be used for devices with limited display capabilities. Only one short title per locale is permitted.

  • javax.portlet.keywords: Keywords describing the functionality of the portlet. Portals that allow users to search for portlets based on keywords may use these keywords. Multiple keywords per locale are permitted, but must be separated by commas.

  • javax.portlet.description: Description of the portlet.

  • javax.portlet.display-name: Name under which this portlet is displayed, deployment time or to tools. The display name need not be unique.

  • javax.portlet.app.custom-portletmode.<,name>.decoration-name: Decoration name for the portlet managed custom portlet mode.

This section has explained the basics of Java standard portlets; in the next section, you learn about the Liferay portlet module.

Liferay Portlet Module (MVC Portlet)

Model View Controller (MVC) patterns are one of the most common patterns for developing Web applications worldwide. The Liferay MVC portlet is an implementation for developing Liferay DXP portlets. You should have an idea about how MVC works in a portlet, which was explained at the beginning of this chapter.

Liferay MVC has benefits compared to the standard MVC pattern, the greatest of which is that it’s lightweight, being an extension of GenericPortlet. It minimizes the effort of maintaining separate configuration files. In addition, it provides an empty portlet file and folder structure, saving effort in writing initialization code with predefined parameters as part of the boilerplate. You can also break down the controller class into separate commands depending on the phases. It abstracts a lot of complexity of portlet development and makes it easier for developers to implement features and operations.

Liferay MVC Layers and Modularity: In Liferay MVC, you have three different layers:
  • Model: This layer holds the application data and logic for manipulation.

  • View: This layer displays the data.

  • Controller: This layer acts as a middleman in the MVC pattern. It passes the data between the View and Model layers.

Liferay commonly uses three kinds of modules:
  • API: These modules define the interfaces.

  • Implementation: These modules provide concrete classes that implement interfaces.

  • Client: These modules consume the APIs.

Now you see how to create an example Liferay MVC portlet to better understand the Liferay MVC portlets.

Creating a Sample Liferay MVC Portlet

This section assumes that you already have a local setup for Liferay. If so, you can follow these steps:
  1. 1.

    Liferay workspace: Open your Liferay Developer Studio with a Liferay workspace. This example uses apress_ws as a Liferay DXP workspace. This workspace contains all the code from this book.

     
  2. 2.

    Template selection: Right-click the Liferay workspace as shown in Figure 3-4 and select Liferay Module Project as the module template.

     

A screenshot of Liferay Developer Studio. Apress underscore ws workspace to create new Liferay module project, by selecting new from the menu.

Figure 3-4

Steps to create a Liferay module project

In this example, we right-clicked the apress_ws workspace for module template selection.
  1. 3.

    Create a Liferay module project: After selecting a module template, you need to provide a project name. Name it apressMVC and then select Gradle for the build type and mvc-portlet for the project template name, as shown in Figure 3-5.

     

The image depicts steps to create apress MVC portlet using Developer Studio. It Includes tabs for the project name, build type, and template name

Figure 3-5

Create the apressMVC portlet using Developer Studio

Once you have selected Gradle for the build type and mvc-portlet for the template, click the Next button.
  1. 4.

    Create a portlet: Now, you need to provide your class name and package, or it will create one by default. Once you’re done, click the Finish button. This example uses ApressMVC for the controller name and com.apress.handsonliferay for the package name, as shown in Figure 3-6.

     

A screenshot of configuring the component class window with tabs for a component class name, and package name. The finish button is highlighted.

Figure 3-6

Configure component class

  1. 5.

    ApressMVC portlet: Once you click the Finish button, it will generate all required files for the Liferay MVC portlet with the default content from the template you selected.

     
  2. 6.

    Portlet path: This path will be created inside the modules folder of your workspace.

     
  1. 7.

    Portlet building: As shown in Figure 3-7, you can see the Gradle Tasks window in the Liferay Developer Studio, which will help build the Liferay MVC portlet. Click the Build task by choosing Gradle Tasks ➤ apress_ws ➤ Modules ➤ apressMVC ➤ Build ➤ Build, as shown in Figure 3-7. This will build your Gradle module.

     
  2. 8.

    Jar creation: Once you click the Deploy task from Gradle Tasks ➤ apress_ws ➤ Modules ➤ apressMVC ➤ Build ➤ Deploy, it will generate the JAR file and store it in the workspace directory location apress_ws ➤ bundles ➤ osgi ➤ modules ➤ *.jar.

     
  3. 9.

    Portlet deployment: You can copy this JAR file manually to the following server location to deploy the ApressMVC portlet in the Liferay Server: Liferay server folder ➤ deploy folder. For example:

     

A screenshot of the Gradle tasks window with build tab selected under apress underscore ws, modules, apress M V C. The left has a java program.

Figure 3-7

ApressMVC controller view in Developer Studio

liferay-dxp-7.4.13-ga1 ➤deploy
  1. 10.
    Successful deployment: You’ll see the following message on the Liferay Server Console once you deploy the module.
    2022-04-18 11:51:25.495 INFO [fileinstall-directory-watcher][BundleStartStopLogger:46] STARTED com.apress.handsonliferay_1.0.0 [1535]
     
  1. 11.

    Portlet view: Once you add the ApressMVC portlet to your page, you’ll see the output in Figure 3-8.

     

A screenshot of the Apress M V C portlet. It has text that reads, hello from Apress MVC.

Figure 3-8

Output of the ApressMVC portlet on a browser

Understanding the Liferay MVC Portlet Controller

In this section, you learn more about the Liferay MVC portlet controller, which will be available for every MVC portlet. Let’s look at the controller you created in the earlier example.

Note

All portlet customizations will be discussed based on the ApressMVC portlet created in the previous section.

The location of the controller is shown in Figure 3-9.

A screenshot of the pathway for Apress M V C portlet dot java. The right side has the corresponding java program for the portlet.

Figure 3-9

Controller location in Developer Studio

ApressMVCPortlet extends Liferay’s MVCPortlet class from com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet, which will help this class become the controller for the MVC pattern. In this controller, the most important section is @Component.

Let’s discuss @Component in detail, using the example shown in Listing 3-2.
@Component(
        immediate = true,
        property = {
                "com.liferay.portlet.display-category=category.sample",
                "com.liferay.portlet.header-portlet-css=/css/main.css",
                "com.liferay.portlet.instanceable=true",
                "javax.portlet.display-name=ApressMVC",
                "javax.portlet.init-param.template-path=/",
                "javax.portlet.init-param.view-template=/view.jsp",
                "javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
                "javax.portlet.resource-bundle=content.Language",
                "javax.portlet.security-role-ref=power-user,user"
        },
        service = Portlet.class )
Listing 3-2

Component Section in Controller

immediate = true declares this component and it must be immediately activated or should be delayed.

property = { defines the properties for this component.

In the @Component section, properties for Liferay and default portlet properties of the Java portlet have been defined:
  • com.liferay.portlet.display-category=category.sample is the category to show the portlet

  • com.liferay.portlet.header-portlet-css=/css/main.css is the path of the CSS files

  • com.liferay.portlet.instanceable=true is the instanceable configuration

  • javax.portlet.display-name=ApressMVC displays the name of the portlet

  • javax.portlet.init-param.template-path=/ is the template path

  • javax.portlet.init-param.view-template=/view.jsp is the path for the View modules

  • javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC is the portlet name

  • javax.portlet.resource-bundle=content.Language is the locale configuration

  • javax.portlet.security-role-ref=power-user,user contains the roles for the portlet

service = defines the types under which to register this component as a service.

Understanding the Different URLs in the Liferay MVC Portlet

In the Liferay MVC portlet, you have three types of URLs:
  • Render URL

  • Action URL

  • Resource URL

Each URL has its own features; let’s discuss them in detail.

Render URL

If you want users to access different portlet views, you must implement navigation to them, and this can be achieved with the help of Render URLs. Figure 3-10 shows the RenderURL created in the ApressMVC portlet.

A screenshot of the Apress M V C portlet pathway with Apress underscore ws that leads to modules then apress M V C, meta I N F, and resources.

Figure 3-10

JSP file path for apressMVC Portlet

In the ApressMVC portlet, by default, two JSPs (init.jsp and view.jsp) are created while creating the ApressMVC portlet; you will create one more JSP called renderexample.jsp to perform navigation in the same path.

  1. 1.

    The init.jsp page is created by default. The MVC portlet template will have all tag libraries declared that are required for the Liferay MVC portlet, as shown in Listing 3-3.

     
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ taglib uri="http://liferay.com/tld/aui" prefix="aui" %>
<%@ taglib uri="http://liferay.com/tld/portlet" prefix="liferay-portlet" %>
<%@ taglib uri="http://liferay.com/tld/theme" prefix="liferay-theme" %>
<%@ taglib uri="http://liferay.com/tld/ui" prefix="liferay-ui" %>
<liferay-theme:defineObjects />
<portlet:defineObjects />
Listing 3-3

apressMVC Portlet init.jsp

  1. 2.

    The view.jsp page is created by default by the MVC portlet template and it includes init.jsp to include the tag libraries. You wrote the logic for creating a Render URL, which will redirect to the render example JSP page using the following tag (see Listing 3-4).

     
<portlet:renderURL var="renderURL">
        <portlet:param name="mvcPath" value="/renderexample.jsp" />
</portlet:renderURL>
<%@ include file="/init.jsp" %>
<div style="padding: 15px">
        <h1><div style="color:blue"> Portlet URL's Section </div></h1>
        <portlet:renderURL var="renderURL">
                <portlet:param name="mvcPath" value="/renderexample.jsp" />
        </portlet:renderURL>
        <portlet:actionURL name="firstAction" var="actionURL" />
        <table>
          <tr>
            <th>Render URL</th>
            <th>Action URL</th>
            <th>Resource URL</th>
          </tr>
          <tr>
            <td><h4><a href="<%= renderURL %>">Go to Render Page</a></h4></td>
            <td></td>
            <td></td>
          </tr>
        </table>
</div>
<style>
        table{
          border: 2px solid green;
          border-collapse: collapse;
        }
        th, td {
          border: 2px dotted blue;
          border-collapse: collapse;
          padding: 10px;
        }
Listing 3-4

JSP Code Snippet for Render URL

  1. 3.

    You will create the renderexample.jsp page in the same path, as shown in Figure 3-10. This page also includes init.jsp to include the tag libraries (see Listing 3-5).

     
<portlet:renderURL var="landingURL">
        <portlet:param name="mvcPath" value="/view.jsp" />
</portlet:renderURL>
<%@ include file="/init.jsp" %>
<portlet:renderURL var="landingURL">
        <portlet:param name="mvcPath" value="/view.jsp" />
</portlet:renderURL>
<div style="padding: 15px">
        <div style="color:green"><h1>Rendering Page of Apress MVC Portlet</h1></div>
        <p>
                <a href="<%= landingURL %>"><h3>Go to Landing Page</h3></a>
        </p>
</div>
Listing 3-5

apressMVC Portlet renderexample.jsp

  1. 4.

    The ApressMVCPortlet.java class acts as a controller, created by the default MVC portlet template. In the controller class, you will write the logic in Listing 3-6 for rendering. The render method will be overridden to use the path you click.

     
package com.apress.handsonliferay.portlet;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCPortlet;
import org.osgi.service.component.annotations.Component;
/**
 * @author Inthiyaz
 */
@Component(
        immediate = true,
        property = {
                "com.liferay.portlet.display-category=category.sample",
                "com.liferay.portlet.header-portlet-css=/css/main.css",
                "com.liferay.portlet.instanceable=true",
                "javax.portlet.display-name=ApressMVC",
                "javax.portlet.init-param.template-path=/",
                "javax.portlet.init-param.view-template=/view.jsp",
                "javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
                "javax.portlet.resource-bundle=content.Language",
                "javax.portlet.security-role-ref=power-user,user"
        },
        service = Portlet.class
)
public class ApressMVCPortlet extends MVCPortlet {
        @Override
        public void render(RenderRequest renderRequest, RenderResponse renderResponse)
                        throws IOException, PortletException {
                // TODO Auto-generated method stub
                String mvcPath = renderRequest.getParameter("mvcPath");
                System.out.println("MVC Path "+mvcPath);
      }
}
Listing 3-6

apressMVC Portlet Controller with Render Method

  1. 5.
    Once you deploy the ApressMVC portlet, you can see the screens shown in Figures 3-11 and 3-12 as output. From Screen1, if you click Go to Render Page, it will show Screen2. If you click Go to Landing Page on Screen2, it will redirect to Screen1.

    A screenshot of the landing page of Apress M V C portlet. The portlet U R L section has render U R L, action U R L, and resource U R L on screen 1.

    Figure 3-11

    Output Screen1 for RenderURL execution

    A screenshot of the rendering page of apress M V C portlet on screen 2. It reads, go to a landing page.

    Figure 3-12

    Output Screen2 for RenderURL execution

     

This example will help you navigate between Screen1 and Screen2 with the help of the Liferay MVC Portlet Render URL.

Action URL

This URL binds your portlets’ action-handling methods to frontend/UI components using the portlet action URL. The following example helps elucidate the Action URL created in the ApressMVC portlet.

  1. 1.

    In the view.jsp file, you create the Action URLs in different ways available in Liferay MVC portlet, and these URL-related methods will be created in the controller of the ApressMVC portlet. The <portlet:actionURL> tag creates a URL, as shown in Listing 3-7.

     
<%@ include file="/init.jsp" %>
<div style="padding: 15px">
        <h1><div style="color:blue"> Portlet URL's Section </div></h1>
        <portlet:renderURL var="renderURL">
                <portlet:param name="mvcPath" value="/renderexample.jsp" />
        </portlet:renderURL>
        <portlet:actionURL name="firstAction" var="actionURL" />
        <table>
          <tr>
            <th>Render URL</th>
            <th>Action URL</th>
            <th>Resource URL</th>
          </tr>
          <tr>
            <td><h4><a href="<%= renderURL %>">Go to Render Page</a></h4></td>
            <td><h4><a href="<%= actionURL %>"><div style="color:green">Test your First Action</div></a></h4>
                <h4><a href="<portlet:actionURL name="secondAction" />">Test your Second Action</a></h4>
                <h4><a href="<portlet:actionURL><portlet:param name="javax.portlet.action" value="nameForMoreActionsMethod" />
                        </portlet:actionURL>">
                                <div style="color:red">Do Something More Actions</div></a>
                        </h4></td>
            <td></td>
          </tr>
        </table>
</div>
<style>
        table{
          border: 2px solid green;
          border-collapse: collapse;
        }
        th, td {
          border: 2px dotted blue;
          border-collapse: collapse;
          padding: 10px;
        }
Listing 3-7

JSP Code Snippet for Action URL

  1. 2.

    In the ApressMVCPortlet.java controller class, you write the following logic for all action methods that are created in the view.jsp file.To execute the action method, the name parameter value of <portlet:actionURL> in the JSP page and the action method name in ApressMVCPortlet should be the same, as shown here:

     
name="firstAction" public void firstAction(
Listing 3-8 shows an example of this in action.
import org.osgi.service.component.annotations.Component;
/**
 * @author Inthiyaz
 */
@Component(
        immediate = true,
        property = {
                "com.liferay.portlet.display-category=category.sample",
                "com.liferay.portlet.header-portlet-css=/css/main.css",
                "com.liferay.portlet.instanceable=true",
                "javax.portlet.display-name=ApressMVC",
                "javax.portlet.init-param.template-path=/",
                "javax.portlet.init-param.view-template=/view.jsp",
                "javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
                "javax.portlet.resource-bundle=content.Language",
                "javax.portlet.security-role-ref=power-user,user"
        },
        service = Portlet.class
)
public class ApressMVCPortlet extends MVCPortlet {
        public void firstAction(
                        ActionRequest actionRequest, ActionResponse actionResponse) {
                System.out.println("Invoking first Action");
        }
        public void secondAction(
                        ActionRequest actionRequest, ActionResponse actionResponse) {
                System.out.println("Invoking second Action");
        }
        @ProcessAction(name = "nameForMoreActionsMethod")
        public void moreActionsMethod(
                        ActionRequest actionRequest, ActionResponse actionResponse) {
                System.out.println("Invoking nameForMoreActionsMethod ");
        }
}
Listing 3-8

apressMVC Portlet Controller Code Snippet for Action Method

  1. 3.
    Once you deploy the ApressMVC portlet, you will see the screen in Figure 3-13 as output. If you click any action URL that you created in JSP, you’ll see a message in the Liferay Server Console.

    A screenshot of the landing page of Apress M V C portlet. The action U R L reads, test your action first, test your second action, and do something more actions.

    Figure 3-13

    Output screen for Action URL

     

Resource URL

This URL performs tasks without refreshing your page. The best example for this URL is the auto-complete feature in Google search (it will fetch the matching result while typing itself). The following example explains the ResourceURL, created in the ApressMVC portlet. In this example, try downloading a sample file called apressMVCResource.csv using the Resource function.

  1. 1.

    In the View.jsp page, you are creating the ResourceURL to call the Resource method of the controller. <portlet:ResourceURL> creates the resource URL, which calls the serveResource method of the controller. Listing 3-9 illustrates this process.

     
<%@ include file="/init.jsp" %>
<div style="padding: 15px">
        <h1><div style="color:blue"> Portlet URL's Section </div></h1>
        <portlet:renderURL var="renderURL">
                <portlet:param name="mvcPath" value="/renderexample.jsp" />
        </portlet:renderURL>
        <portlet:actionURL name="firstAction" var="actionURL" />
        <table>
          <tr>
            <th>Render URL</th>
            <th>Action URL</th>
            <th>Resource URL</th>
          </tr>
          <tr>
            <td><h4><a href="<%= renderURL %>">Go to Render Page</a></h4></td>
            <td><h4><a href="<%= actionURL %>"><div style="color:green">Test your First Action</div></a></h4>
                <h4><a href="<portlet:actionURL name="secondAction" />">Test your Second Action</a></h4>
                <h4><a href="<portlet:actionURL><portlet:param name="javax.portlet.action" value="nameForMoreActionsMethod" />
                        </portlet:actionURL>">
                                <div style="color:red">Do Something More Actions</div></a>
                        </h4></td>
            <td><h4><a href="<portlet:resourceURL id="resourceURL" />"><div style="color:green"> Resource URL</div></a></h4></td>
          </tr>
        </table>
</div>
<style>
        table{
          border: 2px solid green;
          border-collapse: collapse;
        }
        th, td {
          border: 2px dotted blue;
          border-collapse: collapse;
          padding: 10px;
        }
Listing 3-9

JSP Code Snippet for the Resource URL

  1. 2.

    In the ApressMVCPortlet.java controller, you are overriding the serveResource method to write the logic to download a file called apressMVCResource.csv at every click of the ResourceURL from the JSP page. See Listing 3-10.

     
import org.osgi.service.component.annotations.Component;
/**
 * @author Inthiyaz
 */
@Component(
        immediate = true,
        property = {
                "com.liferay.portlet.display-category=category.sample",
                "com.liferay.portlet.header-portlet-css=/css/main.css",
                "com.liferay.portlet.instanceable=true",
                "javax.portlet.display-name=ApressMVC",
                "javax.portlet.init-param.template-path=/",
                "javax.portlet.init-param.view-template=/view.jsp",
                "javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
                "javax.portlet.resource-bundle=content.Language",
                "javax.portlet.security-role-ref=power-user,user"
        },
        service = Portlet.class
)
public class ApressMVCPortlet extends MVCPortlet {
        @Override
        public void serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse)
                        throws IOException, PortletException {
                // TODO Auto-generated method stub
                        System.out.println("Invoking Resource Method ");
                        resourceResponse.setContentType("text/csv");
                        resourceResponse.addProperty(HttpHeaders.CONTENT_DISPOSITION,
                      "attachment;filename=apressMVCResource.csv");
                        OutputStream out = resourceResponse.getPortletOutputStream();
                        out.flush();
                        System.out.println("Resource File Downloaded Successfully ");
        }
}
Listing 3-10

apressMVC Portlet Controller Code Snippet for Resource Method

  1. 3.
    Once you deploy the ApressMVC portlet, you can see the screen shown in Figure 3-14 as output. If you click the Resource URL link, it will download the file called resourcefile.csv, as shown in Figure 3-14.

    A screenshot of the landing page of Apress M V C portlet. The action U R L reads, test your action first, test your second action, and do something more actions.

    Figure 3-14

    Output screen for ResourceURL

     

Understanding Different Commands in the Liferay MVC Portlet

This section explains the different commands available in Liferay MVC portlets.
  • MVC Render command

  • MVC Action command

  • MVC Resource command

Each command has its own features; let’s discuss each MVC command in detail.

The MVC Render Command

These classes handle which page to render, similar to other render methods. They are invoked by the MVCPortlet render URLs. If you want to build simple logic, you can implement all of it in your portlet class. If you want to build complex logic, use the MVC Render commands. The following examples illustrate this concept. You’ll be adding them to the ApressMVC portlet.

  1. 1.

    In the View.jsp page, you create the RenderURL to call the MVC Render command Class. The following tag is used to achieve that:

     
<portlet:renderURL var="renderCommandURL">
<portlet:param name="mvcRenderCommandName" value="/apressmvcrendercommand" />
</portlet:renderURL>
Listing 3-11 shows this process in action.
<%@ include file="/init.jsp" %>
<div style="padding: 15px; color:green"><h1>Landing Page of Apress MVC Portlet</h1></div>
<div style="padding: 15px">
        <h1><div style="color:blue"> MVC Command's Section </div></h1>
        <portlet:renderURL var="renderCommandURL">
                <portlet:param name="mvcRenderCommandName" value="/apressmvcrendercommand" />
        </portlet:renderURL>
        <table>
          <tr>
            <th>MVC Render Command</th>
            <th>MVC Action Command</th>
            <th>MVC Resource Command</th>
          </tr>
          <tr>
            <td><h3><a href="<%= renderCommandURL %>">Go to Render Command Page</a></h3></td>
            <td>
            </td>
            <td>
            </td>
          </tr>
        </table>
</div>
Listing 3-11

JSP Code Snippet with Render Command URL

  1. 2.

    The apressmvcrendercommand.jsp file redirects from the MVC Render Command Class’s render method whenever you click Go to Render Command Page from view.jsp. This JSP is created in the same path as view.jsp.

     
<%@ include file="/init.jsp" %>
<h1>Apress MVC Render Command Page</h1>
  1. 3.

    The ApressMVCRenderCommand.java class implements the logic for the MVC Render command. It will implement the MVCRenderCommand interface (com.liferay.portal.kernel.portlet.bridges.mvc.MVCRenderCommand) to achieve the MVC Render command features. This class is created in the path of ApressMVCPortlet.java. The following points are mandatory while implementing and will come in the Component section.

     
  • service = MVCRenderCommand.class: The Component section

  • "Javax.portlet.name=" + apressmvcportletkeys.APRESSMVC: The portlet name must be the same for your Render command class and MVC controller.

  • mvc.command.name=/apressmvcrendercommand: This property value should be the same as your JSP <portlet:param name="mvcRenderCommandName" value="/apressmvcrendercommand" />.

Listing 3-12 shows an example in action.
package com.apress.handsonliferay.portlet;
import com.apress.handsonliferay.constants.ApressMVCPortletKeys;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCRenderCommand;
import javax.portlet.PortletException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.osgi.service.component.annotations.Component;
/**
 * @author Inthiyaz
 */
@Component(
        immediate = true,
        property = {
                "javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
                "mvc.command.name=/apressmvcrendercommand"
        },
        service = MVCRenderCommand.class
)
public class ApressMVCRenderCommand implements MVCRenderCommand {
        @Override
        public String render(RenderRequest renderRequest, RenderResponse renderResponse) throws PortletException {
                System.out.println("Invoking Render Command Method ");
                return "/apressmvcrendercommand.jsp";
        }
}
Listing 3-12

ApressMVCRenderCommand Class for the Render Command URL

  1. 4.
    Figure 3-15 shows the first screen that will display after deploying the ApressMVC portlet. If you click the Go to Render Command Page link from view.jsp, it will redirect to the screen shown in Figure 3-16 with the help of the Render method from the ApressMVCRenderCommand class.

    A screenshot of the landing page of Apress M V C portlet. It has M V C command's section and portlet U R L's section.

    Figure 3-15

    Output screen with a Render Command link

    A screenshot of the Apress M V C render command page output window.

    Figure 3-16

    Output screen for Render Command page

     

MVC Action Command

This command handles actions as separate classes. With the help of Action commands, you can organize action logic in MVCPortlet that has many actions. These action URLs in the portlet’s JSPs invoke a designated MVC Action command class. This section discusses in detail the MVC Action commands with an example.

  1. 1.

    In the View.jsp page, you create the Action URL to call the MVC Action command class by using the following tag:

     
<portlet:actionURL name="/apressmvcactioncommand" />
<%@ include file="/init.jsp" %>
<div style="padding: 15px; color:green"><h1>Landing Page of Apress MVC Portlet</h1></div>
<div style="padding: 15px">
        <h1><div style="color:blue"> MVC Command's Section </div></h1>
        <portlet:renderURL var="renderCommandURL">
                <portlet:param name="mvcRenderCommandName" value="/apressmvcrendercommand" />
        </portlet:renderURL>
        <table>
          <tr>
            <th>MVC Render Command</th>
            <th>MVC Action Command</th>
            <th>MVC Resource Command</th>
          </tr>
          <tr>
            <td><h3><a href="<%= renderCommandURL %>">Go to Render Command Page</a></h3></td>
            <td>
                <h3><a href="<portlet:actionURL name="/apressmvcactioncommand" />">
                <div style="color:green"> Go to Action Command Class</div></a>
                </h3>
            </td>
            <td>
            </td>
          </tr>
        </table>
</div>
Listing 3-13

JSP Code Snippet with ActionCommand URL

  1. 2.

    The ApressMVCActionCommand.java class implements the logic for the MVC Action command to execute the action methods. It will implement the MVCActionCommand interface, and this class is created in the ApressMVCPortlet.java path. The following points are mandatory while implementing and will be in the Component section.

     
service = MVCActionCommand.class
"javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,

The portlet name must be the same as your Action Command class and MVC Controller.

The mvc.command.name=/apressmvcactioncommand command name from the Action command class must match the actionURL param of JSP <portlet:actionURL name="/apressmvcactioncommand" />. See Listing 3-14.
package com.apress.handsonliferay.portlet;
import com.apress.handsonliferay.constants.ApressMVCPortletKeys;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCActionCommand;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import org.osgi.service.component.annotations.Component;
/**
 * @author Inthiyaz
 */
@Component(
        immediate = true,
        property = {
                "javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
                "mvc.command.name=/apressmvcactioncommand"
        },
        service = MVCActionCommand.class
)
public class ApressMVCActionCommand implements MVCActionCommand {
        @Override
        public boolean processAction(ActionRequest actionRequest, ActionResponse actionResponse) throws PortletException {
                // TODO Auto-generated method stub
                System.out.println("Invoking Action Command Method ");
                return false;
        }
}
Listing 3-14

ApressMVCActionCommand Class for Action Command URL

  1. 3.

    Figure 3-17 displays what you see after deploying the ApressMVC portlet. If you click the Go to Action command class, it will show the “Invoking Action Command Method” message in your Liferay Console.

     

A screenshot of the landing page of Apress M V C portlet. It has M V C command's section with M V C action command link and portlet U R L's section.

Figure 3-17

Output screen with Action Command link

MVC Resource Command

MVC Resource Command classes fetch resources such as XML, documents, images, or any other resources from a DXP/portal instance without triggering actions or renders. Requests or portlet resource URLs invoke MVC Resource commands. This section discusses in detail the MVC Resource commands with an example.

  1. 1.

    In the View.jsp page, you create the ResourceURL to call the MVC Resource command class.

     
<portlet:resourceURL id="/apressmvcresourcecommand" />
<%@ include file="/init.jsp" %>
<div style="padding: 15px; color:green"><h1>Landing Page of Apress MVC Portlet</h1></div>
<div style="padding: 15px">
        <h1><div style="color:blue"> MVC Command's Section </div></h1>
        <portlet:renderURL var="renderCommandURL">
                <portlet:param name="mvcRenderCommandName" value="/apressmvcrendercommand" />
        </portlet:renderURL>
        <table>
          <tr>
            <th>MVC Render Command</th>
            <th>MVC Action Command</th>
            <th>MVC Resource Command</th>
          </tr>
          <tr>
            <td><h3><a href="<%= renderCommandURL %>">Go to Render Command Page</a></h3></td>
            <td>
                <h3><a href="<portlet:actionURL name="/apressmvcactioncommand" />">
                <div style="color:green"> Go to Action Command Class</div></a>
                </h3>
            </td>
            <td>
                <h3><a href="<portlet:resourceURL id="/apressmvcresourcecommand" />">
                <div style="color:red"> Resource Command URL to Download File </div></a>
                </h3>
            </td>
          </tr>
        </table>
</div>
Listing 3-15

JSP Code Snippet with Resource Command URL

  1. 2.

    The ApressMVCResourceCommand.java class implements the logic for the MVC Resource command to execute the file download. It will implement the MVCResourceCommand interface, and this class is created in the ApressMVCPortlet.java path. The following points are mandatory while implementing and will come in the Component section.

     
service = MVCResourceCommand.class
"javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
  • The portlet name must be the same as your resource command class and MVC controller.

  • mvc.command.name=/apressmvcresourcecommand command name from the resource command class must match the resourceURL param of JSP <portlet:actionURL name="/apressmvcresourcecommand" />

package com.apress.handsonliferay.portlet;
import com.apress.handsonliferay.constants.ApressMVCPortletKeys;
import com.liferay.portal.kernel.portlet.bridges.mvc.MVCResourceCommand;
import com.liferay.portal.kernel.servlet.HttpHeaders;
import java.io.IOException;
import java.io.OutputStream;
import javax.portlet.PortletException;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import org.osgi.service.component.annotations.Component;
/**
 * @author Inthiyaz
 */
@Component(
        immediate = true,
        property = {
                "javax.portlet.name=" + ApressMVCPortletKeys.APRESSMVC,
                "mvc.command.name=/apressmvcresourcecommand"
        },
        service = MVCResourceCommand.class
)
public class ApressMVCResourceCommand implements MVCResourceCommand {
        @Override
        public boolean serveResource(ResourceRequest resourceRequest, ResourceResponse resourceResponse)
                        throws PortletException {
                System.out.println("Invoking Resource Method ");
                  resourceResponse.setContentType("text/csv");
                   ;resourceResponse.addProperty(HttpHeaders.CONTENT_DISPOSITION,
                      "attachment;filename=apressMVCResourceCommandFile.csv");
                   ;OutputStream out;
                try {
                        out = resourceResponse.getPortletOutputStream();
                        out.flush();
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                return false;
        }
}
Listing 3-16

ApressMVCResourceCommand with MVC Resource Command Code Snippet

  1. 3.

    If you click the Resource command URL to download a file after deploying the ApressMVC portlet, it will download a file called apressMVCResourceCommandFile.csv, as shown in Figure 3-18.

     

A screenshot of the landing page of Apress M V C portlet. It has M V C command's section with resource command U R L, and portlet U R L's section.

Figure 3-18

Output screen with resource link and file download

Implementing Window State

You have already read about the Window state in a previous section of this chapter. You will now try to implement it in your ApressMVC portlet by following these steps.

  1. 1.

    In the View.jsp page, you are creating the all window state URLs to execute; see Listing 3-17.

     
<%@ include file="/init.jsp" %>
<div style="padding: 15px; color:green"><h1>Landing Page of Apress MVC Portlet</h1></div>
<div style="padding: 15px">
        <h1><div style="color:blue"> Portlet Mode example Section </div></h1>
        <%@page import="com.liferay.portal.kernel.portlet.LiferayWindowState"%>
        <portlet:renderURL var="normalWindowURL" windowState="<%=LiferayWindowState.NORMAL.toString()%>"/>
        <portlet:renderURL var="maximizedWindowURL" windowState="<%=LiferayWindowState.MAXIMIZED.toString()%>"/>
        <portlet:renderURL var="minimizedWindowURL" windowState="<%=LiferayWindowState.MINIMIZED.toString()%>"/>
        <portlet:renderURL var="popupWindowURL" windowState="<%=LiferayWindowState.POP_UP.toString()%>"/>
        <portlet:renderURL var="exclusiveWindowURL" windowState="<%=LiferayWindowState.EXCLUSIVE.toString()%>"/>
        <table>
          <tr>
            <th>Normal Window</th>
            <th>Maximized Window</th>
            <th>Minimized Window</th>
            <th>Pop Up Window</th>
            <th>Exclusive View Window</th>
          </tr>
          <tr>
            <td><a href="<%=normalWindowURL.toString() %>">normalWindowURL now</a></td>
            <td><a href="<%=maximizedWindowURL.toString() %>">maximizedWindowURL now</a></td>
            <td><a href="<%=minimizedWindowURL.toString() %>">minimizedWindowURL now</a></td>
            <td><a href="<%=popupWindowURL.toString() %>">popupWindowURL now</a></td>
            <td><a href="<%=exclusiveWindowURL.toString() %>">exclusiveWindowURL now</a></td>
          </tr>
        </table>
</div>
Listing 3-17

JSP Code Snippet for Window Modes

  1. 2.

    Figure 3-19 shows the output screen that will display after you deploy the ApressMVC portlet with window states to the Liferay Server.

     

A screenshot of Apress M V C portlet&#x2019;s landing page with portlet mode example,command section. It includes with normal, maximized, minimized, pop-up

Figure 3-19

Output screen with a different Window mode link

After every click, it will perform some actions.

This section has explained the Liferay portlet module; in the next section, you are introduced to other portlet modules that can be created in Liferay DXP.

Introduction to Other Portlet Modules

The Spring MVC Portlet

The next most popular portlet type in portlet development is the Spring MVC portlet. Liferay allows you to create/deploy portlets with the Spring framework. Liferay provides development standards, and any module that follows the standard is deployable in Liferay. This does not mean that other Liferay features, such as service builder, externalization, and so on, become useless if you are not using the Liferay MVC portlet. They are also usable in the Spring MVC portlet because it is essentially just a change in the application layer. PortletMVC4Spring is a way to develop portlets using the Spring Framework and the Model View Controller (MVC) pattern.

A significant difference between the Liferay MVC Portlet and the Spring MVC Portlet is that, when built for deployment, a Spring MVC module generates a WAR file instead of a JAR file. This is because it has become a Java EE-style web application. Thanks to Liferay for using OSGi WAB standards (Web Application Bundler) for deployment, you can deploy this WAR on the Liferay Server.

Liferay Soy Portlet

Liferay Soy portlet is essentially a Liferay MVC portlet with the added functionality of using Soy templates. Soy templates make it easy to create complex frontends.

JSF Portlet

Liferay provides support for JavaServer Faces standards. This is made possible with the help of the Liferay Faces Bridge. Liferay has created a separate project for supporting JSF named Liferay Faces. This Liferay Faces Bridge allows for the deployment of JSF applications, and the most significant advantage is that you need not write custom Java code. This is made possible with the support of JSF 2.0 standards within Liferay DXP. Other portlets supported by Liferay faces include Liferay Faces Alloy and Liferay Faces Portal.

Bean Portlet

Contexts and Dependency Injection (CDI) is part of the Portlet Specification 3.0, and Liferay supports this with the help of the Bean portlet. The Bean portlet allows custom CDI such as @PortletSessionScoped, @PortletRequestScoped, and @RenderStateScoped. CDI enables portlet classes instantiated via a CDI container, enabling dependency injection along with scope annotations of the portlet classes. Bean portlets are essentially just plain old Java objects (POJOs); descriptors mark them as portlets.

This section introduced different types of portlets; in the next section, you see the Gogo shell in action.

Gogo Shell in Action

From the explanation and example in the previous chapter, you know what the Gogo shell is and what it is capable of. Now you learn how you can use it in detail. Follows these steps to use the Gogo shell in Telnet.

To connect to the Gogo shell using Telnet, make sure:
  • If you are using the Windows operating system, the Telnet feature is enabled in the Add/Remove programs section.

  • If you are using Linux, Telnet should be installed.

To connect the Gogo shell using Telnet, you must also add the following properties to the portal-ext.properties file.
include-and-override=portal-developer.properties
You must use the following command:
telnet localhost 11311
where 11311 is the port number (default), which can be modified in portal-ext.properties using the following property:
module.framework.properties.osgi.console=11312
Once you execute this, you will get the screen with the g! prompt shown in Figure 3-20. Whoa! Welcome to the Gogo shell; you can execute commands now.

A screenshot of a command window with text that reads, welcome to apache Felix gogo, and a g prompt.

Figure 3-20

Gogo shell command prompt screen

Let’s execute a command. Type lb and press Enter. You will see the list of available bundles and their states, as shown in Figure 3-21. The lb stands for list bundles. You may get 1,400+ bundles listed with this command.

A screenshot of a command window with text, welcome to apache Felix gogo, and a g prompt followed by l b. The next line has all the listings.

Figure 3-21

Output of the lb command

Let’s try to start and stop a bundle using the start and stop commands. You can see in Figure 3-22 how to start and stop bundles from the Gogo shell prompt and how these commands reflect in the server logs in Figure 3-23.

A screenshot of a command window with a g prompt and l b apress. The next line reads start level 20, followed by 2 listings, and stop apress M V C.

Figure 3-22

Output of the lb apress command

A screenshot of the output window. Line 1 represents the command for stop and line 2 represents the command for start.

Figure 3-23

Output of the server logs of the start and stop commands

To exit the Gogo shell, use the disconnect command. Quick tip: If you use Ctrl+C (Break), close, and exit either of the commands, it will shut down the OSGi container, which means your application server will be down. (See Figure 3-24.)

A screenshot of a command window with commands, stop apress M V C, start apress M V C, and disconnect. The next line reads connection to host lost.

Figure 3-24

Gogo shell command output for the start and stop commands

Gogo Shell from the Liferay Control Panel

To access the Gogo shell from the control panel, choose Control Panel ➤ System ➤ Gogo Shell (see Figure 3-25).

The rest of the process remains the same as explained in the Gogo shell with Telnet section.

A screenshot of the gogo shell command window with a command l b apress. The output reads, start level 20, followed by 2 listings.

Figure 3-25

Liferay Server Gogo shell command prompt

Gogo Shell from the Blade CLI

Individual commands can be executed from the Blade command-line interface. You must prepend blade sh to the Gogo shell commands as follows:
blade sh [Gogo shell command]
The rest of the process remains exactly the same as explained in the Gogo shell with the Telnet section. (See Figure 3-26.)

A screenshot of the command window with a command blade s h, I b apress. The output reads, start level 20, followed by 2 listings.

Figure 3-26

Output of the blade sh lb apress command

Summary

Liferay DXP portlets enable you to utilize all the features defined in the portlet specifications. The cherries on top are the additional features Liferay provides to maximize the utilization of the framework. Obviously, because the additional Liferay features are Liferay specific, not generic, these portlets cannot be used on any other portlet containers. It does not mean that these additional features do not follow the portlet standards; Liferay has added features such as APIs to improve development with less effort. You learned about these additional portlet modes in this chapter. Another example is the MVC Portlet implementing standard called MVC Pattern, which simplifies portlet development. Generic portlets are also easily deployable on the Liferay DXP portal.

In the next chapter, you learn about a few advanced Liferay concepts.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset