【问题标题】:Play! Scala: Json reader and additional class field玩! Scala:Json 阅读器和附加类字段
【发布时间】:2015-02-26 07:55:35
【问题描述】:

我正在使用 Play! Scala 2.2,我正在阅读 json 如下,效果很好:

case class YoutubeTrack(//artistId: String,
                          videoId: String,
                          title: String,
                          thumbnail: Option[String] )
val youtubeTrackReads: Reads[YoutubeTrack] = (
      (__ \ "id" \ "videoId").read[String] and
        (__ \ "snippet" \ "title").read[String] and
        (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
      )(YoutubeTrack)

现在我想在我的YoutubeTrack class 中添加一个字段(在类声明中注释的artistId)。 该字段是我在其他地方定义的变量。

如何在读取 json 的同时将此字段添加到我的 YoutubeTrack 中,即我想做类似的事情:

val youtubeTrackReads: Reads[YoutubeTrack] = (
      (__ \ "id" \ "videoId").read[String] and
        (__ \ "snippet" \ "title").read[String] and
        (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
      )((artistId, videoId, title, url) => YoutubeTrack(artistId, videoId, title, url))

【问题讨论】:

  • 这取决于您是否认为这个额外的字段是可选的(可以在 init 之后定义,也可以不定义),或者在某些时候该字段是强制性的。

标签: json scala playframework-2.2


【解决方案1】:

给定函数

def toArtistId(
    videoId: String,
    title: String,
    thumbnail: Option[String]): String = ...
  1. 您甚至可以在不更改阅读器的情况下添加您的艺术家 ID

    case class YoutubeTrack(
        videoId: String,
        title: String,
        thumbnail: Option[String]) {
        val artistId = toArtistId(videoId, title, thumbnail)
    }
    
  2. 或者像这样改变你的阅读器

    (
        (__ \ "id" \ "videoId").read[String] and 
        (__ \ "snippet" \ "title").read[String] and
        (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
    )((videoId, title, thumbnail) => 
         YoutubeTrack(toArtistId(videoId, title, thumbnail), videoId, title, thumbnail)
    )
    
  3. 甚至像这样

    def artistReader(artistId: String): Reads[YoutubeTrack] = {
        (
            (__ \ "id" \ "videoId").read[String] and
            (__ \ "snippet" \ "title").read[String] and
            (__ \ "snippet" \ "thumbnails" \ "default" \ "url").readNullable[String]
        )((videoId, title, thumbnail) => 
            YoutubeTrack(artistId, videoId, title, thumbnail))
    }
    
    artistReader("A")
    

【讨论】:

    【解决方案2】:
    case class YoutubeTrackTemp(
      videoId: String,
      title: String,
      thumbnail: Option[ String ]
    )
    
    val youtubeTrackReads: Reads[ YoutubeTrack ] = (
      ( __ \ "id" \ "videoId" ).read[ String ] and
        ( __ \ "snippet" \ "title" ).read[ String ] and
        ( __ \ "snippet" \ "thumbnails" \ "default" \ "url" ).readNullable[ String ]
      )( YoutubeTrackTemp )
    
    case class YoutubeTrack(
      artistId: String,
      videoId: String,
      title: String,
      thumbnail: Option[ String ]
    )
    
    object YoutubeTrack {
      def apply( yt: YoutubeTrackTemp ): YoutubeTrack = {
        val artistId = getArtistIdSomehow()
        YoutubeTrack( artistId, yt.videoId, yt.title, yt.thumbnail )
      } 
    }
    
    val youtubeTrack = YoutubeTrack( myjson.as[ YoutubeTrackTemp ] )
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 2015-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多