我有一个Servlet A,其中配置了一个HTTPClient - 声明了一个调用Servlet B的GetMethod(基本上将url传递给Servlet B的构造函数)。
在Servlet B中我设置了一些会话变量,当Servlet A在“execute”方法之后返回控件但在Servlet B中设置的会话变量返回为null时。
Servlet A
doPost(req,res)
{
HTTPClient client = new HTTPClient();
GetMethod get = new GetMethod("/ServletB.do");
client.execute(get);
System.out.println("Value of a is :: " + session.getAttribute("a")) ; //gives a NULL
}
Servlet B
doPost(req,res)
{
HTTPSession session = req.getSession();
session.setAttibute("a",a);
session.setAttibute("b",b);
}
请您告诉我我的选择是什么来解决这个问题?
答案 0 :(得分:2)
您的代码至少有两个问题:
您需要将会话ID从HTTP请求中的servlet A传递给servlet B.如何在客户端和服务器之间传递会话ID是特定于容器的,但通常会话ID作为HTTP cookie传递
如果多个servlet同时访问同一个会话且其中一个servlet正在添加或替换新属性,则servlet规范不保证会话属性的更改立即对所有servlet可见。
你最好的选择可能是将servlet B中的业务逻辑移动到一个单独的类中,并使用servlet A或servlet B中的那个类。或者你有一些其他奇怪的原因从一个servlet到一个servlet进行HTTP调用在同一个Web应用程序中使用不同的servlet而不是简单地进行方法调用?
答案 1 :(得分:0)
我可以看到你正在调用A执行'get',而你已经在B中给出了处理'post'的代码。
您使用session.getAttribute("a"))
检索参数的会话与B servlet看到的“会话”不同。
答案 2 :(得分:0)
正确的解决方案取决于这些servlet实际运行的位置。
如果这些servlet在相同的 webserver 和 servletcontext上运行,那么只需使用RequestDispatcher#include()
。他们可以访问完全相同的会话。
request.getRequestDispatcher("/anotherservlet").include(request, response);
如果这些servlet在相同的网络服务器上运行,但是不同的 servletcontext,则考虑共享会话,以便它们共享完全相同的会话。目前还不清楚你正在使用什么servlet容器,所以这里只是一个Tomcat定位示例,为您提供一些提示。只需将两个webapp上下文的crosscontext
属性设置为true
:
<Context crossContext="true">
如果这些servlet在不同的网络服务器上运行,那么您需要将感兴趣的数据作为请求参数传递。这真是你最好的选择。他们不会也不会分享同一个会议,这将是一个安全漏洞。
new GetMethod("http://example.com/ServletB.do?name1=value1&name2=value2");
如果数据相对较大,则考虑共享数据库,以便您只需将PK值作为请求参数传递。