Servlet作为代理:如何转发会话?

时间:2012-03-09 23:53:37

标签: java session servlets

我不太确定我想要实现的要求的可行性,但这是如何实现的:

  • 我创建了一个充当代理的Servlet。它接收RESTful调用,然后在远程服务器(节点)上调用另一个RESTful服务。
  • 转发是通过HTTPClient而不是使用请求调度程序实现的。我基本上向远程服务器发出新的HTTP请求。
  • 当第一个服务器(代理服务器)收到呼叫时,请求(HttpServletRequest)有一个与之关联的会话。 isNew()的{​​{1}}属性为false。
  • 当转接呼叫并且远程服务器接收到呼叫时,会话将成为一个全新的会话。

我正在尝试基本上找到一种方法将会话转发到远程服务器。

更确切地说: 是否可以简单地从HTTPSession获取会话并将其放入新创建的HTTP请求的会话中(通过HttpServletRequest)?

3 个答案:

答案 0 :(得分:2)

这取决于远程WS如何维护会话。例如,它使用cookie(Tomcat在其他技术中执行此操作),然后转发传入的标头应该可以帮助您实现这一点(确保您提到您接受cookie,但我认为HTTPClient默认情况下这样做)。 现在,如果它基于URL中的参数,那么您应该尝试重现该行为。

答案 1 :(得分:1)

如果两个节点(代理和服务)是不属于应用程序集群的单独进程,则可能不是。

servlet容器通常管理HttpSession。如果要将请求转发给另一个由其他容器托管的服务,那么您将拥有一个不同的会话对象。

如果两个节点是集群的一部分,那么通常可以通过多种机制(在内存复制,数据库同步等)中在集群中的节点之间共享会话。

另一种选择是将会话数据外部化为Redis,Memcached,Coherence等。某些应用程序服务器具有对此类进程的可插拔支持。我相信在这种情况下,应用服务器节点不一定必须是群集的一方来共享会话数据。

答案 2 :(得分:0)

当我问这个问题时,我缺乏一些会话处理的基础知识。经过一些研究和讨论后,我得到了:

  • 基本上,会话由JSESSIONID变量处理。
  • 当请求到达服务器时,
  • JSESSIONID会自动创建(可以关闭)。
  • 它会在响应标题中返回。
  • 远程服务器认为它是新会话的原因是请求没有设置此JSESSIONID

  • 代理执行以下操作以确保转发会话:

    1. 当收到请求时;创建并存储JSESSIONID
    2. 向远程服务器发出新请求。
    3. 从远程服务器解压缩响应标头并解压缩JSESSIONID
    4. 维护客户端JSESSIONID和远程服务器JSESSIONID的映射。
    5. 对于以下任何请求,请使用此映射将请求发送到远程服务器。

基本上,代理执行从客户端JSESSIONID到远程服务器JSESSIONID的映射。这样,会话就会转发到远程服务器。