gpt4 book ai didi

java - Struts2 portlet 正在执行 Liferay 刷新的默认操作(而不是其当前操作)

转载 作者:行者123 更新时间:2023-11-30 11:45:45 25 4
gpt4 key购买 nike

编辑:编辑标题以反射(reflect)新发现。第二个 portlet 是什么类型的 portlet 并不重要。请参阅下面的一般行为:

  1. 我在页面上有一个 Struts2 portlet A,它的默认“索引”操作是 pageA1。
  2. 我单击 A1 上的链接并转到页面 A2。
  3. 我刷新页面,portlet A 仍然显示 pageA2。
  4. 页面上还有其他 portlet。我选择任何一个 portlet B,然后单击 B1 上的链接。
  5. Portlet B 导航到 B2。同时,Liferay 刷新页面上的其他 portlet,包括 Struts2 portlet A。
  6. Portlet A 刷新后的预期结果是 pageA2,但是显示的页面是 pageA1!

症状:

我在 struts 操作中添加了一些日志记录以显示传递的参数。在正常导航期间(即我只是单独使用 struts2 portlet A),会显示参数 struts.portlet.action 和 struts.portlet.mode。但是,如果由于另一个 portlet B 的呈现/操作阶段而在 struts2 portlet A 上发生自动刷新,这些参数似乎不会传递给 struts2,因此 portlet A 默认返回其索引 pageA1,而不是页面刷新前显示(pageA2)。

这是否意味着由于 struts2 没有检测到 struts.portlet.action 参数,它将调用默认操作(在这种情况下,我将其设置为“index”->pageA1)?


旧细节

我有一个项目设置有两个 portlet,都使用 Struts2 框架。这两个 portlet 实际上彼此非常相似,但是它们的代码存在于不同的包中,并且在 struts.xml 中,它们的 Actions 是在具有自己的 namespace 的单独模块中定义的。不过,它们仍然是一个项目的一部分,并且一起打包在一个 WAR 文件中。

我将 WAR 部署到 Liferay,并将两个 portlet 添加到一个页面。当我使用这两个 portlet 时会发生以下行为:

  1. 单击 Portlet A 上的链接。
  2. Portlet A 加载到屏幕 A2。
  3. 单击 Portlet B 上的链接。
  4. Portlet B 加载到屏幕 B2。
  5. 但是,作为副作用,Portlet A 刷新并且显示的屏幕是它的“索引”页面(而不是屏幕 A2)。

这是预期的行为,还是我应该做些什么来使这个特定的设置在单个门户页面中工作?

编辑:我单击的链接是 renderURL(使用 s:url 标记生成)。两个 portlet 的第二页都包含表单,我不确定它是否重要。

我添加了一些简单的日志记录,基于它,我发现在每次页面刷新时,两个 portlet 都会被呈现两次。我不认为这是一种自然行为。

如果有用的话,这是我的 struts.xml:

<package name="portletA" extends="struts-portlet-default" namespace="/portletA">

<action name="index" class="my.a.DisplayFirstPageAction">
<result name="success">/pageA1.jsp</result>
</action>

<action name="displayForm" class="my.a.DisplaySecondPageAction">
<result name="input">/pageA2.jsp</result>
</action>
</package>
<package name="portletB" extends="struts-portlet-default" namespace="/portletB">

<action name="index" class="my.b.DisplayFirstPageAction">
<result name="success">/pageB1.jsp</result>
</action>

<action name="displayForm" class="my.b.DisplaySecondPageAction">
<result name="input">/pageB2.jsp</result>
</action>
</package>

在这两个 portlet 上,pageA1.jsp 都有一个调用 struts 操作“displayForm”的链接。 FirstPageAction 的执行方法返回 SUCCESS,而 SecondPageAction 的执行方法返回 INPUT。

我认为这可能是因为我在第二个操作中没有“成功”结果(我的 execute() 方法返回“input”,因为我在页面中有一个表单)。不过,添加 result=success 标签没有帮助。

大声思考,如果我在渲染 B2 时单击 A1 的链接,应该调用 B2 的渲染/执行操作,但似乎调用了 B1 的渲染/执行操作。

最佳答案

检查 http://www.liferay.com/documentation/liferay-portal/6.0/development/-/ai/understanding-the-two-phases-of-portlet-execution ,特别是以下段落:

Portlet 规范为 Portlet 的每个请求定义了两个阶段,以允许门户区分何时执行操作(不应重复)和何时生成(呈现)内容:

  • Action phase:只能在一个 portlet 调用 action 阶段一个时间,通常是用户与组件。在此阶段,Portlet 可以更改其状态,例如例如更改 portlet 的用户首选项。也是建议在数据库中的任何插入和修改或不应重复的操作在此阶段执行。
  • 呈现阶段:始终为所有 portlet 调用呈现阶段 Action 阶段之后的页面(可能存在也可能不存在)。这包括也已执行其操作阶段的 portlet。它是重要的是要注意渲染阶段的顺序页面中的 portlet 得到执行不由 portlet 保证规范。 Liferay 通过以下方式对规范进行了扩展liferay-portlet.xml 中的元素 render-weight。带有较高的渲染权重将在较低的渲染权重之前渲染值(value)。

[...]

Portlet 可以生成三种类型的 URL:

  • renderURL:这是我们目前使用的 URL 类型。它仅使用其呈现阶段调用 portlet。
  • actionURL:这种类型的 URL 告诉 portlet 它应该在呈现页面中的所有 portlet 之前执行它的操作阶段。
  • resourceURL:此类 URL 可用于检索图像、XML、JSON 或任何其他类型的资源。它通常用于动态生成图像或其他媒体类型。向服务器发出 AJAX 请求也非常有用。与其他两种 URL 类型相比,这种 URL 类型的主要区别在于 portlet 可以完全控制将作为响应发送的数据。

所以我猜你正在使用 actionURL 而不是 renderURL 去页面 A2。

关于java - Struts2 portlet 正在执行 Liferay 刷新的默认操作(而不是其当前操作),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10206048/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com