【问题标题】:How do I load and store global variables in Jersey/Glassfish如何在 Jersey/Glassfish 中加载和存储全局变量
【发布时间】:2013-05-12 02:22:04
【问题描述】:

我正在创建一个包装过时的供应商 API 的 RESTful Web 服务。将需要一些外部配置,并将其存储在服务器上的文件或 rdbms 中。我在 Glassfish 3.1.2 中使用 Jersey 1.11.1。这个配置数据都是String key/value格式。

我的第一个问题是 - 我可以在 Jersey 中的哪里存储全局/实例变量,以便它们在请求之间持久存在并可供所有资源使用?如果这是一个纯 Servlet 应用程序,我会使用 ServletContext 来完成。

问题的第二部分是如何在 Jersey 服务器加载后加载我的配置?同样,我的 Servlet 类比是找到与 init() 方法等效的方法。

【问题讨论】:

    标签: glassfish jersey jax-rs


    【解决方案1】:

    @Singleton @Startup EJB 符合您的要求。

    @Singleton
    @Startup // initialize at deployment time instead of first invocation
    public class VendorConfiguration {
    
        @PostConstruct
        void loadConfiguration() {
            // do the startup initialization here
        }
    
        @Lock(LockType.READ) // To allow multiple threads to invoke this method
                             // simultaneusly
        public String getValue(String key) {
        }
    }
    
    
    @Path('/resource')
    @Stateless
    public class TheResource {
        @EJB
        VendorConfiguration configuration;
        // ...
    }
    

    编辑:根据格雷厄姆的评论添加注释

    【讨论】:

    • 这看起来是一个很好的解决方案,它在加载时运行正常,但是当我尝试在我的资源类中引用这个 EJB 时,我得到了一个 InvocationTargetException(容器显示为 NullPointerException)。
    • 来自泽西邮件列表:默认情况下不支持注入 EE 资源,除非您将资源转换为托管 bean(请注意,将资源类转换为托管 bean)。
    • 一旦我在我的资源中添加了@Stateless 标志,它就可以完美运行,绝对是一个很好的解决方案。这两页也帮助我更好地理解了这些概念:EJB 3.1 AND REST - THE LIGHTWEIGHT HYBRIDSingletons
    【解决方案2】:

    您可以使用listener 来初始化变量,并在 Web 应用程序启动之前将其设置为上下文作为属性,如下所示:

    package org.paulvargas.shared;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.ServletContext;
    import javax.servlet.ServletContextEvent;
    import javax.servlet.ServletContextListener;
    
    public class LoadConfigurationListener implements ServletContextListener {
    
        public void contextInitialized(ServletContextEvent sce) {
            // read file or rdbms
            ...
            ServletContext context = sce.getServletContext();
            // set attributes
            ...
        }
    
        public void contextDestroyed(ServletContextEvent sce) {
            ServletContext context = sce.getServletContext();
            // remove attributes
            ...
        }
    
    }
    

    这个监听器是在web.xml中配置的。

    <listener>
        <listener-class>org.paulvargas.shared.LoadConfigurationListener</listener-class>
    </listener>
    

    您可以使用@Context 注解注入ServletContext 并检索属性。

    package org.paulvargas.example.helloworld;
    
    import java.util.*;
    
    import javax.servlet.ServletContext;
    import javax.ws.rs.*;
    import javax.ws.rs.core.*;
    
    @Path("/world")
    public class HelloWorld {
    
        @Context
        private ServletContext context;
    
        @GET
        @Produces("text/plain; charset=UTF-8")
        public String getGreeting() {
    
            // get attributes
            String someVar = (String) context.getAttribute("someName")
    
            return someVar + " says hello!";
        }
    
    }
    

    【讨论】:

    • 这绝对是一个可行的解决方案,但它涉及添加一个我目前没有的 web.xml 以及一些额外的工作以过滤掉 ServletContext 中存在的其他属性。我对此投了赞成票,但不得不将答案授予另一篇帖子,因为它既简单又通用。
    猜你喜欢
    • 2016-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    相关资源
    最近更新 更多