繁体   English   中英

为播放框架http响应创建可写[Argonaut.Json]

[英]creating Writeable[Argonaut.Json] for play framework http response

我试图改变这个函数的实现从使用播放json库这样

def apply[T](action: => ApiResponse[T])(implicit tjs: Writes[T], ec: ExecutionContext): Future[Result] = {
    action.fold(
      err =>
        Status(err.statusCode) {
          JsObject(Seq(
            "status" -> JsString("error"),
            "statusCode" -> JsNumber(err.statusCode),
            "errors" -> Json.toJson(err.errors)
          ))
        },
      t =>
        Ok {
          JsObject(Seq(
            "status" -> JsString("ok"),
            "response" -> Json.toJson(t)
          ))
        }
    )
  }

像这样使用argonaut

def apply[T](action: => ApiResponse[T])(implicit encodeJson: EncodeJson[T], ec: ExecutionContext): Future[Result] = {
    action.fold(
      err =>
        Status(err.statusCode) {
          Json(
          "status" -> jString("error"),
          "statusCode" -> jNumber(err.statusCode),
          "errors" -> err.errors.asJson
          )
        },
      t =>
        Ok {
          Json(
          "status" -> jString("ok"),
          "response" -> t.asJson
          )
        }
    )
  }

但我明白了

无法将argonaut.Json的实例写入HTTP响应。 尝试定义一个可写[argonaut.Json]

对于Status {}阻止和Ok {}阻止,我在这里得到了一个有用的答案https://groups.google.com/forum/#!topic/play-framework/vBMf72a10Zc

所以我试着像这样创建隐式转换

implicit def writeableOfArgonautJson(implicit codec: Codec): Writeable[Json] = {
      Writeable(jsval => codec.encode(jsval.toString))
    }

我认为将json对象转换为字符串并将其提供给codec.encode,它应该将其转换为Array [Bytes]但我得到

无法猜测用于argonaut.Json的内容类型。 尝试定义ContentTypeOf [argonaut.Json]

jsval.nospaces.getBytes也返回Array [Bytes]所以我不知道是否可以用它来帮助

所以虽然我认为最后一条错误消息意味着我只需要告诉它它应该使用内容类型application.json我也觉得这可能是一个不必要的兔子洞,应该有一个更简单的方法来做到这一点。

编辑:它不是这样一个兔子洞,因为定义contentType至少有东西编译,但我仍然想知道这是否正确

您似乎已回答了自己的问题,但要确认, Writable[A]是:

  1. 如何将类型A转换为Array[Bytes]
  2. 在响应中使用什么内容类型,这也需要
  3. 当前的字符编码

字符编码由隐式Codec实例处理,因此您需要一个隐式的ContentTypeOf[A] ,其中Aargonaunt.Json

implicit def contentTypeOf_ArgonautJson(implicit codec: Codec): ContentTypeOf[argonaut.Json] = {
  ContentTypeOf[argonaut.Json](Some(ContentTypes.JSON))
}

然后是Writable[A] ,它在A上有一个类型约束 ,它有一个范围内的ContentTypeOf[A] (你刚刚定义过):

implicit def writeableOf_ArgonautJson(implicit codec: Codec): Writeable[argonaut.Json] = {
  Writeable(jsval => codec.encode(jsval.toString))
}

正如你所指出的,那里有一个兔子洞。 事实上,当你考虑到现在可以在你想要的Ok(myArgonautObject)动作中做Ok(myArgonautObject)而没有进一步的转换和标题设置样板时,它肯定似乎有点转移,但没有多少额外的代码。

也许您可以将这些ExtraJsonHelpers放在ExtraJsonHelpers特性中并将其混合到您的控制器中,以便更多地减少样板。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM