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

dwthyt8l  于 2023-08-05  发布在  Scala
关注(0)|答案(1)|浏览(107)

我有一个端点,我将其表示为/endpoint,它的作用如下所示

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

字符串
当我向端点发送WSRequest并取回WSResponse时,我似乎找不到添加到WSResponse中的会话的"Key","Value"对。
我需要它以便在后续的WSPrequest中使用键、值对。
有人能解释一下为什么会这样吗?有没有办法恢复?
(It如果有人能给我指出解释这个(结果-> WSResponse转换)的链接,那就太好了。
我想将WSRequest解析为Result,但我不确定它是否会恢复丢失的字段。

relj7zay

relj7zay1#

解释一下引擎盖下的东西

在客户端和服务器之间,只有普通的标准HTTP请求和响应,没有Play对象。
当服务器返回Result时,Play HTTP服务器将此结果转换为HTTP标准响应。
在你的客户端代码中,WSResponse是相反的:客户端库接收到一个标准的HTTP响应,并将其转换为WSResponse,以便您将其作为Scala类进行操作。
ResultWSResponse以某种方式表示相同的东西,但在两个不同的上下文中(服务器与没有理由试图将一个转换为另一个。

回到您的问题,您的服务端返回如下HTTP响应:

  • Ok(...):代码200(正常)
  • "Done":正文为纯文本(不带引号),因为您没有指定JSON或其他内容
  • addingToSession("Key" -> "Value"),顾名思义,它们使用播放服务器特定的行为,其中一些数据被添加到“会话”对象,该对象在每个后续请求时被发送回来,并且服务器可以读取该对象以提供响应。
    在标准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的会话机制并不理想。根据您的具体使用情形(身份验证?),我会实现一些专门用于它的东西。

相关问题