简体   繁体   中英

Maintaining session state across two http different requests in an application

I have a scenario where I want to store session information across multiple sessions in Application # 2. We have two applications deployed on a tomcat server. Our use case is as follows:

A. Web Application # 1 makes a HTTP Post request to Application # 2 using a HTTP Rest Client. POST request contains a JSON http request body encapsulating the data to be send to Application # 2. The code block is as follows:

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

The request callback function is

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()));
    }
  }

The second application has a Spring controller with the following set up

@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);
  }
}

When I make a call to another URI within the application # 2 say via browser, I want it done in such as way that the session attributes are retained when making this call. Is there a way to do that?

I know about URL rewriting that stores JSESSIONID in the cookie, but I don't think how you can set the value when making a rest call, and using the same JESSIONID to maintain session attributes.

Is there a better way to do this? These have no answers. I have looked at these links, but none seem to answer my question.

HTTP and Sessions
comparison of ways to maintain state

jraahhali is spot on.

Set the cookie header with the value of JSESSIONID=${sessionId} or use it directly in the url as per the URL rewriting link.

First step is to retrieve the JSESSIONID from the initial response (this will depend on how you decide to set the session id - URL or Cookies, lets assume by cookie for now)

@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;
}

Then in subsequent requests (ie from the app #1 or a browser or whatever)

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

// ...
request.execute();

Note if you really want to use a browser as the other client then I would use the URL rewriting method for ease of use ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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