加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 为play框架http响应创建可写[Argonaut.Json]

发布时间:2020-12-16 09:59:44 所属栏目:安全 来源:网络整理
导读:我试图改变这个函数的实现从使用播放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"),"s
我试图改变这个函数的实现从使用播放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
          )
        }
    )
  }

但我明白了

Cannot write an instance of argonaut.Json to HTTP response. Try to
define a 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]但我得到

Cannot guess the content type to use for argonaut.Json. Try to define
a ContentTypeOf[argonaut.Json]

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

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

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

解决方法

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

>如何将类型A转换为数组[Bytes]和
>在响应中使用哪种内容类型,这也需要
>当前的字符编码

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

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

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

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

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

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读