【发布时间】:2016-06-26 02:39:14
【问题描述】:
有没有办法在页面加载时执行 JSF 托管 bean 操作?
如果相关,我目前正在使用 JSF 1.2。
【问题讨论】:
-
不确定,这个问题有歧义。只要他没有明确说明“在页面加载时下载文件”,或者“在页面加载时触发新请求”等,那么所提到的主题就不一定是这个问题。
标签: jsf action onload managed-bean
有没有办法在页面加载时执行 JSF 托管 bean 操作?
如果相关,我目前正在使用 JSF 1.2。
【问题讨论】:
标签: jsf action onload managed-bean
从<p:remoteCommand> 调用 bean 操作是个好主意,保留属性 autoRun="true"
下面的例子
<p:remoteCommand autoRun="true" name="myRemoteCommand" action="#{bean.action}" partialSubmit="true" update=":form" />
【讨论】:
只需将所需的逻辑放入与 JSF 页面关联的请求范围 bean 的构造函数中即可。
public Bean() {
// Do your stuff here.
}
在请求或视图范围 bean 上使用 @PostConstruct 注释方法。它将在构造和所有托管属性和注入的依赖项的初始化/设置之后执行。
@PostConstruct
public void init() {
// Do your stuff here.
}
如果您使用的是使用代理(例如 CDI)的 bean 管理框架,强烈建议使用此方法而不是构造函数,因为构造函数可能不会在您期望的时间被调用。
或者,使用<f:event type="preRenderView"> 以防您也打算基于<f:viewParam> 进行初始化,或者当bean 放置在比视图范围更广的范围内(这反过来表明存在设计问题,但除此之外)。否则,@PostConstruct 也可以。
<f:metadata>
<f:viewParam name="foo" value="#{bean.foo}" />
<f:event type="preRenderView" listener="#{bean.onload}" />
</f:metadata>
public void onload() {
// Do your stuff here.
}
或者,使用<f:viewAction> 以防您也打算基于<f:viewParam> 进行初始化,或者当bean 放置在比视图范围更广的范围内(这反过来表明存在设计问题,但除此之外)。否则,@PostConstruct 也可以。
<f:metadata>
<f:viewParam name="foo" value="#{bean.foo}" />
<f:viewAction action="#{bean.onload}" />
</f:metadata>
public void onload() {
// Do your stuff here.
}
请注意,如有必要,这可以返回 String 导航案例。它将被解释为重定向(因此您在这里不需要?faces-redirect=true)。
public String onload() {
// Do your stuff here.
// ...
return "some.xhtml";
}
load 事件期间执行 bean 操作方法,而不是在页面加载期间。【讨论】:
ui:composition 页面中放置f:metadata 信息的位置感到好奇的人:在ui:composition 和之前 可能的ui:define 或类似标签之后。
另一个简单的方法是在视图渲染之前使用 fire 方法。这比 postConstruct 更好,因为对于 sessionScope,postConstruct 只会在每个会话中触发一次。每次加载页面时都会触发。当然,这仅适用于 JSF 2.0,不适用于 JSF 1.2。
这是怎么做的-
<html xmlns:f="http://java.sun.com/jsf/core">
<f:metadata>
<f:event type="preRenderView" listener="#{myController.onPageLoad}"/>
</f:metadata>
</html>
并且在 myController.java
public void onPageLoad(){
// Do something
}
编辑 - 虽然这不是此页面上问题的解决方案,但我仅为使用更高版本 JSF 的人添加此内容。
JSF 2.2 有一个新功能,它使用viewAction 执行此任务。
<f:metadata>
<f:viewAction action="#{myController.onPageLoad}" />
</f:metadata>
【讨论】:
@PostConstruct 在创建 Bean 时首先运行一次。 解决方案是创建一个未使用的属性并在该属性的 Getter 方法中执行您的操作 并将此属性添加到您的 .xhtml 文件中,如下所示:
<h:inputHidden value="#{loginBean.loginStatus}"/>
在你的 bean 代码中:
public void setLoginStatus(String loginStatus) {
this.loginStatus = loginStatus;
}
public String getLoginStatus() {
// Do your stuff here.
return loginStatus;
}
【讨论】:
@PostConstruct 中完成工作。