在应用程序中跨两个http不同请求维护会话状态

时间:2014-11-11 00:40:32

标签: java rest session servlets cookies

我有一个场景,我希望在Application#2中的多个会话中存储会话信息。我们在tomcat服务器上部署了两个应用程序。我们的用例如下:

一个。 Web应用程序#1使用HTTP Rest Client向Application#2发出HTTP Post请求。 POST请求包含一个JSON http请求体,封装要发送到Application#2的数据。代码块如下:

RestTemplate template = new RestTemplate();
final SearchCustomer customer = new SearchCustomer();
restTemplate.execute(
    SEND_CUSTOMER_PROFILE, HttpMethod.POST,
    new SearchRequestCallback(searchCustomer), null);

请求回调函数是

static class SearchRequestCallback implements RequestCallback {


  /**
   * Write a JSON response to the request body.
   */
    @Override
    public void doWithRequest(ClientHttpRequest request) throws IOException {
      HttpHeaders httpHeaders = request.getHeaders();
      List<MediaType> acceptableMediaTypes = new LinkedList<>();
      acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
      httpHeaders.setAccept(acceptableMediaTypes);
      httpHeaders.setContentType(MediaType.APPLICATION_JSON);
      request.getBody().write(
          new Gson().toJson(this.searchCustomer).getBytes(StandardCharsets.UTF_8.displayName()));
    }
  }

第二个应用程序有一个Spring控制器,其设置如下

@Controller
public class SearchCustomerController {

  /**
   * Builds customer profile knowledge graph.
   * 
   * <p>This is invoked as an synchronous request.
   */
  @RequestMapping(value="/searchProfilePayload.go", method=RequestMethod.POST)
  @ResponseStatus(HttpStatus.OK)
  public void constructSearchCustomerProfileKnowledgeGraph(
      @RequestBody final SearchCustomer customer, HttpServletRequest request) {
    UserContext userContext =
        (UserContext) request.getSession().getAttribute("userContext");
    if (userContext == null) {
      // Perform heavy operation to fetch user session.
      userContext = UserContextHelper.getUserContext(request);
      request.getSession("userContext", userContext)
    }
    userContext.setCustomerProfile(customer);
  }
}

当我通过浏览器调用应用程序#2中的另一个URI时,我希望它在完成此调用时保留会话属性的方式完成。有没有办法做到这一点?

我知道在Cookie中存储JSESSIONID的{​​{3}},但我不认为在进行休息调用时如何设置值,并使用相同的JESSIONID来维护会话属性。

有更好的方法吗?这些都没有答案。我看过这些链接,但似乎都没有回答我的问题。

URL rewriting
HTTP and Sessions

1 个答案:

答案 0 :(得分:1)

jraahhali就是现场。

使用JSESSIONID = $ {sessionId}的值设置cookie标头,或者根据URL重写链接直接在URL中使用它。

第一步是从初始响应中检索JSESSIONID(这将取决于您决定如何设置会话ID - URL或Cookie,现在假设为cookie)

@Override
public void doWithRequest(ClientHttpRequest request) throws IOException {
  HttpHeaders httpHeaders = request.getHeaders();
  List<MediaType> acceptableMediaTypes = new LinkedList<>();
  acceptableMediaTypes.add(MediaType.APPLICATION_JSON);
  httpHeaders.setAccept(acceptableMediaTypes);
  httpHeaders.setContentType(MediaType.APPLICATION_JSON);
  request.getBody().write(
      new Gson().toJson(this.searchCustomer).getBytes(StandardCharsets.UTF_8.displayName()));

  ClientHttpResponse response = request.execute();
  String sessionId = response.getHeaders().get(HttpHeaders.SET_COOKIE).split(":")[1].trim(); // I didnt test this, will prolly get a NPE :P
  this.sessionId = sessionId;
}

然后在后续请求中(即来自app#1或浏览器或其他任何内容)

if (this.sessionId != null && !this.sessionId.equals(""))
  httpHeaders.set(HttpHeaders.COOKIE, "JSESSIONID=" + this.sessionId);

// ...
request.execute();

请注意,如果您真的想将浏览器用作其他客户端,那么我会使用URL重写方法以便于使用...

相关问题