对于一个项目,我正在更新一个有一些未解决问题的 Java Web 应用程序。我在使用 bean 的 init 方法时遇到问题,该方法在不应该被调用的情况下被调用。
导致问题的页面有三个按钮,可返回到您之前访问过的三个不同页面。其中两个按钮会调用您当前所在页面的 bean 的 init 方法。您必须再次按下按钮才能执行操作(=返回到另一页)。 奇怪的是:您可以通过两个菜单选项到达问题页面。一种方式会导致问题,另一种方式则不会。您可以毫无问题地返回到其他页面。
问题页面的 xhtml 片段:
<h:commandButton value="Show batch" action="/BatchDetail.xhtml" />
<h:commandButton value="Show messages" action="/BatchMessage.xhtml" />
<c:if test="#{batchMessageDetailBean.batch.part}">
<h:commandButton value="Show both" action="/BatchAndBatchMessage.xhtml" />
</c:if>
“显示批处理”和“显示消息”导致了该问题。第三个按钮仅通过导致前两个按钮出现问题的菜单选项出现。奇怪的是,这个按钮并没有再次调用init方法。
我读过有关“c:if”导致问题的信息,但是当我完全删除它时,没有任何变化。 该 bean 是@ViewScoped。 我没有使用Spring。如果您需要更多详细信息,请询问。
有什么想法吗?
最佳答案
<h:commandXxx>
组件通过 POST 请求提交父表单。整个页面中引用的任何请求范围的支持 bean 将在恢复 View 阶段重新初始化。并且,当使用早于 2.1.18 的 Mojarra 版本时,due to a chicken-egg bug, any view scoped beans referenced in view build time tags/attributes也将在恢复 View 阶段重新初始化。
因此,这是完全预期的行为。
这里的具体问题是这些按钮基本上被滥用于简单的页面到页面导航。您根本不想执行回发。您只想导航到不同的页面。为此,您应该使用 <h:button>
反而。这基本上就像一个 GET 链接。额外的好处是,浏览器地址栏中的 URL 将反射(reflect)到正确的 URL。
<h:button value="Show batch" outcome="/BatchDetail.xhtml" />
<h:button value="Show messages" outcome="/BatchMessage.xhtml" />
<h:button value="Show both" outcome="/BatchAndBatchMessage.xhtml" rendered="#{batchMessageDetailBean.batch.part}" />
请注意,我借此机会仅使用 rendered
来改进条件渲染。属性而不是 View 构建时间标记,这不仅可以解决您使用早于 2.1.18 的 Mojarra 版本时的问题,而且还有助于“使用正确的工具来完成工作”。
另请参阅:
关于jsf - 无缘无故调用@PostConstruct方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27624623/