我想初始化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中。所以我的问题是哪种方式是最佳实践。谢谢!
答案 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");
}
}
另见:
Application
或Configuration
答案 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相同,才能正确完成方法类中的注入。