我有一个 servlet,我想向 Web UI 提供数据。数据存储在一个 xml 文件中,我希望在几天内修改一次。我想在 servlet 中加载 xml 文件一次,并为每个请求提供服务,并且仅在我发送另一个“重新加载”请求时重新加载它。
根据我的阅读,servlet 中的静态变量是不好的做法。
我怎样才能达到我所需要的?
谢谢。
我真的开始不喜欢“坏习惯”这个词,因为它暗示我们可以在任何情况下评估某件事是否是坏的。这种情况很少发生 - 或者换句话说,如果 Java 语言的设计者认为静态字段总是不好的,他们就不会将它们包含在语言中。
在 servlet 中具有可变状态是完全可以的 - 但您必须记住,servlet 容器将使用 servlet 的相同对象实例来(同时)服务所有请求。
这意味着特定于请求的状态不应存储在 servlet 中,因为不同的请求处理线程会覆盖彼此的状态。但是,在您的情况下,您希望在所有请求之间共享状态,因此 servlet 中的字段是合适的。由于 servlet 由并发线程访问,因此您必须同步访问该可变共享状态。
servlet 只在 webapp 启动时创建一次,并在所有请求之间共享。无论是否静态,每个类/实例变量都将在所有请求/会话之间共享。您不想将请求/会话范围的数据分配给它们。而是将它们声明/分配为方法局部变量
您可以将数据放在 ServletContext 中,它是每个 Java 虚拟机的每个“Web 应用程序”的上下文(意味着全局)。
您可以使用单例模式或 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;
}
}
}
这不是熟悉的单例,但它使用相同的原理。
您可以定义实例成员或将属性存储到应用程序范围内,但它们都不是线程安全的。
只需创建一个静态变量,您无需再做任何事情