Affects Version/s: 7.4.0 CE GA1
Section 11.1 of the JSR 362 (Portlet 3.0) Specification states:
11.1 Portlet Parameters
Portlet parameters are name-value pairs modeled after servlet request parameters. The parameter name is represented by a String while the value is a String array. The parameter name may not be null.
The value null is a valid parameter value, both within a parameter values array and when set or returned as a single value. Setting a parameter value to null does not remove the parameter. Similarly, an empty array is a valid parameter value.
Regarding the specific requirement about the values array:
null is a valid parameter value ... within a parameter values array
... the Portlet 3.0 TCK has a portlet class named PortletParametersTests_SPEC11_1 that tests the requirement.
Specifically, line 97 sets up the following:
Then on line 239, it tests to see if the invoked RenderURL preserved null as a parameter value in two spots of the array of values:
When the URL is rendered by Apache Pluto (the Portlet 3.0 reference implementation), it looks like this:
The part of the URL that is relevant to this use case is:
When the RenderURL is invoked, Pluto PortalURLParserImpl class tries to parse the URL, lines 339-354 do the following:
First, it tries to split the String into a String array using VALUE_DELIM (which is a ":" character, resulting in the following String array:
It then iterates through the array, and replaces every occurrence of VALUE_NULL (which is a "," character) with the value null. The result is the following String array:
The Liferay implementation of Portlet 3.0 has a bug such that multi-value request parameters contain null instead of an empty string. The cause of the bug is found in lines 1411-1417 of PortletRequestImpl.java:
Although this code causes the aforementioned TCK test to pass, it prevents the empty string ("") from being received from the underlying HttpServletRequest as one of the values in the values String array.
1. Deploy the attached lps133689.jar artifact to $LIFERAY_HOME/deploy
2. Add the "LPS133689" portlet to a widget page
3. Click on the "Click me to invoke the RenderURL" link
The portlet renders the following:
The portlet renders a failure, perhaps something like the following: