【发布时间】:2015-09-21 08:59:26
【问题描述】:
我想初始化 Jersey Rest 服务并引入一个全局应用程序范围的变量,该变量应该在应用程序启动时计算,并且应该在每个休息资源和每个方法中都可用(这里由整数 globalAppValue=17 表示,但以后会是一个复杂的对象)。
为了在启动时初始化服务并计算一次值,我发现了两种做法:通用 ServletContextListener 和 Jersey ResourceConfig 方法。但是我一直不明白他们两个有什么区别?两种方法都在启动时触发(打印两个 System.out 消息)。
这是我的 ServletContextListener 的实现,它工作正常:
public class LoadConfigurationListener implements ServletContextListener
{
private int globalAppValue = 17;
@Override
public void contextDestroyed (ServletContextEvent event)
{
}
@Override
public void contextInitialized (ServletContextEvent event)
{
System.out.println ("ServletContext init.");
ServletContext context = event.getServletContext ();
context.setAttribute ("globalAppValue", globalAppValue);
}
}
这是 Jersey Rest ResourceConfig 方法的实现,其中 ServletContext 不可用。以后也不能通过注入资源方法来获得此应用程序对象:
@ApplicationPath("Resources")
public class MyApplication extends ResourceConfig
{
@Context
ServletContext context;
private int globalAppValue = 17;
public MyApplication () throws NamingException
{
System.out.println ("Application init.");
// returns NullPointerException since ServletContext is not injected
context.setAttribute ("globalAppValue", 17);
}
public int getAppValue ()
{
return globalAppValue;
}
}
这是我希望在资源方法中访问全局值的方式:
@Path("/")
public class TestResource
{
@Context
ServletContext context;
@Context
MyApplication application;
@Path("/test")
@GET
public String sayHello () throws SQLException
{
String result = "Hello World: ";
// returns NullPointerException since application is not injected
result += "globalAppValue=" + application.getAppValue ();
// works!
result += "contextValue=" + context.getAttribute ("globalAppValue");
return result;
}
}
因此,虽然经典的 ServletContextListener 工作正常,但我在使用 ResourceConfig/Application 时遇到了一些问题,但我更喜欢这种方式,因为它似乎更本机地集成到 Jersey 中。所以我的问题是哪种方式是最好的做法。谢谢!
【问题讨论】: