json到json变换使用play 2.3,组合字段

时间:2015-11-06 09:15:49

标签: json scala playframework

我正在尝试使用play 2.3将json结构中的几个字段组合成另一个json结构。基本上我想做的就是这个:

{  
   "a": "aaa"  
   "b": "bbb"  
   "c":   
   {  
        "d": "ddd"  
        "e": 123456  
        "f": "ffff"  
    }  
}  

并将其转换为:

{  
   "a": "aaa"  
   "b": "bbb"  
   "new": "ddd123456fff  
}  

我在这里看过一个解决方案:https://groups.google.com/forum/#!msg/play-framework/6MdDYf1JjEg/z_WG3DcdQIQJ 但是'和'是不可用的,我不会想到'然后'是一回事。

2 个答案:

答案 0 :(得分:0)

您可以执行以下操作

scala> import play.api.libs.json._

scala> val json: JsValue = Json.parse("""
{  
   "a": "aaa",  
   "b": "bbb",  
   "c":   
   {  
       "d": "ddd",  
       "e": 123456,  
       "f": "ffff"  
   }  
}
""")


scala> case class abc(a:String, b:String, c:String)

解决方案:1 适用于2.3 +

scala> implicit val abcdef: Reads[abc] = new Reads[abc] {
    def reads(json:JsValue):JsResult[abc] = {
        json match {
            case o:JsObject if (o.value.get("a").isDefined && o.value.get("b").isDefined && o.value.get("c").isDefined)=> 
                o.value.get("a").get match {
                    case JsString(a)=> o.value.get("b").get match {
                        case JsString(b)=> o.value.get("c").get match {
                            case c:JsObject if (c.value.get("d").isDefined && c.value.get("e").isDefined && c.value.get("f").isDefined)=> 
                                c.value.get("d").get match {
                                    case JsString(d)=> c.value.get("e").get match {
                                        case JsNumber(e)=> c.value.get("f").get match {
                                            case JsString(f) => JsSuccess(abc(a,b,d+e+f))
                                            case _ =>JsError("some error")
                                        }
                                        case _ =>JsError("some error")
                                    }
                                    case _ =>JsError("some error")
                                }
                            case _ =>JsError("some error")
                        }
                        case _ =>JsError("some error")
                    }
                    case _ =>JsError("some error")
                }
            case e => JsError("some error")
        }
    }
}

scala> json.validate[abc]

解决方案:2 仅适用于2.3.x

scala> implicit val abcdef: Reads[abc] = new Reads[abc] {
    def reads(json:JsValue):JsResult[abc] = {
        json match {
            case JsObject(Seq(("a", JsString(a)), ("b", JsString(b)), ("c", jsobj))) => {
                jsobj match {
                    case JsObject(Seq(("d", JsString(d)), ("e", JsNumber(e)), ("f", JsString(f)))) => JsSuccess(abc(a,b,d+e+f))
                    case _ => JsError("some error")
                }
            }
            case e => JsError("some error" + e)
        }
    }
}

scala> json.validate[abc]

答案 1 :(得分:0)

实现这一目标的最常见方法是将Reads结合起来,如下所述:
https://www.playframework.com/documentation/2.3.x/ScalaJsonCombinators

import play.api.libs.json._, Reads.at
import play.api.libs.functional.syntax._

val js  = Json.parse("""{
  "a": "aaa",
  "b": "bbb",
  "c": {
      "d": "ddd",
      "e": 123456,
      "f": "ffff"
    }
}""")

val transform = {

  val c = (__ \ "c");
  {
    c.json.prune ~
    (__ \ "new").json.copyFrom(
      at[String](c \ "d") ~
      at[Int]   (c \ "e") ~
      at[String](c \ "f") apply (_ + _ + _) map (JsString)
    )
  }.apply(_ ++ _).reads(_)
}

transform(js)