json 嵌套的作者 类
json writer for nested classes
我正在使用 Play! Scala 2.2,我在 Json
中呈现 class
时遇到问题:
我有两个 类,一个依赖另一个,如下:
case class Artist(id: String, cover: String, website: List[String], link: String, Tracks: List[Track] = List())
case class Track(stream_url: String, title: String, artwork_url: Option[String] )
以及他们隐含的作家:
implicit val artistWrites: Writes[Artist] = Json.writes[Artist]
implicit val trackWrites: Writes[Track] = Json.writes[Track]
写手们的工作很好,如下:
println(Json.toJson(Track("aaa", "aaa", Some("aaa"))))
println(Json.toJson(Artist("aaa", "aaa", List("aaa"), "aaa", List())))
即如果 Artist
有一个 空 list of tracks
。
但是如果我想这样做:
println(Json.toJson(Artist("aaa", "aaa", List("aaa"), "aaa", List(SoundCloudTrack("ljkjk", "ljklkj", Some("lkjljk"))))))
我得到一个 execution exception
: [NullPointerException: null]
你能解释一下我做错了什么吗?
问题出在初始化顺序上。 Json.writes[Artist]
需要隐含的 Writes[Track]
才能生成自身。编译器能够找到隐式 Writes[Track]
,因为您在同一个对象中声明它,但是 trackWrites
在 之后初始化 artistWrites
,也就是说调用Json.writes[Artist]
时,trackWrites
就是null
。但是,这不会中断 artistWrites
的创建,因此在实际使用之前不会引起注意。
您可以通过简单地切换初始化顺序来解决此问题,因此 trackWrites
是第一个。
使用 Play 2.8,操作起来非常简单,以下对我有用:
假设我有三个 类:
case class InnerBean(fieldName: String, status: String, ruleCode: Int, subRuleCode: List[Int])
case class IntermediateBean(itemId: Long, innerBeanData: Option[List[InnerBean]])
case class OuterBean(uniqueTrackingId: String, intermediateBeanData: List[IntermediateBean])
implicit val innerBeanWrites: Writes[InnerBean] = Json.writes[InnerBean]
implicit val intermediateBeanWrites: Writes[IntermediateBean] = Json.writes[IntermediateBean]
implicit val outerBeanWrites: Writes[OuterBean] = Json.writes[OuterBean]
我正在使用 Play! Scala 2.2,我在 Json
中呈现 class
时遇到问题:
我有两个 类,一个依赖另一个,如下:
case class Artist(id: String, cover: String, website: List[String], link: String, Tracks: List[Track] = List())
case class Track(stream_url: String, title: String, artwork_url: Option[String] )
以及他们隐含的作家:
implicit val artistWrites: Writes[Artist] = Json.writes[Artist]
implicit val trackWrites: Writes[Track] = Json.writes[Track]
写手们的工作很好,如下:
println(Json.toJson(Track("aaa", "aaa", Some("aaa"))))
println(Json.toJson(Artist("aaa", "aaa", List("aaa"), "aaa", List())))
即如果 Artist
有一个 空 list of tracks
。
但是如果我想这样做:
println(Json.toJson(Artist("aaa", "aaa", List("aaa"), "aaa", List(SoundCloudTrack("ljkjk", "ljklkj", Some("lkjljk"))))))
我得到一个 execution exception
: [NullPointerException: null]
你能解释一下我做错了什么吗?
问题出在初始化顺序上。 Json.writes[Artist]
需要隐含的 Writes[Track]
才能生成自身。编译器能够找到隐式 Writes[Track]
,因为您在同一个对象中声明它,但是 trackWrites
在 之后初始化 artistWrites
,也就是说调用Json.writes[Artist]
时,trackWrites
就是null
。但是,这不会中断 artistWrites
的创建,因此在实际使用之前不会引起注意。
您可以通过简单地切换初始化顺序来解决此问题,因此 trackWrites
是第一个。
使用 Play 2.8,操作起来非常简单,以下对我有用:
假设我有三个 类:
case class InnerBean(fieldName: String, status: String, ruleCode: Int, subRuleCode: List[Int])
case class IntermediateBean(itemId: Long, innerBeanData: Option[List[InnerBean]])
case class OuterBean(uniqueTrackingId: String, intermediateBeanData: List[IntermediateBean])
implicit val innerBeanWrites: Writes[InnerBean] = Json.writes[InnerBean]
implicit val intermediateBeanWrites: Writes[IntermediateBean] = Json.writes[IntermediateBean]
implicit val outerBeanWrites: Writes[OuterBean] = Json.writes[OuterBean]