Requires namespaced Parameter in Liferay

Liferay requires namespaced parameter starting from version 6.2. This is required to avoid name collision.

requires namespaced

While working with portlet, most of the cases you are submitting some values from jsp, taking it in action or render method and perform some operation on it.

Many times, even if you pass the parameters from JSP, you are getting null or empty values for those parameter in portlet class. In this article, I will be exploring the reason behind it.

We will understand it by creating liferay MVC portlet. I gave project name as required-namespace and -portlet will be appended by Liferay IDE while creating project. I created portlet class as com.opensource.techblog.portlet.RequiredNamespacePortlet. The project structure should look like below screenshot at this point.

requires namespaced - Project Structure

Add following code in view.jsp (vide.jsp is created under docroot folder by Liferay IDE)

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

<portlet:actionURL name="testParameter" var="testParameterUrl">
</portlet:actionURL>

<form action="${testParameterUrl}" method="POST">
	Parameter : <input type="text" name="param1">
	<input type="submit" value="Submit">
</form>

Explanation

  • I have created an action URL and created one HTML form and assigned its action attribute to the action URL.
  • In this form, there is just one input element called param1.
  • When the user submits this form, the value of the param1 parameter should be available in the action method.

Add action method as per following code in portlet class – RequiredNamespacePortlet.java

package com.opensource.techblog.portlet;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.ProcessAction;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

public class RequiredNamespacePortlet extends MVCPortlet {

	private static Log _log = LogFactoryUtil.getLog(RequiredNamespacePortlet.class.getName());
		
	@ProcessAction(name="testParameter")
	public void testParameter(ActionRequest request, ActionResponse response){
		String param1 = ParamUtil.get(request, "param1", "");
		_log.info("param1 is ==>"+param1);
	}

}

Explanation

  • I have defined one action method. This action method will be called when a user submits the HTML form in the view.jsp.
  • In this action method, I am simply reading the request parameter that is passed from view.jsp and printing it in log.
  • I have used ParamUtil to read request parameters. You may use request.getParameter() method to read request parameter.
  • If request parameter is not available then ParamUtil.get method will return default value (3rd parameter) while request.getParameter() will return null.

Save these files, deploy and place the portlet on a page. You will see one text box and one submit button. Give some value in the text box and submit the form. You will get the empty/null value of this value in the action method.

We took the example of the action method but if you read the request parameter in the render or resource method then also you will get a null/empty value for the request parameter.

Problem statement:- getting null / empty value of request parameter in action / render or resource method.

Reason: starting from version 6.2, Liferay reads the request parameter only if you have attached the portlet namespace to it. This is the default behavior. Liferay requires a namespaced parameter. It means Liferay by default enforces you to pass portlet namespace along with parameter name. In the above example, we haven’t pass portlet namespace so the portlet will not read the request parameter.

before further explanation, you must understand what is portlet namespace. Portlet namespace is a unique value assigned by the portal to each portlet on page.

How to solve requires namespaced issue

There are various solutions to read request parameters (especially starting from Liferay 6.2) so that requires namespaced criteria is fulfilled.

By Passing portlet namespace to each form element

  • This is very straightforward. You must have to pass the portlet namespace to each form element/request parameter. You may refer to my blog on portlet namespace usage. Portlet namespace can be passed in the following ways.
<input type="text" name="<portlet:namespace/>studentName" id="<portlet:namespace/>stdNm"/>

OR

<input type="text" name="<%=renderResponse.getNamespace()%>studentName" id="<%=renderResponse.getNamespace()%>stdNm"/>
  • Pros
    • Easy to use, no extra setting required. This is the simplest way to fulfill requires a namespace parameter.
    • Enforcing portlet namespace will save name collision at a later stage of development.
  • Cons
    • If you already written lots of JSP code with many form elements, then you need to put extra effort to pass portlet namespace to each form element in each JSP. This is applicable especially you are migrating your code from Liferay 6.1 to 6.2

Set <requires-namespaced-parameters> to false

  • This is another way to read parameter in portlet.
  • In this approach, we will Instruct liferay not to enforce us to pass portlet namespace. This can be achieved by setting <requires-namespaced-parameters> to false in liferay-portlet.xml file
  • In other words, requires namespaced is a switch for that portlet. The default value for requires namespaced parameter is true. If requires a namespaced parameter is set to false then the portal will allow reading all parameters (with or without portlet namespace) for that portlet.
  • Pros
    • Easy to use.
    • In case if you are migrating your existing code from Liferay 6.1 to 6.2, it’s just one place configuration to read parameters.
    • Parameters are not requires namespaced.
  • Cons
    • It’s not mandatory to pass namespace in this approach. This means there is a chance of name collision at a later stage.
    • Only choose this approach if you are sure about name collision.

Use AUI tags

  • Liferay provides AUI taglibs to construct various form elements.
  • When you use AUI taglibs, it will automatically pass portlet namespace to that element.
  • The below code snippet shows how to use the AUI element.
<%@ taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui" %>

<aui:input name="studentName" label="Student Name" id="studentName"/>
  • To avail AUI taglib, you must have to define <% taglib uri=”http://alloy.liferay.com/tld/aui” prefix=”aui” %> in your JSP.
  • when this tag resolve, it will generate input element like below snippet
<input id="_requirednamespace_WAR_requirednamespaceportlet_studentName" name="_requirednamespace_WAR_requirednamespaceportlet_studentName" type="text" class="field" value="">
  • As you can observe that the portlet namespace (_requirednamespace_WAR_requirednamespaceportlet_) is attached to studentName field name when this tag is resolved.
  • For a complete list of AUI form elements, you can refer AUI form element link.
  • Pros
    • Easy to use.
    • No worry about passing portlet namespace as it will do automatically.
    • The need of requires namespaced criteria is fulfilled.
  • Cons
    • New Learning.
    • AUI form elements can’t be used in certain situations for example you had your own theme and HTML.

Summing Up

  • To avoid name collision, Liferay requires a namespaced parameter starting from version 6.2.
  • It’s always best practice to pass portlet namespace to each form element to fulfill requires namespaced criteria.
  • Liferay however provides few ways to either pass portlet namespace automatically (use AUI taglib) or not enforcing us to pass portlet namespace (by setting requires-namespaced-parameters to false in liferay-portlet.xml).

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.