ServletContext 变量对其他 servlet 不可见



假设我有两个servlet,A和B。在 Servlet A 中,我创建了一个 HashMap 并存储在 init() 中的 Servlet 上下文中,如下所示:

ServletContext context = getServletContext();
context.setAttribute("otable", someObject);

现在在 Servlet B 的 init() 中,我正在初始化对 servlet 上下文对象的本地引用(我指定首先创建 servlet 上下文对象的 servlet 首先通过 web.xml 启动):

// get and set reference to object cache
oc = (ObjectCache)getServletContext().getAttribute("otable");

然后我插入,大小变为 1。 当再次调用 Servlet A 并检查 servlet 上下文 HashMap 时,大小仍为 0。

存储对 servlet 上下文对象的本地引用是一个坏主意吗?我也尝试直接从servlet上下文中获取对象,但得到了相同的结果。 我在这里错过了什么?

创建共享对象的 servlet 首先在我的 web 中启动.xml如下所示:

<servlet>
<servlet-name>ServletA</servlet-name>
<servlet-class>package.ServletA</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>

在 ServletContext 中存储跨 servlet 又名应用程序范围对象的想法是完全可行的。我重新测试了你的方法,它完全有效。你一定错过了代码中忘记发布的东西。

我可以使其按如下方式工作:

ServletA (snip):

public void init() throws ServletException {
Map<String, String> map = new ConcurrentHashMap<>();
getServletContext().setAttribute("map", map);
System.out.println("Servlet A Mapsize: " + map.size());
map.put("foo", "bar");
System.out.println("Servlet A Mapsize: " + map.size());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map<String, String> map = (Map<String, String>) getServletContext().getAttribute("map");
System.out.println("Servlet A Mapsize: " + map.size());
}

ServletB (snip):

public void init() throws ServletException {
Map<String, String> map = (Map<String, String>) getServletContext().getAttribute("map");
System.out.println("Servlet B Mapsize: " + map.size());
map.put("foo", "bar");
System.out.println("Servlet B Mapsize: " + map.size());
}

网络.xml(截图):

<servlet>
<servlet-name>ServletA</servlet-name>
<servlet-class>mypackage.ServletA</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet>
<servlet-name>ServletB</servlet-name>
<servlet-class>mypackage.ServletB</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletA</servlet-name>
<url-pattern>/a</url-pattern>
</servlet-mapping>

启动应用程序将提供以下输出:

Servlet A 映射大小: 0

Servlet A 映射大小:1

Servlet B 映射大小: 1

Servlet B 映射大小: 1

如您所见,地图已正确填充。

现在你可以调用servletA来检查一切是否正常。

在浏览器中打开(我的设置):

http://localhost:8080/servtest/a

将产生以下输出

Servlet A 映射大小:1

顺便说一句,有了CDI,你可以编写你的applicationScoped缓存生产者,以获得更易于维护的代码。

相关内容

最新更新