如何使用Play Json将JSON空字符串解析为“None”?

时间:2017-03-27 17:06:53

标签: json scala playframework

我有一个案例类别" Bag of Fields" - 许多代表商业实体的字段。对于我的用例,JSON对象中完全不存在""nullk/v之间的区别与我无关。在这种情况下,这些字段已经是Option[String]个,所以我希望所有这三个案例都崩溃到None。我相信自动生成的Reads的当前行为是我想要的,除了空字符串情况。

这个BOF将来可能会发生变化,所以"只需实现自己的Reads" (正如这里所建议的那样:make play-json read the empty string as None for a type of Option[T])或其他我需要重新枚举所有字段的内容是非首发。

我认为我可能需要的是Play' Json Transformers'。如果它们具有空值,则编写一个删除条目的变换器似乎微不足道,但我不知道如何使用自动生成的Reads实现来组合它。

我想我需要的是Reads和变形金刚之间的组合,有些签名如:(JSON -> JSON, JSON -> T) -> (JSON -> T)。显然我已经找到了这个页面:https://www.playframework.com/documentation/2.5.x/ScalaJsonCombinators,但是没有一个列出的组合器做我想要的东西。这个组合器可以轻松实现吗?我有点超出了我的类型 - 深度,但如果我能得到一些指示,这将是一个很好的解决方案。

1 个答案:

答案 0 :(得分:1)

这对我有用:

class RemoveEmpty[T] (reader: Reads[T]) extends Reads[T] {
  override def reads(json: JsValue): JsResult[T] = json match {
    case JsObject(underlying) => { 
      reader.reads(JsObject(underlying.filterNot{ case (k, v) => jsonValueEmpty(v) } ))
    }
    case _ => { 
      JsError("Non-JsObj passed to RemoveEmpty")
    }
  }

  def jsonValueEmpty(v: JsValue) = v match {
    case JsNull | JsString("") => true
    case _ => false
  }
}

然后你可以像这样使用它:

implicit val myTypeReads = new RemoveEmpty(Json.reads[MyType])