掲示板

Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

10年前 に Klaus Bachmaier によって更新されました。

Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Regular Member 投稿: 223 参加年月日: 13/09/30 最新の投稿
I did the first "Hello You" Example from "Liferay in Action" several Times, and never faced any Problems with it using the Liferay 6.1.x SDK's

Now I tried it just for fun again with Liferay Plugin SDK 6.2.0 and Liferay 6.2.0 CE GA1 and this really simple standard portlet example won't work anymore. Unfortunately I can't figure out why.

The problem is in the processAction() method of the portlet class. This method is invoked from a JSP, whitch has a form on it with a field called "username". So "username" is one of the POST parameters in the Action Request.

This is the method from the Liferay in Action Example Code:


public void processAction(
			ActionRequest actionRequest, ActionResponse actionResponse)
		throws IOException, PortletException {

		String addName = actionRequest.getParameter("addName");
		if (addName != null) {
			PortletPreferences prefs = actionRequest.getPreferences();
			prefs.setValue("name", actionRequest.getParameter("username"));
			prefs.store();
			actionResponse.setPortletMode(PortletMode.VIEW);
		}
	}


When I try this in Liferay 6.1.x SDK the parameter "username" can be retreived from the actionRequest object. But in Liferay 6.2.0 actionRequest.getParameter("username") returns null, while I can see that "username=someName" exists in the POST Request when checkin the request with the Chrome browsers developer tools.

Here is the code witch makes up the edit jsp in the example code:

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

<jsp:usebean class="java.lang.String" id="addNameURL" scope="request" />

<portlet:defineobjects />

<form id="<portlet:namespace />form" action="<%= addNameURL %>" method="post">

	<table>
		<tbody><tr>
			<td>Name:</td>
			<td><input type="text" name="username"></td>
		</tr>
	</tbody></table>
	<input type="submit" id="nameButton" title="Add Name" value="Add Name">
</form>



I just want to understand why the exact same code - actionRequest.getParameter("username") - returns some value in Liferay 6.1.x and returns Null in Liferay 6.2.0.

Thanks in advance
thumbnail
10年前 に meera prince によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Liferay Legend 投稿: 1111 参加年月日: 11/02/08 最新の投稿
hI

in the form you have only one text filed and its name is username

you have to get like this actionRequest.getParameter("username")

but in the code i found actionRequest.getParameter("addName"); no field in the form with the name addName. that is why it migh not enter into if block.

in side if block u have used prefs.setValue("name", actionRequest.getParameter("username"));

String addName = actionRequest.getParameter("addName");
if (addName != null) {
PortletPreferences prefs = actionRequest.getPreferences();
prefs.setValue("name", actionRequest.getParameter("username"));
prefs.store();
actionResponse.setPortletMode(PortletMode.VIEW);
}
10年前 に Klaus Bachmaier によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Regular Member 投稿: 223 参加年月日: 13/09/30 最新の投稿
The addName Parameter is used in the example to distinguish between possible differnet actions the processAction() method could handle (of course there is only one action here). It is passed to the form in the doEdit() method of the portlet. So only if the addName Parameter has been set in the request, the username parameter will be read from the request in the processAction() method, and stored in the portlet preferences.

This is the code where the addName Parameter comes from:

public void doEdit(
			RenderRequest renderRequest, RenderResponse renderResponse)
		throws IOException, PortletException {

		renderResponse.setContentType("text/html");
		PortletURL addNameURL = renderResponse.createActionURL();
		addNameURL.setParameter("addName", "addName");
		renderRequest.setAttribute("addNameURL", addNameURL.toString());
		include(editJSP, renderRequest, renderResponse);
	}


Finally the post request from the form should pass two parameters back to the portlet: addName and username. Both parameters exitst in the POST request as I can see with Chromes developer tools, but somehow username could not be retrieved using actionRequest.getParameter("username"), and as i wrote earlier, this problem only occurs in Liferay 6.2.
10年前 に Rich Newton によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

New Member 投稿: 1 参加年月日: 14/01/01 最新の投稿
Hi,

I'm having the exact same problem using 6.2 SDK. Were you able to resolve the issue? Can you share how you resolved it?

Thanks
Rich.
thumbnail
10年前 に Juan Gonzalez によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Liferay Legend 投稿: 3089 参加年月日: 08/10/28 最新の投稿
Hi Rich, Klaus,

in 6.2 parameters should be namespaced by default. If not, you should add this element to your xml (example):

https://github.com/liferay/liferay-portal/blob/6.2.0-ga1/definitions/liferay-portlet-app_6_2_0.dtd#L651-655
10年前 に Klaus Bachmaier によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Regular Member 投稿: 223 参加年月日: 13/09/30 最新の投稿
Thank you Juan!

I had only to change my Form to like like this:


<form id="<portlet:namespace />fm1" name="<portlet:namespace />fm1" action="<%= addNameURL %>" method="post">

	<table>
		<tbody><tr>
			<td>Name:</td>
			<td><input type="text" name="<portlet:namespace />username"></td>
		</tr>
	</tbody></table>
	<input type="submit" id="nameButton" title="Add Name" value="Add Name">
</form>


Nothing more to change in the portlet class. Now it works perfectly in 6.2
9年前 に Marko Perić によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Junior Member 投稿: 52 参加年月日: 14/09/03 最新の投稿
Hi,

I also have a problem with this example your're talking about. I'm using Liferay 6.2, I did everything like in book Liferay in action, but when I enter some name in textbox (Edit Mode) and press a button, there is no content from input field where I wrote my name. My code:


package com.liferayinaction.portlet;

import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.GenericPortlet;
import javax.portlet.PortletException;
import javax.portlet.PortletMode;
import javax.portlet.PortletPreferences;
import javax.portlet.PortletRequestDispatcher;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Portlet implementation class HelloYouPortlet
 */
public class HelloYouPortlet extends GenericPortlet {
	

    public void init() throws PortletException {
        editJSP = getInitParameter("edit-jsp");
        viewJSP = getInitParameter("view-jsp");
    }

	@Override
	protected void doView(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {
		
		PortletPreferences prefs = request.getPreferences();
		String username = (String) prefs.getValue("name","no");
		if (null != username &amp;&amp; username.equalsIgnoreCase("no")) {
			username = " ";
		}
		
		request.setAttribute("userName", username);
		include(viewJSP, request, response);
		
	}
	
	@Override
	protected void doEdit(RenderRequest request, RenderResponse response)
			throws PortletException, IOException {

		response.setContentType("text/html");
		PortletURL addNameURL = response.createActionURL();
		addNameURL.setParameter("addName", "addName");
		request.setAttribute("addNameURL", addNameURL.toString());
		include(editJSP, request, response);
	}
	
	@Override
	public void processAction(ActionRequest request, ActionResponse response)
			throws PortletException, IOException {
		String addName = request.getParameter("addName");
		if (addName != null) {
			PortletPreferences prefs = request.getPreferences();
			prefs.setValue("name", request.getParameter("username"));
			prefs.store();
			response.setPortletMode(PortletMode.VIEW);
		}
	}

	protected void include(
			String path, RenderRequest request, RenderResponse response)
			throws IOException, PortletException {
		
		PortletRequestDispatcher prd = getPortletContext().getRequestDispatcher(path);
		
		if (prd == null) {
			_log.error(path + " is not a valid include");
		}
		else {
			prd.include(request, response);
		}
	}
	
    protected String editJSP;
    protected String viewJSP;
    private static Log _log = LogFactory.getLog(HelloYouPortlet.class);
   
}


edit.jsp

&lt;%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %&gt;
<jsp:usebean class="java.lang.String" id="addNameURL" scope="request" />

<portlet:defineobjects />

<form id="<portlet:namespace/>helloForm" action="<%= addNameURL %>" method="post">
	<table>
		<tbody><tr>
			<td>Name</td>
			<td><input type="text" name="<portlet:namespace/>username"></td>
		</tr>
	</tbody></table>
	<input type="submit" id="nameButton" title="Add Name" value="Add Name">
</form>


view.jsp

&lt;%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %&gt;
<jsp:usebean id="username" class="java.lang.String" scope="request" />

<portlet:defineobjects />

<p>Ovo je <b>Hello You</b> portlet</p>
<p>Hello &lt;%= username %&gt;!</p>


I'm trying to solve this for 2 days but I don't know what's happening...Any ideas?
9年前 に Ravi Challapalli によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

New Member 投稿: 1 参加年月日: 14/12/23 最新の投稿
You might have already figured it out but incase not, its already mentioned in the above post

<td><input type="text" name="<portlet:namespace />username"></td>
prefix the username with <portlet:namespace /> in the edit.jsp

Cheers.
9年前 に Laura Salas によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

New Member 投稿: 2 参加年月日: 15/03/26 最新の投稿
Hi, Marco,
Be careful with the Upper Case letter in view.jsp, you wrote username and it must be userName:
<jsp:useBean id="userName" class="java.lang.String" scope="request"/>

<portlet:defineObjects />

<p>Ovo je <b>Hello You</b> portlet</p>
<p>Hello <%= userName %>!</p>
thumbnail
9年前 に David H Nebinger によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Liferay Legend 投稿: 14915 参加年月日: 06/09/02 最新の投稿
Sorry, Laura, but in the context "username" was the right thing. When you check the ID from the edit.jsp page you'll see that the field was defined as <portlet:namespace />username.

When you get into accessing the Liferay objects, well then of course the lower camel casing applies (mixed capitals as first letters of words but lower case first letter).
thumbnail
9年前 に Rajeeva Lochana .B.R によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Junior Member 投稿: 67 参加年月日: 10/01/04 最新の投稿
Hi Klaus Bachmaier,


Another approach : Without changing code in ".jsp" file. By adding the below code in liferay-portelt.xml

<requires-namespaced-parameters>false</requires-namespaced-parameters>
thumbnail
9年前 に Andew Jardine によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Liferay Legend 投稿: 2416 参加年月日: 10/12/22 最新の投稿
Just to add to the thread, Liferay best practice dictates that you should use the ParamUtil --


String username = ParamUtil.getString( actionRequest, "username", StringPool.BLANK);


Both work, but I am sure you would prefer not to anger the Liferay Gods emoticon
thumbnail
8年前 に Fernando Fernandez によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Expert 投稿: 396 参加年月日: 07/08/22 最新の投稿
Juan Gonzalez:

(...)in 6.2 parameters should be namespaced by default. (...)


This was a bad decision. I just lost a day's work over this, because I never believed Liferay would break the API behaviour like that. Why is there no warning in the logs, at least?

Yes, I understand the need for discipline, but this solution is awful and UGLY. This type of decisions is what makes web development the OPPOSITE OF ELEGANCE! :-(

Sorry for the rant. I'm really pissed by this.

Fernando
thumbnail
8年前 に David H Nebinger によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Liferay Legend 投稿: 14915 参加年月日: 06/09/02 最新の投稿
Fernando Fernandez:
This was a bad decision.


This will sound kinda harsh, but that opinition is only based on your lack of knowledge and experience with the portal. The JSR-168 clearly spells out that parameters will be namespaced and even provided the <portlet:namespace /> tag to assist in handling namespacing in JSPs.

Parameters are namespaced in order to ensure there are no input name/id collisions. If your portlet has a field named "zipcode" and my form has a field named "zipcode", the lack of a namespace would result in a collision on the fields during submission and processing on the server side.

I just lost a day's work over this, because I never believed Liferay would break the API behaviour like that.


Break what API behaviour? The servlet API? It's not broken. Parameters on the rendered page are all have unique names and, on submission, the parameters have the same name as the field from the original form.

Why is there no warning in the logs, at least?


What is there to warn? That the portal is operating per correct JSR specification?

Yes, I understand the need for discipline, but this solution is awful and UGLY. This type of decisions is what makes web development the OPPOSITE OF ELEGANCE! :-(

Sorry for the rant. I'm really pissed by this.


Sorry for tearing your argument to pieces, but please know this is not meant to be a personal attack. I'd recommend reading Portlets in Action (talks about the portlet implementations in general) or even just peruse JSR-168 and JSR-286; any of these may provide further background on portlets that may help prevent this kind of time loss again in the future.
thumbnail
8年前 に Fernando Fernandez によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Expert 投稿: 396 参加年月日: 07/08/22 最新の投稿
Hi David,

First of all, I'd like to make it clear that Liferay is a great product and the developers are doing an excellent job. :-)

I understand the name collision problem - having experienced and solved it sometime ago - and I'm not the only one saying that this is a broken behaviour:


Anyway, we have a workaround and and I was really too harsh yesterday, sorry for that. :-)

Fernando
thumbnail
8年前 に David H Nebinger によって更新されました。

RE: Simple "Hello World" Portlet from LIA Book in Liferay 6.2.

Liferay Legend 投稿: 14915 参加年月日: 06/09/02 最新の投稿
So 286 allowed for the portlet to ask for the namespaced parameter name, not just the name, from the portlet request and Liferay wasn't respecting that.

Looks like they resolved it in EE and the upcoming L7. It's not in CE yet. The one bug includes a pull ID so you should be able to replicate into the CE source if you needed to backport.

I've never run into this myself as I naturally use the simple name in the portlet code. If it's a failure to adhere to the JSR, then it should be fixed.

Admittedly I've been sitting here for 10 minutes trying to figure out the use case for including namespace with the param name, why that would make sense, and honestly it's just escaping me. But that's okay, the JSR allows for it so it doesn't matter if I should understand why or not.