我正在尝试将应用程序从Play 2.7更新。我看到现在不赞成通过Http.Context访问会话对象。相反,我必须使用Http.Request对象。另外,在我可以立即更改Session对象之前-现在看来我必须创建一个新的Session和add to the Result by myself。但是如何在无法访问Result对象的Action组合中实现这一目标?
动作组成如下:
public class VerboseAction extends play.mvc.Action.Simple {
public CompletionStage<Result> call(Http.Request req) {
...
return delegate.call(req);
}
}
我在这里看不到如何向会话中添加内容!
编辑:
我找不到简单的解决方案,但找到了带有第二个动作注释的解决方法。可以通过.thenApply
访问Result对象并附加新的Session对象。
public CompletionStage<Result> call(Http.Request request) {
return delegate.call(request).thenApply(result -> {
Http.Session session = ... change the session
return result.withSession(session);
});
}
如果有人对如何直接在动作组成中直接更改会话有更好的主意,请随时回答。
答案 0 :(得分:1)
使用newNewSession()清除的会话。当您使用addingToSession(...)添加某些内容时(可能是在登录后),会创建一个新会话。这是我完整的工作代码:我有2个时间戳:一个用于日志文件,一个用于应用程序超时。
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;
}
});
}
};
}
}