播放请求之前和之后
Before and After request in Play
我正在 Play Framework (2.8) 中开发一个应用程序,我试图拦截请求以在请求被处理和清理之前在 ThreadContext 上保留一些信息。
更准确地说,我想从会话中读取NDC,将其放入ThreadContext(如果不存在则生成一个新的并将其存储在会话中),并在请求处理后清理。
在 Spring 中,我会使用具有 preHandle()
和 postHandle()
的 HandlerInterceptor 来执行此操作,但是我在 Play 中找不到类似的东西。
我正在查看 HttpRequestHandler 和提供的示例,但无法真正使其工作。有正确的做法吗?
设法使用 ActionCreator 解决了问题。
我实现了一个动作创建器,我从请求中读取了 cookie。如果它不存在,我会生成一个新的 NDC。我将 NDC(无论它是从 cookie 中读取的还是生成的)存储在 ThreadContext 中。
我将委托调用的结果存储在一个单独的变量中,因为它是一个 COmpletionStage,如果使用 thenApply() 将 NDC 添加到 cookie,如果它是先前生成的。否则我只是 return 结果。此处有更详细的文章:https://petrepopescu.tech/2021/09/intercepting-and-manipulating-requests-in-play-framework/
public Action createAction(Http.Request request, Method actionMethod) {
return new Action.Simple() {
@Override
public CompletionStage<Result> call(Http.Request req) {
CompletionStage<Result> resultCompletionStage;
boolean ndcWasGenerated = false;
String ndcStr = null;
// Get the NDC cookie from the session
Optional<String> ndc = req.session().get("NDC");
if (ndc.isPresent()) {
ndcStr = ndc.get();
} else {
// Generate a new NDC since no cookie was in the session. This means that it is the first request from this user
ndcStr = UUID.randomUUID().toString().replace("-", "");
ndcWasGenerated = true;
}
// Push the NDC in the Thread context
ThreadContext.push(ndcStr);
// Go down the call chain and pass the request. Eventually it will reach our controller
resultCompletionStage = delegate.call(req);
// Clean up the ThreadContext
ThreadContext.pop();
ThreadContext.clearAll();
if (ndcWasGenerated) {
// If we generated the NDC, store it in a session cookie so we can use it for the next calls
String finalNdcStr = ndcStr;
return resultCompletionStage.thenApply(result -> result.addingToSession(req, "NDC", finalNdcStr));
}
return resultCompletionStage;
}
};
}
我正在 Play Framework (2.8) 中开发一个应用程序,我试图拦截请求以在请求被处理和清理之前在 ThreadContext 上保留一些信息。 更准确地说,我想从会话中读取NDC,将其放入ThreadContext(如果不存在则生成一个新的并将其存储在会话中),并在请求处理后清理。
在 Spring 中,我会使用具有 preHandle()
和 postHandle()
的 HandlerInterceptor 来执行此操作,但是我在 Play 中找不到类似的东西。
我正在查看 HttpRequestHandler 和提供的示例,但无法真正使其工作。有正确的做法吗?
设法使用 ActionCreator 解决了问题。 我实现了一个动作创建器,我从请求中读取了 cookie。如果它不存在,我会生成一个新的 NDC。我将 NDC(无论它是从 cookie 中读取的还是生成的)存储在 ThreadContext 中。 我将委托调用的结果存储在一个单独的变量中,因为它是一个 COmpletionStage,如果使用 thenApply() 将 NDC 添加到 cookie,如果它是先前生成的。否则我只是 return 结果。此处有更详细的文章:https://petrepopescu.tech/2021/09/intercepting-and-manipulating-requests-in-play-framework/
public Action createAction(Http.Request request, Method actionMethod) {
return new Action.Simple() {
@Override
public CompletionStage<Result> call(Http.Request req) {
CompletionStage<Result> resultCompletionStage;
boolean ndcWasGenerated = false;
String ndcStr = null;
// Get the NDC cookie from the session
Optional<String> ndc = req.session().get("NDC");
if (ndc.isPresent()) {
ndcStr = ndc.get();
} else {
// Generate a new NDC since no cookie was in the session. This means that it is the first request from this user
ndcStr = UUID.randomUUID().toString().replace("-", "");
ndcWasGenerated = true;
}
// Push the NDC in the Thread context
ThreadContext.push(ndcStr);
// Go down the call chain and pass the request. Eventually it will reach our controller
resultCompletionStage = delegate.call(req);
// Clean up the ThreadContext
ThreadContext.pop();
ThreadContext.clearAll();
if (ndcWasGenerated) {
// If we generated the NDC, store it in a session cookie so we can use it for the next calls
String finalNdcStr = ndcStr;
return resultCompletionStage.thenApply(result -> result.addingToSession(req, "NDC", finalNdcStr));
}
return resultCompletionStage;
}
};
}