Playframework Scala 将请求从 Json 转换为 x-www-form-urlencoded

Playframework Scala Transform Request from Json to x-www-form-urlencoded

大家好,我是 Scala 和 Playframework 的新手。我收到一个 ajax 格式的 json 请求,我需要用 x-www-form-urlencoded 格式向另一台服务器发出另一个请求。

我在控制器中有这段代码

  def getToken = Action.async(parse.json) { request =>
    WS.url("https://api.xxxx.com/v1/yyyy")
      .withHeaders(
        "accept" -> "application/json",
        "content-type" -> "application/x-www-form-urlencoded",
        "Authorization" -> "Auth %s".format(apiKey)
      ).post(request.body) map { response =>
        Logger.info("response from get user: " +  Json.prettyPrint(response.json))
        Ok("ok")
    }
  }

我尝试了不同的方法,但无法正常工作。也许我应该在模型中做一个格式化程序。将请求 json 转换为 x-www-form-urlencoded 请求的最佳方式是什么?

谢谢

简答

您只需要将 Map[String, Seq[String]] 传递给 post 方法。 如果你有一些键和值,你可以很容易地构造这样一个 Map

例如:

WS.url(url).post(Map("key1" -> Seq("value1"), "key2" -> Seq("value2")))

详情

Form Submission section of Play WS docs 中所述,如果您想提交表单,则必须将 Map[String, Seq[String]] 传递给 post 方法。

你在这里传递的是 JsValue(因为 request.bodyJsValue 类型,因为正文解析器类型是 parser.json) .所以首先你必须从 json 对象中提取 key/value 对的集合,然后从中构造一个 Map[String, Seq[String]] 并将它传递给 post 方法。

例如,如果您确定 json 对象(由正文解析器从请求正文中提取)是一个 JSON 对象(不是数组或字符串或数值),您可以轻松构建所需的 Map(仅针对第一级 key/value 对):

def getToken = Action.async(parse.json) { request =>
  import play.api.libs.json.JsObject
  val json = request.body.as[JsObject]
  val formParamsMap = json.value.mapValues(_.asOpt[String].toSeq)
  WS.url("https://api.xxxx.com/v1/yyyy")
    .withHeaders(
      "accept" -> "application/json",
      "content-type" -> "application/x-www-form-urlencoded",
      "Authorization" -> "Auth %s".format(apiKey)
    )
    .post(formParamsMap) map { response =>
  Ok("ok")
  }
}