繁体   English   中英

维护应用程序中两个http不同请求之间的会话状态

[英]Maintaining session state across two http different requests in an application

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

A. Web应用程序1使用HTTP Rest客户端向应用程序2发出HTTP发布请求。 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 URL重写的信息,但是我不认为在进行rest调用并使用相同的JESSIONID维护会话属性时如何设置值。

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

HTTP和会话
维持状态的方式比较

jraahhali上有现货。

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

第一步是从初始响应中检索JSESSIONID(这取决于您决定如何设置会话ID-URL或Cookies,现在让我们假设是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;
}

然后在随后的请求中(即来自应用程序1或浏览器或其他任何请求)

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

// ...
request.execute();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM