【问题标题】:How to store static data in a servlet and share it between all sessions/requests?如何将静态数据存储在 servlet 中并在所有会话/请求之间共享?
【发布时间】:2013-05-12 10:37:06
【问题描述】:

我有一个 servlet,我想向 Web UI 提供数据。 数据存储在一个 xml 文件中,我希望在几天内修改一次。 我想在 servlet 中加载 xml 文件一次,并为每个请求提供服务,并且仅在我发送另一个“重新加载”请求时重新加载。

根据我的阅读,servlet 中的静态变量是不好的做法。

我怎样才能达到我的需要?

谢谢。

【问题讨论】:

    标签: java servlets


    【解决方案1】:

    我真的开始讨厌“不良做法”一词,因为它暗示我们可以在任何情况下评估某事是否是不良行为。这种情况很少发生——或者换句话说,如果 Java 语言的设计者认为静态字段总是不好的,他们就不会将它们包含在语言中。

    在 servlet 中具有可变状态是完全可以的 - 但您必须记住,servlet 容器将使用 servlet 的相同对象实例来(同时)处理所有请求。

    这意味着特定于请求的状态不应存储在 servlet 中,因为不同的请求处理线程会覆盖彼此的状态。但是,在您的情况下,您希望在所有请求之间共享状态,因此 servlet 中的字段是合适的。由于 servlet 由并发线程访问,因此您必须同步访问该可变共享状态。

    【讨论】:

    • 如何同步访问 servlet 中的数据?只需用同步包装方法?
    • 如何编写正确的线程安全代码超出了此答案的范围。 Java 教程有一个introduction 主题。
    【解决方案2】:

    一个 servlet 只在 webapp 启动时创建一次,并在所有请求之间共享。无论是否静态,每个类/实例变量都将在所有请求/会话之间共享。您不想将请求/会话范围的数据分配给它们。而是将它们声明/分配为方法局部变量

    SEE HERE

    【讨论】:

      【解决方案3】:

      你可以把数据放在 ServletContext 中,它是每个 Java 虚拟机的每个“Web 应用程序”的上下文(意味着全局)。

      在这里查看用法:http://www.javatpoint.com/servletcontext

      【讨论】:

        【解决方案4】:

        您可以使用单例模式或 CDI 应用程序范围的 bean,具体取决于您的环境。

        不要忘记线程安全。

        public class ServletSingleton {
            private static ServletSingleton instance = new ServletSingleton();
        
            //Here is your data objects
            private Object firstDataObject;
            private Object secondDataObject;
        
            public static Object getFirstDataObject(){
                synchronized (instance){
                    return instance.firstDataObject;
                }
            }
        
            public static Object getSecondDataObject(){
                synchronized (instance){
                    return instance.secondDataObject;
                }
            }
        
            public static void setFirstDataObject(Object dataObject){
                synchronized (instance){
                    instance.firstDataObject = dataObject;
                }
            }
        
            public static void setSecondDataObject(Object dataObject){
                synchronized (instance){
                    instance.secondDataObject = dataObject;
                }
            }
        }
        

        这不是我们熟悉的单例,但它使用相同的原理。

        【讨论】:

        • 是的,当然。我编辑了我的答案,所以现在它包含线程安全准单例的示例。
        【解决方案5】:

        只需创建一个静态变量,您无需再做任何事情

        【讨论】:

          【解决方案6】:

          您可以定义实例成员或将属性存储到应用程序范围内,但它们都不是线程安全的。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2020-09-11
            • 1970-01-01
            • 2011-08-16
            • 1970-01-01
            • 1970-01-01
            • 2010-12-01
            相关资源
            最近更新 更多