actionUrl 中的请求为空

Request in actionUrl comes empty

我正在尝试读取 Liferay 6.0.6 中的 POST 数据,但我总是收到一个空的 ActionRequest(空的意思是数据不存在):

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

并且:

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

然后在 ViewController:

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

此时,request.getAttributeNames()、request.getParameterNames() 和request.getPortletSession().getAttributeNames() 始终为空。我错过了什么?

哇,我可以用

读取数据
ParamUtil.getString(request, name-of-data)

并且缺少

@SessionAttributes({})

在 ViewController 的开头,虽然我不知道为什么,因为我的工作样本没有使用它们。

会话属性和命名空间

虽然您已经对您的问题有了部分答案,但我认为阐述该答案会有所帮助。

首先,如果您可以 post 更多代码,那将是有益的。具体来说,我有兴趣查看您的 liferay-portlet.xml 文件和更多 form 元素。

命名空间

Portlet 名称空间是与您的 Portlet 关联的唯一 ID。命名空间可防止来自同一页面上两个独立 portlet 的两个同名表单意外地将数据发送到 POST.

上的错误 portlet

在 Java portlet 开发中,所有 html 表单元素都有一个 portlet 命名空间。示例 JSP 页面应如下所示

<!-- 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>

您会注意到上例中的 <portlet:namespace /> 标记。构建和部署 portlet 后,您可以检查 html 元素。您会看到 <portlet:namespace /> 标记变成了您的 portlet 的命名空间(通常是 YourPortletName)。这就是 Liferay 处理唯一性的方式。

您可以选择使用自动注入的 Alloy UI 表单,而不是在 html 表单中显式使用命名空间标签。

<!-- 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>

如果在部署 portlet 后检查此标记,您会注意到两件事。首先,会注意到 name 属性自动注入命名空间(它将与前面的示例具有完全相同的名称)。您还会注意到 AUI 会自动创建一个同名的 id 标签(不要创建您自己的标签)。

如果您尝试在没有命名空间的情况下使用 ParamUtil.getString 实用程序,它将无法工作。您可以通过添加

来禁用名称空间要求
<requires-namespaced-parameters>false</requires-namespaced-parameters>

到您的 liferay-portlet.xml 文件,但是 非常 不鼓励。

会话属性

您应该小心使用“会话属性”一词。在 JSR-168 和 JSR-286 portlet 中,您具有由应用程序容器(Tomcat 等)管理的普通 HTTP 会话属性。

Liferay 也有一个 portlet session,它在决策上类似,但用于不同的原因。 Portlet 会话不是由容器管理,而是由 Liferay 管理。 Liferay 有一个单独的 portlet 会话,用于加载到页面上的 portlet。在 Liferay 中,您可以修改 liferay-portlet.xml 文件以更改您的 portlet 是否具有私有会话或 public 会话(控制它们是否访问门户会话和其他 portlet 会话)。


通常,POST 请求您根本不关心“会话属性”的 portlet。将数据发送到后端 Portlet class 是通过使用命名空间 ActionRequests 完成的。如果您在 JSP 页面中使用上述任一示例,并且您通过使用 ParamUtil.getString(actionRequest, "input") 获取输入框(名为 input)的值应该没问题。在这种情况下,MVCPortlet 或 Spring MVC Portlet 中的 ActionRequests 不需要 @SessionAttributes({})