Jersey Rest Service的ResourceConfig和ServletContextListener之间的区别

tom*_*189 4 java rest jersey

我想初始化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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Jersey Rest ResourceConfig方法的实现,其中ServletContext不可用.以后可以通过使用资源方法注入来提供此Application对象:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我希望在资源方法中获取全局值的方式:

@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;
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,虽然经典的ServletContextListener工作正常但我使用ResourceConfig/Application时遇到了一些问题,但是更喜欢这种方式,因为它似乎更多地本地集成到Jersey中.所以我的问题是哪种方式是最佳实践.谢谢!

Pau*_*tha 5

您只需ResourceConfig通过调用即可设置属性property( key, value ).

public MyApplication() {
    property("MyProp", "MyValue");
}
Run Code Online (Sandbox Code Playgroud)

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

然后你可以做的是调用标准ApplicationAPI方法之一来获取设置属性.该方法当然是命名的getProperties(),它返回属性的映射.

@Path("/")
public class TestResource
{
    @Context
    Application application;

    @GET
    public String get() {
        String value = (String)application.getProperties().get("MyProp");
    }
}
Run Code Online (Sandbox Code Playgroud)

同样通过使用该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");
    }
}
Run Code Online (Sandbox Code Playgroud)

也可以看看: