2015-09-21 65 views
4

我想初始化Jersey Rest服务并引入应用程序启动时应计算的全局应用程序范围的变量,并且应该在每个其余资源和每个方法中都可用(这里用整数globalAppValue = 17表示,但稍后会是一个复杂的对象)。Jersey Rest服务的ResourceConfig和ServletContextListener之间的区别

为了初始化服务并在启动时计算一次值,我发现了两种做法:一般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); 
    } 
} 

这是泽西休息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中。所以我的问题是使用哪种方式是最佳做法。谢谢!

回答

4

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

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"); 
    } 
} 

而且通过使用关于ResourceConfigproperty方法,该属性被放入一个全局javax.ws.rs.core.Configuration对象,这也是可注射的。因此,而不是Application,你可以注入Configuration

@Path("/") 
public class TestResource 
{ 
    @Context 
    Configuration config; 

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

另请参见:

+0

Thanx,这种方式的作品!但是在泽西休息网络服务中哪种方法更受欢迎? ServletContextListener或Application-ResourceConfig方式? –

+0

我更喜欢与泽西岛坚持。如果你不需要,不需要使用servlet容器。它就像穷人的依赖注入。泽西岛拥有处理DI的所有能力。 –

+0

我似乎又被卡住了:当我使用'property(“value”,17);'在公共类Application的构造函数中扩展ResourceConfig'时,我可以立即重读属性,但不是在我的Resource-method中。有注入'@Context应用程序应用程序;'工作(应用程序不为空),但application.getProperties()返回null。那么在Application类中是否有特殊的注释?您能否将您上一个示例中的Application类扩展为带有注释和导入的完整类? –

0

no 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>(无*)分别改变

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

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

+0

我不知道它适用于我。在我发布答案之前进行了测试。现在再来确定。 S.o.p(getProperties())正在打印? –

+0

是的,该调试输出ist正确打印... –

+0

也许在web.xml或context.xml中需要一些其他资源或配置? –

相关问题