在PlayFramework 2.4中使用JSON转换器添加可选属性 [英] Add optional property with json transformers in playframework 2.4
问题描述
我不明白,如何使用json转换器添加可选属性.
I can't understand, how can i add optional property with json transformer.
我想合并两个json对象(列表和日历),不带或带有动态属性列表(例如,不带owner
):
I want merge two json objects (list and calendars) without or with dynamic list of properties (for example without owner
):
calendar1 = {id:1, name: "first", description:"my first calendar", owner: 1}
calendar2 = {id:2, name: "second", owner: 1}
list = [{id: 1, settings: []}, {id: 2, settings: []}]
结果必须为
{calendars:
[
{id:1, name: "first", description:"my first calendar", settings: []},
{id:2, name: "second", settings: []}
]
}
推荐答案
我将假设以下json树
I'll assume the following json trees
val calendar1 = Json.parse("""{"id":1, "name": "first", "description":"my first calendar", "owner": 1}""")
val calendar2 = Json.parse("""{"id":2, "name": "second", "owner": 1}""")
您需要为每个日历添加设置,然后删除所有者(如果存在).
You need to add settings to each calendar, then remove the owner if it exists.
在分支 删除所有者也是解释 现在您可以定义要应用于每个日历对象的转换器 Now you can define the transformer to be applied to each of your calendar object 有了这些,根据实际数据建模的方式,有多个选项.如果您有 With that in place there are multiple options depending on how your data is actually modeled. If you have a 可以做到 这为您提供了一个 This gives you a 我很确定有一种方法可以使用play的功能语法(请参阅 I am pretty sure there is a way to do it using play's functional syntax (see 相反,我依赖于受scala Instead, I rely on the following code inspired by scala's 您可以这样写: ,这将为您提供 which will give you a 返回: 与您对某些空格取模的要求相同 which is the same as what you asked modulo some whitespace 这篇关于在PlayFramework 2.4中使用JSON转换器添加可选属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!settings
中放置值是
val removeOwner = (__ \ "owner").json.prune
val transformer = addSettings andThen removeOwner
Seq
of calendars as in val calendars = Seq(calendar1, calendar2)
val normalizedCalendars = calendars.map(_.transform(transformer))
Seq[JsResult[JsObject]]
,您希望将其转换为JsResult[Seq[JsObject]]
. Seq[JsResult[JsObject]]
which you want to transform into a JsResult[Seq[JsObject]]
. play.api.libs.functional
和play.api.libs.functional.syntax
),但是这部分内容没有得到很好的记录,我还没有研究Applicatives
即使我对他们的工作有感觉.play.api.libs.functional
and play.api.libs.functional.syntax
) but this part of play is not well documented and I haven't gotten around to studying Applicatives
yet even though I have a feel for what they do.Future#sequence
Future#sequence
def sequence[A, M[X] <: TraversableOnce[X]](in: M[JsResult[A]])(implicit cbf: CanBuildFrom[M[JsResult[A]], A, M[A]]): JsResult[M[A]] = {
val empty: JsResult[mutable.Builder[A, M[A]]] = JsSuccess(cbf(in))
in.foldLeft(empty) {(jracc,jrel) => (jracc,jrel) match {
case (JsSuccess(builder,_), JsSuccess(a,p)) =>JsSuccess(builder+=a, p)
case (ra@JsError(builderErrors), re@JsError(errors)) =>JsError.merge(ra, re)
case (JsSuccess(_,_), re@JsError(errors)) => re
case (ra@JsError(builderErrors), JsSuccess(_,_)) => ra
}} map (_.result())
}
val calendarArray = sequence(normalizedCalendars).map(v=>Json.obj("calendars"->JsArray(v)))
JsResult[JsObject]
.只要您的原始日历确实是JsObject
,您就会得到一个JsSuccess
.您可以使用以下命令验证输出结构:JsResult[JsObject]
. As long as your original calendars are indeed JsObject
s you will get a JsSuccess
. You can verify the output structure with : calendarArray.foreach(println)
{"calendars":[{"id":1,"name":"first","description":"my first calendar","settings":[]},{"id":2,"name":"second","settings":[]}]}
{
"calendars":[
{"id":1,"name":"first","description":"my first calendar","settings":[]},
{"id":2,"name":"second","settings":[]}
]
}