【发布时间】:2012-12-26 18:38:10
【问题描述】:
我想在应用程序范围内设置一些值。
我通过使用拦截器init() 方法进行了尝试。但它在下面的代码中给出了null 指针:
ServletActionContext.getContext().getApplication().put("ApplicationName", applName);
想要在所有会话中访问此字段。
【问题讨论】:
我想在应用程序范围内设置一些值。
我通过使用拦截器init() 方法进行了尝试。但它在下面的代码中给出了null 指针:
ServletActionContext.getContext().getApplication().put("ApplicationName", applName);
想要在所有会话中访问此字段。
【问题讨论】:
官方文档在这里:
不要在你的构造函数中使用
ActionContext.getContext()动作课。值可能未设置,调用可能返回getSession()为空。
https://struts.apache.org/docs/accessing-application-session-request-objects.html
看起来和ServletActionContext.getContext()一样。
【讨论】:
你可以这样做:
public class ContextListenerOne implements ServletContextListener {
ServletContext context;
@Override
public void contextInitialized(ServletContextEvent sce) {
context = sce.getServletContext();
try {
//Create a database connection here and run queries to retrieve data.
context.setAttribute("data", data); //Use setAttribute method to make this data available to everyone.
} catch(Exception e {
}
}
}
注意,你也可以通过下面不推荐的非常规方法来做。
由于整个过程中只创建了一个 Servlet 对象的实例,因此您可以像这样覆盖 init 方法:
@Override
public void init(ServletConfig config) throws ServletException {
super.init();
//Do all your database transactions here.
ServletContext c = config.getServletContext(); //Get the ServletContext.
c.setAttribute("data", data); //Make data available to all.
}
在 servlet 的生命周期中,无论发出多少请求,init 方法都只会被调用一次。
但是,请注意,如果您覆盖特定类型的 Servlet 的 init 方法,如果之前向另一个 Servlet(不是您覆盖 init 方法的类型)发出请求,您的数据库数据将不可用您覆盖了 init 方法的对 Servlet 的第一个请求。
【讨论】:
在应用启动时初始化数据的规范方法是使用ServletContextListener。
IMO 拦截器对此毫无意义:拦截器旨在在请求过程中实现跨应用程序的行为,而不是在启动时实现一次性功能。
【讨论】: