Kris
Kris

Reputation: 4823

Play Framework 2.7: How to update session within a Action composition in Java

I'm trying to update an app from to Play 2.7. I see that now the access to the session object via Http.Context is deprecated. Instead I have to use the Http.Request object. Additionally before I could just change the Session object right away - now it seems like I have to create a new Session and add to the Result by myself. But how can I achieve this within an Action composition where I don't have access to the Result object?

An Action composition can look like:

public class VerboseAction extends play.mvc.Action.Simple {
  public CompletionStage<Result> call(Http.Request req) {
    ...
    return delegate.call(req);
  }
}

I can't see how to add something to the Session here!

EDIT:

I couldn't find an easy solution but a workaround with a second action annotation. It's possible to access the Result object via .thenApply and attache the new Session object.

public CompletionStage<Result> call(Http.Request request) {
  return delegate.call(request).thenApply(result -> {
     Http.Session session = ... change the session  
     return result.withSession(session);
  });
}

Still if someone has a better idea how to change the Session directly in the action composition please feel free to answer.

Upvotes: 2

Views: 662

Answers (1)

Jean-Claude Stritt
Jean-Claude Stritt

Reputation: 21

A session in cleared by withNewSession(). A new session is created when you add something with addingToSession(...), perhaps after a login. Here is my complete working code : I have 2 timestamp : one for the log file and one for an application timeout.

public class ActionCreator implements play.http.ActionCreator {
  private final int msTimeout;

  @Inject
  public ActionCreator(Config config) {
    this.msTimeout = config.getInt("application.msTimeout");
  }

  @Override
  public Action<?> createAction(Http.Request request, Method actionMethod) {
    return new Action.Simple() {

      @Override
      public CompletionStage<Result> call(Http.Request req) {

        // add timestamp for the elapsed time in log
        req.getHeaders().addHeader("x-log-timestamp", "" + System.currentTimeMillis());

        // did a session timeout occur
        boolean timeout = SessionUtils.isTimeout(req, msTimeout);

        // apply current action 
        return delegate.call(req).thenApply(result -> {

          // display some info in log
          Utils.logInfo(req);

          // return final result
          if (timeout) {
            return result.withNewSession();
          } else if (SessionUtils.isOpen(req)) {
            return result.addingToSession(req, "timestamp", "" + System.currentTimeMillis());
          } else {
            return result;
          }
        });
      }

    };
  }

}

Upvotes: 2

Related Questions