【问题标题】:How to use different names when mapping JSON array to Scala object using combinators使用组合器将 JSON 数组映射到 Scala 对象时如何使用不同的名称
【发布时间】:2014-04-10 13:06:08
【问题描述】:

给定一个像这样的 JSON 数组:

{
    "success": true,
    "data": [
        {
            "id": 600,
            "title": "test deal",
            "e54cbe3a434d8e6": 54
        },
        {
            "id": 600,
            "title": "test deal",
            "e54cbe3a434d8e6": 54
        },
    ],
    "additional_data": {
        "pagination": {
            "start": 0,
            "limit": 100,
            "more_items_in_collection": false
        }
    }
}

在我的 Play 2.2.2 应用程序中,使用 Scala JSON Reads Combinator,一切正常:

implicit val entityReader = Json.reads[Entity]

  val futureJson: Future[List[Entity]] = futureResponse.map(
    response => (response.json \ "data").validate[List[Entity]].get

现在的问题是名为“e54cbe3a434d8e6”的键,我想在我的对象中将其命名为“值”:

// This doesn't work, as one might expect
case class Entity(id: Long, title: String, e54cbe3a434d8e6: Long)

// I would like to use 'value' instead of 'e54cbe3a434d8e6'
case class Entity(id: Long, title: String, value: Long)

关于组合子 here 和 here 的信息很多,但我只想使用与 JSON 数组中的键名不同的字段名。有人可以帮我找到一种简单的方法吗? 我想这和JSON.writes有关?!

【问题讨论】:

    标签: json scala playframework


    【解决方案1】:

    一种不尝试对 json 本身应用转换的简单方法是定义一个自定义读取以处理此问题:

    val json = obj(
      "data" -> obj(
        "id" -> 600, 
        "title" -> "test deal", 
        "e54cbe3a434d8e6" -> 54))
    
    case class Data(id: Long, title: String, value: Int)
    
    val reads = (
      (__ \ "id").read[Long] ~
      (__ \ "title").read[String] ~
      (__ \ "e54cbe3a434d8e6").read[Int] // here you get mapping from your json to Scala case class
    )(Data) 
    
    def index = Action {
      val res = (json \ "data").validate(reads)
      println(res) // prints "JsSuccess(Data(600,test deal,54),)"
      Ok(json)
    }
    

    另一种方法是使用这样的组合器:

    ... the same json and case class
    
    implicit val generatedReads = reads[Data]
    
    def index = Action {
    
      val res = (json \ "data").validate(
        // here we pick value at 'e54cbe3a434d8e6' and put into brand new 'value' branch
        __.json.update((__ \ "value").json.copyFrom((__ \ "e54cbe3a434d8e6").json.pick)) andThen 
    
        // here we remove 'e54cbe3a434d8e6' branch
        (__ \ "e54cbe3a434d8e6").json.prune andThen 
    
        // here we validate result with generated reads for our case class
        generatedReads) 
    
      println(res) // prints "JsSuccess(Data(600,test deal,54),/e54cbe3a434d8e6/e54cbe3a434d8e6)"
      Ok(prettyPrint(json))
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-02
      • 2019-06-03
      • 2018-01-18
      相关资源
      最近更新 更多