我正在尝试(并且失败)了解spray-json如何将json提要转换为对象。如果我有一个简单的密钥 - >值json feed然后它似乎工作正常,但我想要读取的数据出现在这样的列表中:
[{
"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]
那么它可以正常解析但是只要我尝试解析一个数组它就会失败并返回错误{{ 1}}
有人能指出我做错的方向吗?
答案 0 :(得分: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如何读/写(只是在我的情况下阅读)列表对象足以让它工作。
希望能帮到别人!
答案 1 :(得分:2)
通过实现适当的apply和length方法,使Friend数组更易于使用扩展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