liferayliferay-6

Request in actionUrl comes empty


I'm trying to read POST data in Liferay 6.0.6 but I always receive an empty ActionRequest (empty in the sense that the data isn't there):

<portlet:actionURL var="prc">
<portlet:param name="view" value="prc"></portlet:param>

And:

<form method="POST" action="${prc}" id="of2017" name="of2017" class="datos" enctype="multipart/form-data">

Then in the ViewController:

@RequestMapping(params="view=prc")
public void prc(ActionRequest request, ActionResponse response) {

At this point, request.getAttributeNames(), request.getParameterNames() and request.getPortletSession().getAttributeNames() are always empty. What I'm missing?


Solution

  • Session Attributes and Namespace

    Although you have a partial answer to your question already I think it would be beneficial to expound that answer.

    Firstly, it would be beneficial if you could post more of your code. Specifically, I am interested in seeing your liferay-portlet.xml file and more of your form elements.

    Namespacing

    A portlet namespace is a unique ID associated with your portlet. The namespace prevents two identically named forms from two separate portlets on the same page from accidentally sending data to the wrong portlet on POST.

    In Java portlet development, all of your html form elements would have a portlet namespace. A sample JSP page should look like the following

    <!-- This is necessary on all JSP pages -->
    <%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
    <portlet:defineObjects />
    
    <form id="<portlet:namespace />fm" name="<portlet:namespace />fm" action="${whereever}">
       <input type="text" id="<portlet:namespace />input" name="<portlet:namespace />input" />
       <input type="submit" id="<portlet:namespace />button" name="<portlet:namespace />button">
    </form>
    

    You will notice the <portlet:namespace /> tag in the above example. Once you build and deploy your portlet, you can inspect your html elements. You will see the <portlet:namespace /> tag has turned into the namespace of your portlet (usually YourPortletName). This is how Liferay deals with uniqueness.

    Instead of explicitly using the namespace tag inside a html form you can instead opt to use an Alloy UI form which automatically injects it.

    <!-- This is necessary on all JSP pages -->
    <%@ taglib uri="http://java.sun.com/portlet" prefix="portlet" %>
    <%@ taglib uri="http://liferay.com/tld/aui" prefix="aui"%>
    <portlet:defineObjects />
    
    <aui:form name="fm" action="${whereever}">
       <input type="text" name="input" />
       <input type="submit" name="button">
    </form>
    

    You will notice two things if you inspect this markup after deploying the portlet. Firstly, will notice that the name attribute automatically injects the namespace (it will have the same exact name as the previous example). You will also note that AUI automatically creates an id tag with the same name (don't create your own).

    If you attempt to use the ParamUtil.getString utility without a namespaced form it will not work. You can disable the namespace requirement by adding

    <requires-namespaced-parameters>false</requires-namespaced-parameters>
    

    to your liferay-portlet.xml file however it is HIGHLY discouraged.

    Session Attributes

    You should be careful with the term "Session attribute". In JSR-168 and JSR-286 portlets you have the normal HTTP Session attributes which are managed by the application container (Tomcat, etc).

    Liferay also has a portlet session which is similar in decision but used for a different reason. Instead of being managed by the container, the portlet session is managed by Liferay. Liferay has a separate portlet session for very portlet that is loaded onto a page. In Liferay you can modify the liferay-portlet.xml file to change whether your portlet has private or public sessions (controls whether they access the portal sessions and other portlet sessions).


    In general, POST requests to a portlet you don't care about "session attributes" at all. Sending data to your backend Portlet class is done by using namespaced ActionRequests. If you use either of the above examples in a JSP page, and you get the value of the input box (which is named input) by using ParamUtil.getString(actionRequest, "input") there should be no issue. The @SessionAttributes({}) is not needed for ActionRequests in an MVCPortlet or Spring MVC Portlet in this case