从包含Map的JSON加载对象列表

时间:2014-05-21 15:28:30

标签: json scala

我有一组对象,如:

 class Car(val id: Int, val name: String)

然后,我将在列表中收集一系列汽车

List[Car]();

我希望能够将List [Car]转换为JSON字符串,然后从JSON字符串中加载它。

作为旁注,这个转换过程有多易变,比如说我在User对象中添加了另一个属性? (注意:我不想要一个解决这个问题的答案,只是想知道添加一个项目是否会破坏它)

更新

如何正确处理地图,例如:Map [Int,Long]

说我的模型已更新为包含地图

class Car(val id: Int, val name: String, val options: Map[Int, Long])

使用 play的json 我创建了隐含的写作:

implicit val carWrites = new Writes[Car] {
  def writes(c: Car) = Json.obj{
    "id" -> c.id
    "name" -> c.name
    //"options" -> t.options
  }
}

目前我看到一个错误:找不到类型Map [Int,Long]

的Json序列化程序

4 个答案:

答案 0 :(得分:1)

您是否使用任何现有的工具包来执行此操作?我有Spray-Json的经验。您不必使用整个Spray工具包,您可以单独使用Spray-Json。你的编组很简单。

object UserJsonProtocol extends DefaultJsonProtocol {
  implicit val userFormat = jsonFormat3(User)
}

import UserJsonProtocol._

val jsonFromList = listUsers.toJson
val usersFromJsonString = usersString.parseJson.convertTo[List[User]]

向User类添加字段只需要将jsonFormat更新为正确的字段数。

答案 1 :(得分:1)

使用play-json库(作为独立库提供),您可以自由地向User类添加字段,甚至无需修改用于序列化/反序列化的play-json读/写/格式,例如:类型为Int,String等。但是,如果添加自定义类型,则需要为该字段编写自定义序列化程序。

如果您想进行向后兼容客户端而不知道新字段的更改,请将其设置为类型选项,并且不需要再做任何其他事情。

  1. 即使客户端发送没有customField的JSON:

    ,这也会有效

    class User(val id:Int,val name:String,val age:Int,val customField:Option [String])

  2. 但是如果客户端不包含customField,则会失败(Play JSON没有将customField设置为null,就像Gson for Java所说的那样):

    class User(val id:Int,val name:String,val age:Int,val customField:String)

  3. 干杯,

答案 2 :(得分:1)

如果你正在使用Play框架,那么

case class User(val id: Int, val name: String, val age: Int)

implicit val userReads : Reads[User] = (
 (__ \ "id").read[Int] ~
 (__ \ "name").read[String] ~
 (__ \ "age").read[Int] 
)(User.apply _)

play.api.libs.json.Json.fromJson[User](incomingJson)    

同样定义写入[用户]

答案 3 :(得分:1)

case class Car(id: Int, name: String, options: Map[Int, Long])

object Car{
  implicit val carWrites = new Writes[Car] {
    def writes(c: Car) = Json.obj(
      "id" -> c.id,
      "name" -> c.name,
      "options" -> c.options.map(item=>{
        Json.obj(
          "id" -> item._1,
          "name" -> item._2
        )
      })
     )

  }

  implicit val carReads =
    (__ \ "id").read[Int] ~
      (__ \ "name").read[String] ~
      (__ \ "options").read(
        (__ \ "id").read[Int] ~
        (__ \ "name").read[Long]
      )
    (Car)



}

然后输出它,如果使用Play:

 val x = Car(1,"Porsche",Map(0->1,1->2.toLong))
 val json = Json.toJson(x)
 Ok(json).as("application/json")