附加到http帖子

时间:2017-10-02 12:47:03

标签: scala playframework

我从一个动作中调用以下辅助函数来创建一个同步的HTTP-post,其中一个特殊的键值对附加在formdata中的URL参数中:

  def synchronousPost(url: String, formdata: Map[String, Seq[String]], timeout: Duration=Duration.create(30, TimeUnit.SECONDS)): String = {
    import ExecutionContext.Implicits.global
    val params = formdata.map { case (k, v) => "%s=%s".format(k, URLEncoder.encode(v.head, "UTF-8")) }.mkString("&")
    val future: Future[WSResponse] = ws.url(url).
       withHttpHeaders(("Content-Type", "application/x-www-form-urlencoded")).
       post(params)
    try {
      Await.result(future, timeout)
      future.value.get.get.body
    } catch {
      case ex: Exception =>
        Logger.error(ex.toString)
        ex.toString
    }
  }

它被称为:

  def act = Action { request => 
    request.body.asFormUrlEncoded match {
      case Some(formdata) =>
        synchronousPost(url, formdata + ("handshake" -> List("ok"))) match {

实际上它是从一些旧的要点复制粘贴的,我很确定它可以用更干净的方式重写。

如何以更干净的方式重写行val params = ...?这似乎是低水平。

原始的formdata来自request.body.asFormUrlEncoded,我只需要将handshake参数附加到formdata-map并将原始请求发送回发件人进行握手。

1 个答案:

答案 0 :(得分:1)

由于formdataMap[String, Seq[String]],是一种提供默认WSBodyWritable的数据类型,您可以直接将其用作请求正文:

val future: Future[WSResponse] = ws.url(url)
  .withHttpHeaders(("Content-Type", "application/x-www-form-urlencoded"))
  .post(formdata)

顺便提一下,如果使用Await很容易让Play控制器使用Future[Result]返回Action.async,则使用def asyncPost(url: String, formdata: Map[String, Seq[String]]): Future[String] = { ws.url(url) .withHttpHeaders(("Content-Type", "application/x-www-form-urlencoded")) .post(formdata) .map(_.body) } def action = Action.async { request => request.body.asFormUrlEncoded match { case Some(formdata) => asyncPost(url, formdata + ("handshake" -> List("ok"))).map { body => Ok("Here is the body: " + body) } recover { case e => Logger.error(e) InternalServerError(e.getMessage) } case None => Future.successful(BadRequest("No form data given")) } } 会被视为不良表单,例如:

function remove(obj, key) {
  var value = obj[key]
  var ret = {}
  ret[key] = obj[key]
  obj = ret
}