使用Spray-json解析简单数组

7

我试图理解spray-json如何将json数据转换为对象,但一直无法成功。如果我有一个简单的键-值json数据源,那么它似乎可以正常工作,但我想要读取的数据是以这样的列表形式呈现:

[{
    "name": "John",
    "age": "30"
},
{
    "name": "Tom",
    "age": "25"
}]

我的代码看起来像这样:

package jsontest

import spray.json._
import DefaultJsonProtocol._

object JsonFun {

  case class Person(name: String, age: String)
  case class FriendList(items: List[Person])

  object FriendsProtocol extends DefaultJsonProtocol {
    implicit val personFormat = jsonFormat2(Person)
    implicit val friendListFormat = jsonFormat1(FriendList)
  }

  def main(args: Array[String]): Unit = {

    import FriendsProtocol._

    val input = scala.io.Source.fromFile("test.json")("UTF-8").mkString.parseJson

    val friendList = input.convertTo[FriendList]

    println(friendList)
  }

}    

如果我更改我的测试文件,使其只有一个不在数组中的人,并运行val friendList = input.convertTo [Person] ,那么它可以工作并且一切都可以解析,但是一旦我尝试解析数组,就会出现错误对象在字段“items”中期望 有人可以指出我做错了什么吗?

你能发一下你试图解码的JSON的例子吗? - Max Heiber
2个回答

9

经常在StackOverflow上发布问题并花费数小时尝试解决问题后,这种情况通常会发生:我已经成功使其工作。

FriendsProtocol的正确实现如下:

object FriendsProtocol extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat2(Person)
  implicit object friendListJsonFormat extends RootJsonFormat[FriendList] {
    def read(value: JsValue) = FriendList(value.convertTo[List[Person]])
    def write(f: FriendList) = ???
  } 
}

告诉Spray如何读取/写入(在我的情况下只读取)列表对象就足以使其正常工作。
希望这对其他人有所帮助!

2
为了使Friend数组更易使用,通过实现适当的apply和length方法扩展IndexedSeq [Person]特性。这将允许标准的Scala Collections API方法(如map,filter和sortBy)直接在FriendsArray实例本身上运行,而无需访问其包装的基础Array [Person]值。
case class Person(name: String, age: String)

// this case class allows special sequence trait in FriendArray class
// this will allow you to use .map .filter etc on FriendArray
case class FriendArray(items: Array[Person]) extends IndexedSeq[Person] {
    def apply(index: Int) = items(index)
    def length = items.length
}

object FriendsProtocol extends DefaultJsonProtocol {
  implicit val personFormat = jsonFormat2(Person)
  implicit object friendListJsonFormat extends RootJsonFormat[FriendArray] {
    def read(value: JsValue) = FriendArray(value.convertTo[Array[Person]])
    def write(f: FriendArray) = ???
  } 
}

import FriendsProtocol._

val input = jsonString.parseJson
val friends = input.convertTo[FriendArray]
friends.map(x => println(x.name))
println(friends.length)

这将会打印出以下内容:
John
Tom
2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接