玩框架2.1转换巨型json结构

时间:2014-01-09 18:03:37

标签: json scala playframework playframework-2.1

我一直在使用Play 2.1的JSON库,特别是组合器和变换器:http://www.playframework.com/documentation/2.1.4/ScalaJsonCombinators

我有一个用例,我有一个大的json结构(100+键)。我需要更新这些值的20-30。在我目前对图书馆的理解中,我可以通过几种不同的方式实现这一目标:

1.使用带有“andThen”组合器的更新转换器:

val jsonTransformer = (__ \ 'key2).json.pickBranch(
  (__ \ 'key21).json.update( 
    of[JsNumber].map{ case JsNumber(nb) => JsNumber(nb + 10) }
  ) andThen 
  (__ \ 'key23).json.update( 
    of[JsArray].map{ case JsArray(arr) => JsArray(arr :+ JsString("delta")) }
  )
)

我必须连锁20多个“andThen”组合器...这是一个更好的方法,对吗?如果有一个带有HashMap值的变换器,并将hashmap的键/值替换为该特定json分支中的键值/值,那将会很不错。可以这样做吗?

2.我想到的另一种方法是事先创建一个JsObject,然后用一个转换调用更新分支:

val jsonObject = Json.toJson(
  Map(
    "users" -> Seq(
      toJson(
        Map(
          "name" -> toJson("Bob"),
          "age" -> toJson(31),
          "email" -> toJson("bob@gmail.com")
        )
      ),
      toJson(
        Map(
          "name" -> toJson("Kiki"),
          "age" -> toJson(25),
          "email" -> JsNull
        )
      )
    )
  )
)

这是可行的,但又可能会变得很大。

3.使用隐式读取/写入格式化程序为此数据定义自己的类。这将需要我构建OO层次结构,并且似乎违反了图书馆作者使用JSON-coast-to-coast建立的一些原则:http://www.playframework.com/documentation/2.1.2/ScalaJsonTransformers

如果您对哪种方法最好有任何想法,我很想听听。谢谢!

1 个答案:

答案 0 :(得分:1)

我使用了lift-json(https://github.com/lift/lift/tree/master/framework/lift-base/lift-json/)和Play!对于与ScalaJsonCombinators方法类似的用例,框架(mixin LiftJson trait可在:https://github.com/tototoshi/lift-json-play-module获得)似乎很难维护。

您可以创建仅包含您认为更改的字段的案例类(如果所有字段都可更改,则根据JSON结构创建包含所有JSON节点名称的案例类),LiftJson提供将JSON字符串映射到案例类的功能。 (除非您必须编写自定义序列化程序或反序列化程序,否则不需要自定义TypeHints。只需使用DefaultFormats。)

将JSON反序列化为case类对象后,可以使用case类的copy方法替换所需的字段并将其序列化为JSON。这似乎是更易于维护的解决方案,而不是直接在整个代码中调用JSON节点名称。