create resource URL programmatically in Portlet class and JSP

Liferay provides PortletURLFactoryUtil class to create resource URL programmatically (Java API). You can call serveResource method by such resource URL of same portlet or different portlet kept on different page

Liferay provides the facility to create resource URL programmatically through Java API. This is useful when you want to call serveResource() method of portlet B from portlet A or even the same portlet.

Resource URL can be created in JSP by portlet tag. Such resource URL can point to serveResource method (or serve resource phase) of the same portlet only.

If you want to call serveResource method of a different portlet, you need to create a resource URL either through liferay-portlet:resourceURL tag or programmatically by Java API.

In this article, I will be showing you how to create resource URL programmatically through Java API.

resource URL programmatically

 

You need to create a LiferayMVC portlet. To make it simple, I have created the MVC portlet with Maven. Give portlet class as com.opensource.techblog.portlet.ResourceURLByJavaAPIPortlet. The project structure would look like the below screenshot.

resource URL programmatically - project structure

Create resource URL programmatically.

There are two places where you can create resource URL programmatically with Java API.

Place 1: resource URL by PortletURLFactoryUtil in Portlet class

PortletURLFactoryUtil class (provided by Liferay) is used to create various portlet URLs (like render URL, action URL, resource URL, etc.). In this article, we will use this class to create resource URL programmatically.

Add the following code in ResourceURLByJavaAPIPortlet class.

package com.opensource.techblog.portlet;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portlet.PortletURLFactoryUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

public class ResourceURLByJavaAPIPortlet extends MVCPortlet {

    private static final Log _log = LogFactoryUtil.getLog(ResourceURLByJavaAPIPortlet.class);
    @Override
    public void render(RenderRequest request, RenderResponse response)
            throws PortletException, IOException {
        
        
        ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(WebKeys.THEME_DISPLAY);/*themeDisplay.getPortletDisplay().getId()*/
        PortletURL resourceUrl =  PortletURLFactoryUtil.create(request, PortalUtil.getPortletId(request), themeDisplay.getPlid(), PortletRequest.RESOURCE_PHASE);
        resourceUrl.setParameter("sampleParam", "This parameter comes from resource URL generated with Java API");
        request.setAttribute("resourceUrlByJavaAPI", resourceUrl.toString());
        
        super.render(request, response);
    }

    
    @Override
    public void serveResource(ResourceRequest resourceRequest,
            ResourceResponse resourceResponse) throws IOException,
            PortletException {
        
        String sampleParam = ParamUtil.getString(resourceRequest, "sampleParam");
        _log.info("parameter is : "+sampleParam);
        
        PrintWriter out = resourceResponse.getWriter();
        out.println("Parameter that you pass is :- "+sampleParam);
        out.flush();
        super.serveResource(resourceRequest, resourceResponse);
    }
        
}

Explanation

First, I created a log variable. LogFactoryUtil in Liferay is used to create a log variable. This log variable is used to print various logs in the server console.

Render method

  • I will create a resource URL in the render method and set it to the request attribute. This will be used to make resource URL call with Ajax in JSP.
  • The code written in the render method is used to generate resource URL programmatically.
  • First, I took the ThemeDisplay (provided by Liferay out of the box) object from the request parameter.
  • Create a method of PortletURLFactoryUtil class is used to construct resource URL programmatically. It takes the following parameters.
    • PortletRequest:- RenderRequest is extending PortletRequest so you can pass it.
    • PortletName (String):- p_p_id of portlet whose serveResource method we want to be called by generated resource URL. To get p_p_id, you can either use
      1. themeDisplay.getPortletDisplay().getId()
        • themeDisplay.getPortletDisplay() returns object of type PortletDisplay which represents Portlet content.
        • getId() method of PortletDisplay returns portlet id which is nothing but p_p_id.
      2. PortalUtil.getPortletId(renderRrequest)
    • Note:- In either of the above two cases, it returns p_p_id of the current portlet. If you wish to call the serveResource method of another portlet, you need to pass the p_p_id of that portlet.
    • plid (long):- It represents page layout id. (PK for Layout table).
      • plid represents layout id (PK) of liferay page on which the target portlet (of whose serveResource method is called by generated resource URL) is placed.
      • themeDisplay.getPlid() is used to get plid of liferay page for current portlet.
      • If the target portlet is different than the current portlet, you need to pass plid of the layout on which the target portlet is placed.
    • lifecycle(String):- The type of generated Portlet URL is decided based on the value of this parameter.
      • If PortletRequest.RENDER_PHASE is passed, then this Portlet URL works as render URL.
      • If PortletRequest.ACTION_PHASE is passed, then this Portlet URL works as action URL
      • If PortletRequest.RESOURCE_PHASE is passed, then this Portlet URL works as a resource URL
      • Since we need to generate a resource URL, I gave PortletRequest.RESOURCE_PHASE.
  • PortletURLFactoryUtil.create() method returns the object of type PortletURL which represent resource URL in our case.
  • Note:- Since this is a resource URL that would be called through Ajax from JSP, there is no need to set window state or portlet mode.
  • Additional parameters
    • Additional parameters can be added by calling the setParameter method of PortletURL. I have added one parameter called ‘sampleParam‘ with sample text.
    • I will return it back as a response to the serverResource() method.

serverResource method

Add serveResource method in ResourceURLByJavaAPIPortlet so that finally it looks like as below snippet.

package com.opensource.techblog.portlet;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.kernel.util.WebKeys;
import com.liferay.portal.theme.ThemeDisplay;
import com.liferay.portal.util.PortalUtil;
import com.liferay.portlet.PortletURLFactoryUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.portlet.PortletException;
import javax.portlet.PortletRequest;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;

public class ResourceURLByJavaAPIPortlet extends MVCPortlet {

    private static final Log _log = LogFactoryUtil.getLog(ResourceURLByJavaAPIPortlet.class);
    @Override
    public void render(RenderRequest request, RenderResponse response)
            throws PortletException, IOException {
        
        
        ThemeDisplay themeDisplay = (ThemeDisplay)request.getAttribute(WebKeys.THEME_DISPLAY);/*themeDisplay.getPortletDisplay().getId()*/
        PortletURL resourceUrl =  PortletURLFactoryUtil.create(request, PortalUtil.getPortletId(request), themeDisplay.getPlid(), PortletRequest.RESOURCE_PHASE);
        resourceUrl.setParameter("sampleParam", "This parameter comes from resource URL generated with Java API");
        request.setAttribute("resourceUrlByJavaAPI", resourceUrl.toString());
        
        super.render(request, response);
    }

    
    @Override
    public void serveResource(ResourceRequest resourceRequest,
            ResourceResponse resourceResponse) throws IOException,
            PortletException {
        
        String sampleParam = ParamUtil.getString(resourceRequest, "sampleParam");
        _log.info("parameter is : "+sampleParam);
        
        PrintWriter out = resourceResponse.getWriter();
        out.println("Parameter that you pass is :- "+sampleParam);
        out.flush();
        super.serveResource(resourceRequest, resourceResponse);
    }
}
  • The serverResource() method represents the serve resource phase/lifecycle of the portlet.
  • This method will be called you make a call to resource URL
  • I am simply taking samplePara, displaying it into the log, and putting on a response, which will be sent back to the browser.
  • At the end, calling super.serveResource() method

In view.jsp file, we will use this resourceURL to call serveResource method. Add the following code into view.jsp

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

<a href="#" onclick="callResourceUrlByJavaAPI()">Action Url created by Java API in Portlet Class</a>

<script type="text/javascript">
function callResourceUrlByJavaAPI(){
    processAjax('${resourceUrlByJavaAPI}');
}

function processAjax(resourceUrl){
    AUI().use('aui-io-request', function(A){
        A.io.request(resourceUrl, {
               method: 'post',
               data: {
            	   <portlet:namespace />param2: 'value2',
               },
               on: {
                   success: function() {
                    alert(this.get('responseData'));
                   }
              }
        });
     });
}
</script>

Explanation:

  • added anchor tag and call javascript function callResourceUrlByJavaAPI. Which ultimately calling the processAjax function with resourceUrlByJavaAPI resource URL as a parameter. This is the same resource URL that we created in the render method and added into the request attribute.
  • Actual ajax call is made in the processAjax function.
  • When you click this anchor tag, it will call resource URL and ultimately call serverResource method.
  • You should be aware that the resource URL should always be called from Ajax. You also can get some more information from this link.

Place 2: resource URL programmatically in JSP

You can create a resource URL in JSP. Add the following code so that view.jsp finally looks as below.

<%@page import="javax.portlet.ResourceURL"%>
<%@page import="com.liferay.portal.kernel.portlet.LiferayPortletMode"%>
<%@page import="com.liferay.portal.kernel.portlet.LiferayWindowState"%>
<%@page import="javax.portlet.PortletURL"%>
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<portlet:defineObjects />

<a href="#" onclick="callResourceUrlByJavaAPI()">Action Url created by Java API in Portlet Class</a>
<br>
<br>
<%
    ResourceURL resourceUrlFromJSP = renderResponse.createResourceURL();
    resourceUrlFromJSP.setParameter("sampleParam", "This portletULR is created with API in JSP");
%>

<a href="#" onclick="callResourceUrlByFromJSP()">Action Url created by JAVA API in JSP</a>

<script type="text/javascript">
function callResourceUrlByJavaAPI(){
    processAjax('${resourceUrlByJavaAPI}');
}

function callResourceUrlByFromJSP(){
    processAjax('<%=resourceUrlFromJSP%>');
}

function processAjax(resourceUrl){
    AUI().use('aui-io-request', function(A){
        A.io.request(resourceUrl, {
               method: 'post',
               data: {
            	   <portlet:namespace />param2: 'value2',
               },
               on: {
                   success: function() {
                    alert(this.get('responseData'));
                   }
              }
        });
     });
}
</script>

Explanation:-

  • renderResponse is the implicit object available in JSP for the Liferay portal.
  • This object is used to create various URLs (render URL, action URL, and resource URL) in JSP.
  • I  have used renderResponse.createResourceURL() method to get resource url
  • Note:- return type is of ResourceURL
    • unlike PortletURLFactoryUtil.create() method which returns object of type PortletURLrenderResponse.createResourceURL() method returns object of type ResourceURL which you should take in consideration.
  • Once the resource URL is created, I just added one parameter.
  • You need to write this code in scriplet.
  • I have added one more javascript function callResourceUrlByFromJSP(), from which I am calling the processAjax function and passing the resource URL which I have created in scriptlet above.

And you are done. When you deploy, it looks like the below screenshot.

resource URL programmatically - final portlet output

  • The first link is of resource URL that we created in the render method with Java API
  • the second link is of resource URL that we created in JSP
  • When you click the first link, you will get the parameter you set while creating it in the portlet class’s render method as below.

resource URL programmatically - resource url with java api

  • When you click the second link, you will get the parameter you set while creating it in JSP.

resource URL programmatically - resource url with JSP

And you are done. Please share your thoughts on creating a resource URL programmatically in the comment section.

Summing Up

  • Resource URL can be used to call the serve resource phase of the portlet.
  • Programmatically you can create resource URL either from portlet class or from JSP.
  • Programmatically created Resource URL can point to another portlet as well.

Download

If you don’t have Liferay developer studio 2.x, You can use Liferay IDE 3.1.2 GA3, which ships with Eclipse Neon 3. Download the maven project structure and source from Git Hub Project

Recommended For You

About the Author: Nilang

Nilang Patel is a technology evangelist who loves to spread knowledge and helping people in all possible ways. He is an author of two technical books - Java 9 Dependency and Spring 5.0 Projects.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.