我要初始化Jersey Rest服务并引入一个全局应用程序范围的变量,该变量应在应用程序启动时进行计算,并且应在每个rest资源和每个方法中可用(此处由整数globalAppValue = 17表示,但是将一个复杂的对象)。

为了初始化服务并在启动时计算一次值,我发现了两种做法:常规ServletContextListener和Jersey ResourceConfig方法。但是我不明白两者之间的区别是什么?两种方法都在启动时触发(同时打印System.out-messages)。

这是我的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中,所以会更喜欢这种方式。所以我的问题是哪种方法将是最佳实践。谢谢!

最佳答案

您只需调用 ResourceConfig 即可在property( key, value )中设置属性。

public MyApplication() {
    property("MyProp", "MyValue");
}

在您的资源类中,只允许您注入javax.ws.rs.core.Application扩展的超抽象类 ResourceConfig

然后,您可以做的是调用标准Application API方法之一来获取设置属性。该方法当然称为 getProperties() ,它返回属性映射。
@Path("/")
public class TestResource
{
    @Context
    Application application;

    @GET
    public String get() {
        String value = (String)application.getProperties().get("MyProp");
    }
}

同样,通过在property上使用ResourceConfig方法,将该属性放入全局 javax.ws.rs.core.Configuration 对象中,该对象也可以注入。因此,您可以注入Application而不是Configuration
@Path("/")
public class TestResource
{
    @Context
    Configuration config;

    @GET
    public String get() {
        String value = (String)config.getProperty("MyProp");
    }
}

另请参见:
  • Using a custom hk2 InjectionResolver to inject application configuration提供一些其他有趣的方式来仅注入值,而不必从ApplicationConfiguration
  • 中检索它

    08-27 14:04