Webflux 将 Mono 的结果存储到会话变量

Webflux store result of Mono to session variable

我的Spring Boot Webflux-application (Netty) 输出HTML 使用 Thymeleaf-模板。在一种处理程序方法中,我使用 WebClient 向外部 ID 提供者进行身份验证。 现在我想将生成的身份验证令牌存储在会话变量中,以便我可以在后续 Controller/Handler 方法中重用它。 如果我将令牌存储在模型变量中,Spring/Webflux 在呈现之前解析 Mono 并提供生成的令牌字符串供视图(Thymeleaf 模板)使用。但是我找不到将令牌存储在会话变量中的方法。 WebSession 对我来说已经足够了,因为我不会 运行 具有多个节点的应用程序。

我试过的代码 (Kotlin):

@PostMapping("/login")
fun login(@Valid loginForm: LoginForm, model: Model, webSession: WebSession): String {
  val tokenMono: Mono<String> = loginService.login(loginForm.email, loginForm.password)
  model.addAttribute("token", tokenMono) // works and the token is available as a String in resulting view template
  webSession.addAttribute("token", tokenMono) // session-variable "token" is null in subsequent requests.
  return "login/success"
}

以下似乎有效:

@PostMapping("/login")
fun login(@Valid loginForm: LoginForm, webSession: WebSession): Mono<String> {
   return loginService.login(loginForm.email, loginForm.password)
     .doOnNext { token ->
        webSession.attributes["token"] = token
     }
     .map { token -> "login/success" }
}

主要知识:

  • 模板视图名称(此处为“login/success”)可以包含在 Mono.
  • 检索响应式类型后需要完成的所有事情都需要包装在 Mono 的 onXXX 函数之一中(也许 then 也可以)。
  • 这也适用于重定向到需要来自反应类型结果的某些内容的处理程序方法。所以说原始的 Mono 是 R2DB 插入的未来结果。如果我想重定向到结果视图,我可以使用 .map { entity -> "redirect:/entity/${entity.id}" }.