将 WSResponse 转换为结果:从结果中恢复丢失的会话键值

问题描述 投票:0回答:1

我有一个端点,我将其表示为

/endpoint
,它会执行类似的操作

def endPoint() = Action.async { implicit request =>
  val result: Result = Ok("Done")
  result.addingToSession("Key" -> "Value"): Result
}

当我向端点发送

WSRequest
并取回
WSResponse
时,我似乎找不到添加到
"Key","Value"
中会话的
WSResponse
对。

我需要它才能在后续 WSRequest 中使用键值对。

有人可以解释为什么会出现这种情况以及是否有办法恢复吗?

(如果有人可以向我指出解释此(结果 -> WSResponse 转换)的链接,那就太好了)

我想将

WSRequest
解析为
Result
,但我不确定它是否会恢复丢失的字段。

scala playframework play-ws
1个回答
0
投票

对幕后内容的一些解释

在您的客户端和服务器之间,只有简单的标准 HTTP 请求和响应,没有 Play 对象。

当服务器返回

Result
时,Play HTTP 服务器会将结果转换为 HTTP 标准响应。

在您的客户端代码中,

WSResponse
有点相反:客户端库收到标准 HTTP 响应并将其转换为
WSResponse
,以便您将其作为 Scala 类进行操作。

Result
WSResponse
在某种程度上代表相同的事物,但在两个不同的上下文中(服务器与客户端)。没有理由尝试将其中一种转换为另一种。


回到你的问题,你的服务器端点返回以下HTTP响应:

  • Ok(...)
    :代码200(OK)
  • "Done"
    :纯文本正文(不带引号),因为您没有指定 JSON 或其他内容
  • addingToSession("Key" -> "Value")
    ,顾名思义,使用 Play 服务器特定的行为,其中一些数据被添加到“会话”对象中,该对象在每个后续请求中发送回,并且服务器可以读取该对象以提供响应。

在标准 HTTP 响应中,不存在会话这样的东西。会话数据实际上存储在名为

SESSION
(默认情况下)的 cookie 中,该 cookie 本身是通过 HTTP 响应特殊标头
Set-Cookie: ...
设置的。

这对您的客户端代码意味着什么?这意味着如果你想读取这个键值,你需要从

WSResponse
中检索cookie,然后解析它并提取数据。

现在,这种方法存在几个问题:

  • cookie 值可能以某种方式进行编码和/或加密,使其只能从服务器读取(或知道服务器的秘密值)。实际上,它是最新版本的 JWT 令牌,因此它是可读的。
  • 当服务器上的 Play 版本升级时,会话 cookie 的实际实现(甚至名称)可能会发生变化,并且您的客户端代码将被破坏
  • 会话cookie是一种在对服务器的后续请求之间以及为服务器共享数据的一种方式,而不是在服务器和客户端之间共享数据

您可能想要什么:

返回 HTTP 响应正文中的键值信息,例如 JSON:

Ok(Json.toJson(Map("key" -> "value")))

在您的客户端代码中:

val map = wsResponse.body.as[Map[String, String]]
map.get("key")

如果由于某种原因您不想使用响应正文,另一种选择是使用 HTTP 标头。标头是您可以在服务器响应上设置并在客户端响应上轻松读取的键值。


编辑:我没有阅读您所说的需要在后续请求中发回键值的部分。

如果你实际上对键值不感兴趣,除了在后续请求中将其发送回来,因此使用会话是有意义的,你只需要在响应中检索cookie并将其添加回下一个请求:

val sessionCookie = wsResponse.cookies.get("SESSION")

// Next request
wsRequest.addCookie(sessionCooKie).get

(方法名称是近似值,请检查文档或您的 IDE 会有所帮助)

不过,恕我直言,使用 Play 的会话机制来实现这一点并不理想。根据您的具体用例(身份验证?),我会实现一些专用于它的东西。

© www.soinside.com 2019 - 2024. All rights reserved.