代码之家  ›  专栏  ›  技术社区  ›  mkUltra

使用play将case类隐式序列化为Json。应用程序编程接口。libs。json

  •  0
  • mkUltra  · 技术社区  · 8 年前

    这是我的案例类响应api模型,必须转换为json(重头戏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
    }
    

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

    你知道吗?

    1 回复  |  直到 8 年前
        1
  •  3
  •   James Roper    8 年前

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

    如果希望自动生成格式,则只需实现隐式宏。我们需要区分我们想要自动生成格式的类型,如果你只是为了 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结构不仅仅是无关紧要的偶然事件。它们构成了RESTAPI的协议,或者您正在使用的任何协议。这通常是您希望明确的,并且在整个代码库中保持一致的内容。通过明确定义每个伴生类型的格式,您可以在这个一致的地方查找格式是什么。当你需要自定义它时,你可以用一个手动的格式声明来代替你的宏,而且你没有改变任何关于声明格式的方法,答案仍然是去看看伴随对象上的格式字段。

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

    推荐文章