如何模式匹配 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