【问题标题】:Implicit serializing case class to Json with play.api.libs.json使用 play.api.libs.json 将案例类隐式序列化为 Json
【发布时间】:2018-02-08 16:26:35
【问题描述】:

这是我的案例类Response api模型,必须转换为json(Play 2.5):

import play.api.libs.json.{Json, OFormat}

case class ResponseModel(content: NestedCaseClassModel)

object ResponseModel {
  implicit val format: OFormat[ResponseModel] = Json.format
}

case class NestedCaseClassModel(value: String)

object NestedCaseClassModel {
  implicit val format: OFormat[NestedCaseClassModel] = Json.format
}

问题是: 当我有非常深嵌套的响应结构时,我需要为我的模型中的每个案例类实现伴随对象,并添加 隐式格式,看起来非常相似。

我正在寻找一种允许我编写一次并将其用于任何案例类的机制。我无法切换表单 play.api.libs.json 库。

你知道吗?

【问题讨论】:

    标签: json scala serialization playframework format


    【解决方案1】:

    好的,我会告诉你如何做你想做的事,然后我会告诉你为什么不应该这样做。

    如果您想要为您自动生成格式,那么您只需要实现一个隐式宏。我们需要区分我们希望为哪些类型自动生成格式,如果你只是为Any 生成它,那么它将覆盖String 之类的东西,这会很糟糕。因此,我们将定义一个所有案例类都将实现的特征:

    trait ImplicitJsonFormat
    

    现在我们为它实现我们的隐式宏:

    import play.api.libs.json._
    import scala.language.experimental.macros
    
    trait JsonImplicits {
      // This works for Play 2.5, in Play 2.6 it becomes JsMacroImpl.implicitConfigFormatImpl
      implicit def implicitJsonFormat[A <: ImplicitJsonFormat]: OFormat[A] = macro JsMacroImpl.formatImpl[A]
    }
    

    所以现在任何你想要自动生成格式的东西,你只需要扩展ImplicitJsonFormat,并确保任何需要的隐式格式都已经混合了JsonImplicits

    import play.api.libs.json.{Json, OFormat}
    
    case class ResponseModel(content: NestedCaseClassModel)
    
    object ResponseModel extends JsonImplicits {
      implicit val format: OFormat[ResponseModel] = Json.format
    }
    
    case class NestedCaseClassModel(value: String) extends ImplicitJsonFormat
    

    你有它,NestedCaseClassModel 会自动生成它的格式。当然你也可以自动生成ResponseModel的格式。

    但你真的不应该这样做。为什么?有时,明确是有价值的。这些 json 结构不仅仅是无关紧要的偶然事物。它们构成了您的 REST API 的协议,或者您正在使用的任何协议。这通常是您想要明确说明的事情,并且在整个代码库中保持一致。通过明确定义每种伴随类型的格式,您可以在这个一致的地方查找格式是什么。当您需要自定义它时,您可以用手动格式声明替换您的宏,并且您没有更改任何声明格式的方法,答案仍然在于查看伴随对象上的格式字段.

    当然,当您预先创建项目时,声明所有这些格式可能有点乏味。但这是一件容易做的事情,容易做对,一旦完成,它就完成了。随着代码库的发展和进步,无论如何,您可能会在伴随对象中包含其他内容,并且您会发现自己需要改进格式,并在迁移代码库和协议架构时远离宏不同的方向。

    【讨论】:

    • gitlab.com/fommil/stalactite 中采用的方法是经过验证的介于显式和样板之间的中间地带,这也是 Haskell 所做的。
    猜你喜欢
    • 2012-08-12
    • 2017-04-10
    • 2020-10-08
    • 2014-08-09
    • 2011-06-29
    • 2019-03-28
    • 1970-01-01
    • 2016-01-15
    • 2021-06-27
    相关资源
    最近更新 更多