0

Using Spray JSON, I would like to be able to parse an array of String, but still be able to deserialize correctly if a single String comes. That is, with this field:

arrayval: List[String]

and this JSON:

arrayval: ["a", "b"]

it would create a List("a","b"), and with this JSON:

arrayval: "a"

it would create a List("a"). Using default listFormat it would complain in the second case. Is there a way to configure this kind of flexibility?

1 Answer 1

1

In case it helps anyone, I've solved it by overriding the listFormat in the CollectionFormats (which is used in the DefaultJsonProtocol).

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)
    }
  }
}

Then I created my own protocol instead of DefaultJsonProtocol, that basically uses the same ones as Default but overriding the CollectionFormats:

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

object FlexibleDefaultJsonProtocol extends FlexibleDefaultJsonProtocol

and later you use extends FlexibleDefaultJsonProtocol instead of DefaultJsonProtocol. You can always switch and use one or the other in your classes, so I like the flex it provides.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.