2017-03-27 68 views
0

我有一个案例类,它是一个“字段包” - 很多代表一个业务实体的字段。对于我的使用情况下,区别""nullk/v之间从JSON对象完全不存在是无关的我。在这种情况下,这些字段已经是Option[String] s,所以我希望所有这些案例中的3个崩溃到None。我相信自动生成的Reads的当前行为是我想要的,除了空字符串的情况。如何使用Play Json将JSON空字符串解析为`None`?

这BOF很可能会在未来发生变化,因此“只是实现自己的Reads”(如下建议:make play-json read the empty string as None for a type of Option[T])或别的东西,我不得不重新枚举所有的字段是一个非首发。

我想我可能需要的是Play的'Json变形金刚'。这似乎微不足道写一个变压器,如果他们有空值,消除条目,但我无法弄清楚是如何使用自动生成的Reads实现撰写它。

我想象我需要的是一些结合Reads和变形金刚,一些签名,如:(JSON -> JSON, JSON -> T) -> (JSON -> T)。很明显,我找到了这个页面:https://www.playframework.com/documentation/2.5.x/ScalaJsonCombinators,但是没有一个列出的组合符做我想要的东西,我相信。这个组合器可以轻松实现吗?如果我能得到一些指针,那我会略微偏离我的type-fu深度,但这将是一个很好的解决方案。

回答

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]) 
+0

FWIW我从来没有见过已经看到大量使用的错误情况下,该功能后,打 - 我相信玩的智能不知怎么的,我不是特别了解它的JSON解析 – Alex

+0

很爽的内脏!但它不以'隐VAL myTypeReads =新RemoveEmpty(play.api.libs.json.Reads.localDateTimeReads(DateTimeFormatter.ISO_DATE_TIME))'工作;它会抛出你的“Non-JsObj传递给RemoveEmpty”的错误。任何想法? –