当前位置: 首页 > 知识库问答 >
问题:

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

凌朗
2023-03-14

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

  1. 我在页面上有一个Struts2 portlet a,它的默认“索引”操作是pageA1

症状:

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

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

旧细节

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

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

  1. 单击Portlet a上的链接。

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

编辑:我单击的链接是renderUrl(使用s:url标记生成)。这两个portlet的第二页都包含表单,我不确定这些表单是否有任何意义。

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

这是我的支柱。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都有一个链接,该链接调用strut操作“displayForm”。FirstPageAction的执行方法返回SUCCESS,而第二个PageAction的执行方法返回INPUT。

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

大声想一想,如果我在渲染B2时单击A1的链接,应该调用B2的渲染/执行操作,但看起来B1的渲染/执行操作被调用了。

共有1个答案

司寇昱
2023-03-14

检查http://www.liferay.com/documentation/liferay-portal/6.0/development/-/ai/understanding-the-two-phases-of-portlet-execution,具体如下:

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

  • 操作阶段:操作阶段一次只能为一个portlet调用,并且通常是用户与portlet交互的结果。在此阶段,portlet可以更改其状态,例如更改portlet的用户首选项。还建议在此阶段执行数据库中的任何插入和修改或不应重复的操作

[...]

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

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

因此,我猜您使用的是actionURL来转到A2页,而不是renderURL。

 类似资料:
  • 我有一个名为“客户列表”的组件,其中显示了API中的所有客户: 客户列表。html customers-list.ts 我有另一个名为“添加客户”的组件,我将在其中添加新客户,如下所示: 现在,POST操作正常,但如果不刷新页面,则不会更新客户列表。 如何在成功执行操作后更新组件,而无需刷新整个页面? 服务文件:

  • 根据对条件dplyr评估的讨论,我想根据传递的数据帧中是否存在参考列,有条件地在管道中执行一个步骤。 和生成的结果应该是相同的。 对于可用列,传递的对象与初始数据帧不对应。原始代码返回错误消息: :未找到对象 我尝试过其他语法(运气不佳): 我想扩展这个问题,以解释调用中右侧的评估。例如,下面的语法试图过滤第一个可用值。mtcars% 预期的是,调用的结果是错误消息: 中出错:结果的长度必须为32

  • 问题内容: 我有一个http服务器(使用启动),我想做一些操作。 我该怎么做(在Linux上)?在ctrl-C的情况下可以进行那些操作吗? 我不熟悉Unix信号,因此答案可能很简单。 问题答案: 您可以使用信号包订购TERM和INT信号。但是请注意,只有在明确终止进程时才发送这些信号。正常退出(由流程本身启动)不涉及任何信号。我认为,对于正常退出,只需在主例程中执行某些操作即可(该例程应该生成工作

  • 我在一个项目中工作,我需要要求用户输入一个路径来使用jOptionPane保存程序,但我的问题是,如果用户没有在文本中添加任何内容,然后单击取消或确定,将得到一个错误...我试图控制它,检查字符串是否为空()或等于空

  • Redisson 支持对每个操作自动重试的策略并且在每次尝试期会尝试发送命令。 重试策略由设置项 retryAttempts (默认为 3) 和 retryInterval (默认为 1000 ms) 来控制。 每次尝试会在 retryInterval 时间间隔后执行。 Redisson 实例和 Redisson 对象都是完全线程安全的。 带有同步/异步方法的 Redisson 对象可通过 Red

  • 我有一个while循环,它运行一些代码,而selector是隐藏的,即。 如何在这里添加超时,使//do在运行前延迟? 我想这样做,因为我发现代码运行太快,无法找到选择器。。。