Liferay portlet 在 processAction 之后重新呈现初始页面

Liferay portlet rerenders init page after processAction

我正在使用 portlet,并且正在研究 liferay 的 wiki 上的示例:https://www.liferay.com/documentation/liferay-portal/6.1/development/-/ai/writing-the-my-greeting-portl-4

我在处理表单后重定向回 init jsp 时遇到了一些问题。我的 Java class 是:

import java.io.IOException;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;
import com.liferay.util.bridges.mvc.MVCPortlet;

public class Directory extends MVCPortlet {

    @Override
    public void processAction(
        ActionRequest actionRequest, ActionResponse actionResponse)
        throws IOException, PortletException {
        PortletPreferences prefs = actionRequest.getPreferences();
        String greeting = actionRequest.getParameter("greeting");

        if (greeting != null) {
            prefs.setValue("greeting", greeting);
            prefs.store();
        }

        super.processAction(actionRequest, actionResponse);
    }
}

我有两个 jsp。 view.jsp:

<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
<%@ page import="javax.portlet.PortletPreferences" %>

<portlet:defineObjects />

<%
PortletPreferences prefs = renderRequest.getPreferences();
String greeting = (String)prefs.getValue(
"greeting", "Hello! Welcome to our portal.");
%>

<p><%= greeting %></p>

<portlet:renderURL var="editGreetingURL">
   <portlet:param name="mvcPath" value="/edit.jsp" />
</portlet:renderURL>

<p><a href="<%= editGreetingURL %>">Edit greeting</a></p>

和edit.jsp:

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

<%@ page import="com.liferay.portal.kernel.util.ParamUtil" %>
<%@ page import="com.liferay.portal.kernel.util.Validator" %>
<%@ page import="javax.portlet.PortletPreferences" %>

<portlet:defineObjects />

<%
    PortletPreferences prefs = renderRequest.getPreferences();
    String greeting = (String)prefs.getValue(
    "greeting", "Hello! Welcome to our portal.");
%>

<portlet:actionURL var="editGreetingURL">
 <portlet:param name="mvcPath" value="/edit.jsp" />
</portlet:actionURL>

<aui:form action="<%= editGreetingURL %>" method="post">
    <aui:input label="greeting" name="greeting" type="text 
       value="<%=greeting%>
    <aui:button type="submit" />
</aui:form>

<portlet:renderURL var="viewGreetingURL">
    <portlet:param name="mvcPath" value="/view.jsp" />
</portlet:renderURL>

<p><a href="<%= viewGreetingURL %>">&larr; Back</a></p>

在 edit.jsp 的表单提交中,它应该重新呈现该页面。当我只使用 portlet:renderUrl 而不是 portlet:actionUrl 时,它会正确执行,但不会重新呈现 actionUrl。本教程说它应该再次呈现 edit.jsp,所以我不确定我遗漏了什么。注意:它正确保存了我的所有参数。

根据 JSR 286(又名 Portlet 规范 2.0),PLT.11.1.1.2:

The portlet-container must not propagate parameters received in an action or event request to subsequent render requests of the portlet.

这是当用户点击浏览器页面上的提交按钮时发生的情况:

  1. 浏览器向 Liferay 发送一个 Action 请求,其参数包含 "name" 和 "mvcPath".
  2. Portlet 现在处于 Action 阶段,因此它执行 processAction 方法。
  3. processAction 方法无错误终止时,Liferay 仍在响应 Action 请求,浏览器仍在等待响应,这将是当前页面的 HTML。
  4. 因为 Liferay 现在必须用页面的 HTML 响应浏览器,它会为页面中的每个 portlet 调用 render 方法。也就是说,如果向这些 portlet 发出 Render 请求。
  5. 对于您的 portlet,它是一个 MVCPortletrender 方法读取 "mvcPath" 参数以找出它必须呈现哪个 JSP 页面。

但是现在,JSR 286 说 ActionRender 阶段之间没有参数传递,所以 mvcPath,它是 Action 请求的一部分,不会被 Liferay 复制到 Liferay 向您的 portlet 发出的 Render 请求。

现在,解决方案:

  • 正如您所建议的,在 processAction 方法的末尾(但通常您不会更改 processAction 方法,而是为不同的操作创建不同的方法,他们会告诉您教程中的操作方法...请查看 http://dev.liferay.com),您可以设置 actionResponse.setRenderParameter("mvcPath","/edit.jsp")。这是完全正常的。
  • 如果您希望您的 Action 参数始终被复制到 Liferay 对您的 portlet 发出的后续 Render 请求,您可以设置copy-request-parameters 初始化参数 true (看看 here
  • 但是您会看到通常 Liferay portlet 在执行 "edit" 操作后返回视图(在 Action 中传递 "redirect" 参数请求),所以这取决于你。

不好意思,这个话题说的有点多,希望我写的对你有用!