我们正在使用ApplicationListener来加载一些定时器库,这些库将对某些bean进行常规后台工作。但是在applicationCreated中,我们似乎无法通过ApplicationEx对象找到进入ServletContext的方法。有许多不赞成使用的方法看起来会有所帮助。有没有人知道在applicationCreated方法期间如何从ApplicationEx遍历FacesContext或外部ServletContext?
答案 0 :(得分:1)
似乎,没有办法从ApplicationEx获取FacesContext或ServletContext。
ServletContextListener在初始化Web应用程序时提供ServletContext但不幸的是,XPage不支持这种监听器。
那么,ApplicationListener和应用程序作用域托管bean的组合呢?
首先,ApplicationListener将启动。然后,如果在用户可以首先调用的每个页面的beforePageLoad事件中“调用”托管bean,则将对其进行实例化。这时候 托管bean能够使用
获取ApplicationListener对象(ApplicationEx)(FacesContext.getCurrentInstance().getApplication()).getApplicationListeners()
并且可以在ApplicationListener中运行一个方法来获取FacesContext,ExternalContext和bean。 ApplicationListener可以在FacesContext / ExternalContext的帮助下启动所有操作(例如计时器库),并将上下文和/或bean保存为ApplicationListener对象中的字段。在applicationDestroyed()时,仍然可以使用上下文或“关闭”托管bean。
以下是一个例子:
ApplicationListener“MyApplicationListener”
package com.knutherrmann.listener;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import com.ibm.xsp.application.ApplicationEx;
import com.ibm.xsp.application.events.ApplicationListener;
public class MyApplicationListener implements ApplicationListener {
private FacesContext facesContext;
private ExternalContext externalContext;
private AppBean app;
public void applicationCreated(ApplicationEx arg0) {
System.out.println("applicationCreated(" + arg0.getApplicationId() + ") in MyApplicationListener");
}
public void applicationDestroyed(ApplicationEx arg0) {
System.out.println("applicationDestroyed(" + arg0.getApplicationId() + ") in MyApplicationListener");
System.out.println("...FacesContext: " + facesContext);
System.out.println("...ExternalContext: " + externalContext);
System.out.println("...AppBean: " + app);
app.stop();
}
public void initContext(AppBean app) {
facesContext = FacesContext.getCurrentInstance();
externalContext = facesContext.getExternalContext();
this.app = app;
System.out.println("initContext() in MyApplicationListener");
System.out.println("...FacesContext: " + facesContext);
System.out.println("...ExternalContext: " + externalContext);
System.out.println("...AppBean: " + app);
}
}
应用程序作用域的托管bean“app”作为“AppBean”类的实例
package com.knutherrmann.listener;
import java.io.Serializable;
import javax.faces.context.FacesContext;
import com.ibm.xsp.application.ApplicationEx;
import com.ibm.xsp.application.events.ApplicationListener;
public class AppBean implements Serializable {
private static final long serialVersionUID = 1L;
public AppBean() {
ApplicationEx app = (ApplicationEx) FacesContext.getCurrentInstance().getApplication();
for (ApplicationListener listener : app.getApplicationListeners()) {
if (listener instanceof MyApplicationListener) {
MyApplicationListener myApplicationListener = (MyApplicationListener) listener;
myApplicationListener.initContext(this);
}
}
}
public void start() {
}
public void stop() {
System.out.println("AppBean stopped");
}
}
的XPage
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core"
beforePageLoad="#{app.start}">
Test MyApplicationListener and AppBean
</xp:view>
服务器控制台的输出
07:23:44 HTTP JVM: applicationCreated(32) in MyApplicationListener
07:23:44 HTTP JVM: initContext() in MyApplicationListener
07:23:44 HTTP JVM: ...FacesContext: com.ibm.xsp.domino.context.DominoFacesContext@f850f85
07:23:44 HTTP JVM: ...ExternalContext: com.ibm.xsp.domino.context.DominoExternalContext@13891389
07:23:44 HTTP JVM: ...AppBean: com.knutherrmann.listener.AppBean@22c522c5
07:54:06 HTTP JVM: applicationDestroyed(32) in MyApplicationListener
07:54:06 HTTP JVM: ...FacesContext: com.ibm.xsp.domino.context.DominoFacesContext@f850f85
07:54:06 HTTP JVM: ...ExternalContext: com.ibm.xsp.domino.context.DominoExternalContext@13891389
07:54:06 HTTP JVM: ...AppBean: com.knutherrmann.listener.AppBean@22c522c5
07:54:06 HTTP JVM: AppBean stopped
答案 1 :(得分:0)
我们使用服务器的预加载xpage功能(bit.ly/10rfvEs)但不创建会话,因此从不存在FacesContext(获取当前实例返回null)。所以我们做了一些技巧来从监听器打开一个返回应用程序的链接,然后创建了我们需要的第一个会话和应用程序范围。