我一直在使用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。
如果您对哪种方法最好有任何想法,我很想听听。谢谢!
答案 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节点名称。