如何模式匹配 JsStrings 的 JsArray
How to pattern match JsArray of JsStrings
例如我有一个简单的作者JSON:
{
"name": "string",
"articles": [
"string",
"string",
"string"
]
}
我正在定义Json阅读格式:
implicit object authorFormat extends RootJsonFormat[Author] {
override def write(a: Author) = ???
override def read(json: JsValue) = json.asJsObject.getFields("name", "articles") match {
case Seq(JsString(name), JsArray(articles)) => ... //Build author
}
}
此模式匹配保证 "articles"
是一个数组(JsValues
)。但它不能保证 "articles"
是一个字符串数组。如何解决?
像这样尝试将 articles
反序列化为 List[String]
articles.map(_.convertTo[String]).toList
如果 jsonFormat2
不是一个选项。这是一个工作示例
import spray.json._
import DefaultJsonProtocol._
object MyApp extends App {
case class Author(name: String, articles: List[String])
implicit object authorFormat extends RootJsonFormat[Author] {
override def write(a: Author) = ???
override def read(json: JsValue) = json.asJsObject.getFields("name", "articles") match {
case Seq(JsString(name), JsArray(articles)) => Author(name, articles.map(_.convertTo[String]).toList)
}
}
val raw =
"""
|{
| "name": "string",
| "articles": [
| "string,
| "string",
| "string"
| ]
|}
""".stripMargin
val json = raw.parseJson
val author = json.convertTo[Author]
println(author)
}
输出
Author(string,List(string, string, string))
而如果 articles
包含一个 non-string 就像这样
val raw =
"""
|{
| "name": "string",
| "articles": [
| 1,
| "string",
| "string"
| ]
|}
""".stripMargin
我们收到错误
Exception in thread "main" spray.json.DeserializationException: Expected String as JsString, but got 1
例如我有一个简单的作者JSON:
{
"name": "string",
"articles": [
"string",
"string",
"string"
]
}
我正在定义Json阅读格式:
implicit object authorFormat extends RootJsonFormat[Author] {
override def write(a: Author) = ???
override def read(json: JsValue) = json.asJsObject.getFields("name", "articles") match {
case Seq(JsString(name), JsArray(articles)) => ... //Build author
}
}
此模式匹配保证 "articles"
是一个数组(JsValues
)。但它不能保证 "articles"
是一个字符串数组。如何解决?
像这样尝试将 articles
反序列化为 List[String]
articles.map(_.convertTo[String]).toList
如果 jsonFormat2
不是一个选项。这是一个工作示例
import spray.json._
import DefaultJsonProtocol._
object MyApp extends App {
case class Author(name: String, articles: List[String])
implicit object authorFormat extends RootJsonFormat[Author] {
override def write(a: Author) = ???
override def read(json: JsValue) = json.asJsObject.getFields("name", "articles") match {
case Seq(JsString(name), JsArray(articles)) => Author(name, articles.map(_.convertTo[String]).toList)
}
}
val raw =
"""
|{
| "name": "string",
| "articles": [
| "string,
| "string",
| "string"
| ]
|}
""".stripMargin
val json = raw.parseJson
val author = json.convertTo[Author]
println(author)
}
输出
Author(string,List(string, string, string))
而如果 articles
包含一个 non-string 就像这样
val raw =
"""
|{
| "name": "string",
| "articles": [
| 1,
| "string",
| "string"
| ]
|}
""".stripMargin
我们收到错误
Exception in thread "main" spray.json.DeserializationException: Expected String as JsString, but got 1