将带有 Ajax4jsf 1.x 的 JSF 1.1 迁移到 JSF 2

Posted

技术标签:

【中文标题】将带有 Ajax4jsf 1.x 的 JSF 1.1 迁移到 JSF 2【英文标题】:Migrating JSF 1.1 with Ajax4jsf 1.x to JSF 2 【发布时间】:2013-07-07 08:14:36 【问题描述】:

我们正在将 JSF 1.1 (MyFaces) 项目迁移到 JSF 2。这个想法是通过将 JSP 和 Xhtml 保持一段时间来定期迁移。我们在 JSP 页面中使用了许多 ajax4jsf-1.1.1 标签。我们不使用 RichFaces。将系统配置为 JSF 2 后(Balusc 在教程中提到的所有配置更改)当尝试使用类路径中的 ajax4jsf.jar 访问 JSP 页面时,我们得到一个异常:

Caused by: java.lang.IllegalStateException: setViewHandler may not be executed after a lifecycle request has been completed
    at org.apache.myfaces.application.ApplicationImpl.setViewHandler(ApplicationImpl.java:853)
    at org.ajax4jsf.framework.ajax.InitPhaseListener.beforePhase(InitPhaseListener.java:92)
    at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersBefore(PhaseListenerManager.java:76)
    at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:131)

看起来 ajax4jsf.jar 与 JSF 2 不兼容。LifeCycle 配置看起来有些问题。

有什么方法可以让 a4j 与 JSF 2 JSP 一起工作?我知道当我们使用 XHTML 时,我们不需要所有这些。

【问题讨论】:

你试过用 RichFaces 4 代替 ajax4jsf 吗? 是的,很快就试过了。但是面临着使用 JSP 进行导航和操作处理的问题。没有深入研究它,因为我们计划将来使用 primefaces 并且目前不想冒险进入 Richfaces。 只是为了让你知道,RichFaces 吸收了 ajax4jsf 项目。我不明白为什么不冒险进入 RichFaces。 担心我们最终可能会同时拥有 RF 和 PF。知道 RichFaces 4 a4j 标签是否适用于 JSP? RF 和 PF 都没有问题。我建议您首先尝试让它发挥作用来解决您当前的问题,然后开始关注新的迁移问题(这不会很难如果那让你担心的话),而不是一直问,什么也不做。 【参考方案1】:

完全摆脱 Ajax4jsf 1.x。它确实与 JSF2 不兼容。相反,JSF2 提供了一个新的主 ajax 标记 <f:ajax>,它涵盖了 Ajax4jsf 1.x 之前提供的所有核心功能。

如果升级到 RichFaces 4 不是一个选项(因为,正如您自己所说,您没有在任何地方使用 RichFaces 组件),那么只需删除 Ajax4jsf 1.x 并将所有 <a4j:xxx> 标记替换为标准 JSF2 等效项。

<a4j:ajaxListener>:使用<f:ajax listener><a4j:keepAlive>:只需将托管 bean 放在 @ViewScoped 的视图范围内即可。 <a4j:log>:在 JS 上下文中使用 jsf.ajax.addOnEvent()jsf.ajax.addOnError()<a4j:commandLink>:只需将 <f:ajax> 嵌套在 <h:commandLink> 内。 <a4j:outputPanel>:使用 <h:panelGroup> 并记住在 <f:ajax render> 或 PrimeFaces <p:outputPanel> 中包含其 ID。 <a4j:repeat>:使用标准的<ui:repeat><a4j:form>:使用<h:form>,它会自动识别<f:ajax><a4j:htmlCommandLink>:只需将<f:ajax> 嵌套在<h:commandLink> 内。 <a4j:jsFunction>:没有替代品。考虑OmniFaces <o:commandScript> 或PrimeFaces <p:remoteCommand><a4j:region>:只需使用<f:ajax execute>,您甚至可以将<f:ajax> 包裹在一组组件周围。 <a4j:loadBundle>:使用标准的<f:loadBundle><a4j:status>:在 JS 上下文中使用 jsf.ajax.addOnEvent()jsf.ajax.addOnError()<a4j:actionparam>:使用标准的<f:param><a4j:loadScript>:使用标准的<h:outputScript><a4j:mediaOutput>:没有替代品。考虑PrimeFaces <p:media><a4j:poll>:没有替代品。考虑OmniFaces <o:commandScript> 或PrimeFaces <p:poll><a4j:commandButton>:只需将 <f:ajax> 嵌套在 <h:commandButton> 内。 <a4j:include>:使用标准的<ui:include><a4j:loadStyle>:使用标准的<h:outputStylesheet><a4j:support>:使用标准的<f:ajax>

您还需要将 JSP 文件重命名/重写为 Facelets 文件。在简单的情况下,这通常只是更改根声明和文件扩展名的问题。 Facelets 可以更轻松地用单个模板替换所有重复的代码。以下答案适用:

Migrating from JSF 1.2 to JSF 2.0

【讨论】:

但是如果我理解正确的话, 标签在 JSP 中就不起作用了,对吧?是否有任何适用于 JSP 的解决方案(而不是将 JSP 重新实现为 XHTML)? JSP 在 JSF2 中已被弃用。因此,确实希望您也迁移到 Facelets。这可能会有所帮助:***.com/questions/4441713/… 一直在寻找一种方法,当我们迁移到 XHTML 时,我们可以将现有的带有 a4j 标签的 JSP 保留一段时间。看来没有办法了。不确定升级到 RichFaces 只是为了支持 JSP 页面中的 a4j 标记。 感谢您对更换a4j标签的详细回答,这对我们将来一定会有所帮助。

以上是关于将带有 Ajax4jsf 1.x 的 JSF 1.1 迁移到 JSF 2的主要内容,如果未能解决你的问题,请参考以下文章

安装 Richfaces 后,“Palette”不显示 Richfaces 或 Ajax4Jsf 库

RichFaces CVE-2018-14667

JSF 1.x 通用异常处理

如何在 JSF 1.x 中对页面加载进行重定向

带有 JSF 项目的组件库

我应该使用带有 render 属性的 ui:fragment 来有条件地在带有 JSF 2.2 的 Facelets 中呈现 HTML 标记吗?