首页 > 解决方案 > 如何模式匹配 JsStrings 的 JsArray

问题描述

例如,我有一个简单的作者 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"是字符串数组。如何解决?

标签: scalaspray-json

解决方案


尝试反序列化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包含这样的非字符串

  val raw =
    """
      |{
      |  "name": "string",
      |  "articles": [
      |    1,
      |    "string",
      |    "string"
      |  ]
      |}
    """.stripMargin

我们得到错误

Exception in thread "main" spray.json.DeserializationException: Expected String as JsString, but got 1

推荐阅读