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

我想初始化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不可用。 以后,通过使用资源方法注入,此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; } } 

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

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

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

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

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

然后你可以做的是调用Application API方法之一来获取set属性。 当然,该方法名为getProperties() ,它返回属性的映射。

 @Path("/") public class TestResource { @Context Application application; @GET public String get() { String value = (String)application.getProperties().get("MyProp"); } } 

此外,通过在ResourceConfig上使用property方法,该属性将放入全局javax.ws.rs.core.Configuration对象,该对象也是可注入的。 因此,您可以注入Configuration ,而不是Application

 @Path("/") public class TestResource { @Context Configuration config; @GET public String get() { String value = (String)config.getProperty("MyProp"); } } 

也可以看看:

  • 使用自定义hk2 InjectionResolver为一些其他有趣的方法注入应用程序配置 ,只注入值而不必从ApplicationConfiguration检索它

没有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部署,首先我写错了

  Jersey REST Service /*  

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

 @ApplicationPath("/") public class MyApplication extends ResourceConfig 

它终于成功了。 因此,ApplicationPath必须与web.xml中的Servlet-Url相同,才能正确完成方法类中的注入。