zig*_*ggy 1 java session tomcat servlets
我正在尝试编写一个简单的程序,我可以在应用程序范围的会话中放置HashMap,并获得两个应用程序/上下文,因为两个war文件访问HashMap.
Servlet 1
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{
PrintWriter out = response.getWriter();
HashMap<String ,String> hm = new HashMap<String, String>();
hm.put("1", "1");
this.getServletContext().setAttribute("usermanager", hm);
this.getServletConfig().getServletContext().setAttribute("usermanager2", hm);
}
Run Code Online (Sandbox Code Playgroud)
Servlet 2
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException{
HashMap newMap2 = (HashMap) this.getServletConfig().getServletContext().getAttribute("usermanager");
HashMap newMap3 = (HashMap) this.getServletContext().getAttribute("usermanager2");
System.out.println("newmap2 size " + newMap2.size());
System.out.println("newmap3 size " + newMap3.size());
}
Run Code Online (Sandbox Code Playgroud)
为了测试这一点,我重新启动了Tomcat 6,然后首先运行访问Servlet 1,以便初始化Hashmap对象.当我随后访问Servlet 2时,我得到一个NULL-POINTER错误,指向我试图调用newMap2.size()的行号
我究竟做错了什么?
java.lang.NullPointerException
at com.TestServlet.doGet(TestServlet.java:24)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:291)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:602)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:619)
Run Code Online (Sandbox Code Playgroud)
正如@Peter Cetinski已经提到的,Servlet Context总是与一个Web应用程序(WAR文件)完全相关.尽管如此,Servlet API提供了一种通过调用来访问"外部"Servlet上下文的方法javax.servlet.ServletContext.getContext(uriPath).
因此,如果您真的希望/需要将Servlet分布在不同的WAR上并且需要它们之间的通信,那么您可以这样做.
假设的Servlet 1位于web应用藁,Servlet的2位于web应用warB,以及应用上下文路径是相同的web应用名称(例如http://myserver/warA和http://myserver/warB),为的Servlet 2的代码看起来是这样的:
/* retrieve foreign context */
ServletContext ctxWarA = this.getServletContext().getContext("warA");
/* ... and work with it */
Map<String, String> map = (Map<String, String>) ctxWarA.getAttribute("usermanager");
Run Code Online (Sandbox Code Playgroud)
有一些限制:
您必须warB通过在应用程序中指定它来明确允许访问外部上下文context.xml:<Context crossContext="true"/>
这个设置是专有的(我无法告诉你它在其他应用服务器/ servlet引擎中是如何工作的)
如果要共享自定义类,则必须在应用程序之间共享它们(将它们放入 <tomcat>/lib
在标准设置你与不同的类加载器的工作warA和warB,你应该知道的是
Tomcat不保证某个启动序列(没有办法配置它).在你的情况下warB必须能够处理这个并期望warA尚未开始
如果您需要在Web应用程序之间共享对象/信息,我会考虑这些替代方法:
位于Tomcat/lib中的共享单例(我知道单例,但它有效)
位于JNDI树中的对象(Tomcat文档)
在共享数据存储(文件,数据库等)中构建缓存所需的信息,每个应用程序在启动时加载数据
| 归档时间: |
|
| 查看次数: |
4240 次 |
| 最近记录: |