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

标记

我正在尝试通过使用plays 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响应。尝试定义一个Writeable [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. 如何将类型转换AArray[Bytes]and
  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)无需进行进一步转换和设置标题设置样例就可以执行任意数量的操作时,这似乎确实有些分散,但没有太多额外的代码

也许您可以将这些隐式变量放入ExtraJsonHelpers特征中,然后将其混入控制器中,以进一步减少样板。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章