Jersey Rest Service

时间:2015-09-21 08:59:27

标签: java rest jersey

我想初始化Jersey Rest服务并引入一个全局应用程序范围的变量,该变量应该在应用程序启动时计算,并且应该在每个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不可用。以后,这个Application-object也不能通过资源方法注入来实现:

@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中。所以我的问题是哪种方式是最佳实践。谢谢!

2 个答案:

答案 0 :(得分:5)

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

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

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

然后你可以做的是调用标准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");
    }
}

另见:

答案 1 :(得分:0)

没有sory,如果调用GET / test /,这会产生“value = null”作为输出。

package rest;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.Context;

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

    @GET
    public String sayHello () 
    {
        String result = "value=" + application.getProperties ().get ("value");

        return result;
    }
}

ApplicationPath在这里设置为“资源”?

package rest;

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("resources")
public class MyApplication extends ResourceConfig
{
    public MyApplication ()
    {
        property ("value", 17);
        System.out.println (getProperties ());
    }
}

编辑:对于那些关注我们讨论的人,解决方法/问题如下。使用我的web.xml的servlet部署,首先我写错了

<servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

删除*并将url-pattern更改为<url-pattern>/</url-pattern>(不带*)并分别更改

@ApplicationPath("/")
public class MyApplication extends ResourceConfig
它终于成功了。因此,ApplicationPath必须与web.xml中的Servlet-Url相同,才能正确完成方法类中的注入。