喷涂JSON:灵活性数组/对象

时间:2018-05-21 13:46:44

标签: json scala json-deserialization spray-json

使用Spray JSON,我希望能够解析一个String数组,但是如果有一个String,它仍然可以正确地反序列化。 也就是说,用这个字段:

arrayval: List[String]

和这个JSON:

arrayval: ["a", "b"]

它会创建一个List(" a"," b"),并使用此JSON:

arrayval: "a"

它会创建一个List(" a")。 使用默认的listFormat,它会在第二种情况下抱怨。 有没有办法配置这种灵活性?

1 个答案:

答案 0 :(得分:1)

如果它对任何人都有帮助,我通过覆盖CollectionFormats(在DefaultJsonProtocol中使用)中的listFormat来解决它。

trait FlexibleCollectionFormats extends CollectionFormats {

  implicit override def listFormat[T: JsonFormat] = new RootJsonFormat[List[T]] {
    import spray.json._

    def write(list: List[T]) = JsArray(list.map(_.toJson).toVector)
    def read(value: JsValue): List[T] = value match {
      case JsArray(elements) => elements.map(_.convertTo[T])(collection.breakOut)
      case JsString(element) => List[T](new JsString(element).convertTo[T]) 
      case x                 => deserializationError("Expected List as JsArray, but got " + x)
    }
  }
}

然后我创建了自己的协议而不是DefaultJsonProtocol,它基本上使用与Default相同的协议但覆盖了CollectionFormats:

trait FlexibleDefaultJsonProtocol
        extends BasicFormats
        with StandardFormats
        // with CollectionFormats
        with FlexibleCollectionFormats
        with ProductFormats
        with AdditionalFormats

object FlexibleDefaultJsonProtocol extends FlexibleDefaultJsonProtocol

稍后您使用extends FlexibleDefaultJsonProtocol而不是DefaultJsonProtocol。你总是可以在课堂上切换和使用其中一个,所以我喜欢它提供的flex。