PlayFramework 2.2 - Scala - 读取混合数组

时间:2013-11-12 20:06:41

标签: json scala playframework playframework-2.2 playframework-json

我正在尝试使用reader / combinator来解析包含混合数据类型的数组,但我不确定如何为这样的事情指定一个阅读器。我有一些像这样的JSON:

{
  "stuff": [1, 2, true, null, "false", "hahaha", 5, "8"]
}

我想将所有这些解析成字符串表示,但是当我尝试使用List[String]的读者时,我得到了解析异常。我想象这样的事情:

 implicit val mixedArrayReader = (
       (__ \ 'not).readNullable[List[JsValueWrapper]].map(opt => opt.map(list =>
             list.map { wrapper : JsValueWrapper =>
                val parsed : String = wrapper match {
                      case b : JsBoolean => if (b.value) "1" else "0"
                      case n : JsNumber  => n.value.toString
                      case s : JsString  => s.value
                      case JsNull        => "null"
                      case u             => u.toString  // unknown
                   }
                parsed
                }
          ))
 )

但是,由于JsValueWrapper没有读者,我不知道从哪里开始。非常感谢任何帮助。

谢谢!

2 个答案:

答案 0 :(得分:3)

首先实现自定义的Reads [String],然后使用Reads.list将其转换为List[String]的阅读器,然后像往常一样使用该阅读器。希望明确地传递这些特定的读者而不是为他们定义隐含,以便不隐藏Play的默认Reads[String]

import play.api.libs.json.Reads

val myReader: Reads[String] = Reads[String](value => JsSuccess(value match {
  case b : JsBoolean => if (b.value) "1" else "0"
  case n : JsNumber  => n.value.toString
  case s : JsString  => s.value
  case JsNull        => "null"
  case u             => u.toString  // unknown
}))

val listReads = Reads.list[String](myReader)

然后,在组合阅读器中,您可以编写如下内容:

implicit val objReader =
  (__ \ 'not).readNullable(listReads)

答案 1 :(得分:1)

同样的解决方案可能是最直接的。我认为如果你使用.readNullable[List[JsValue]],你的解决方案将会起作用,JsValue是所有Js *类型的超类型,你永远不需要直接使用的包装器,它只是为了帮助轻松创建JSON对象而存在和数组。

另一个更实用,更灵活的解决方案(请注意,此解决方案可以更好地处理错误),您可以使用:

val anyValueAsStringReader =
  implicitly[Reads[BigDecimal]].map(_.toString) or
  implicitly[Reads[String]] or
  implicitly[Reads[Boolean]].map(if (_) "1" else "0") or
  implicitly[Reads[JsValue]].map(_.toString)

val mixedArrayReader = (__ \ 'not).readNullable(Reads.list(anyValueAsStringReader))