Servlet会话HTTPClient

时间:2010-08-13 16:14:06

标签: session servlets httpclient

我有一个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);

}

请您告诉我我的选择是什么来解决这个问题?

3 个答案:

答案 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值作为请求参数传递。