Scala Play JSON如何捕获完整的JSON源数据?
解决方案
你可以通过以下两种方式实现需求,无需繁琐的手动解析:
方案一:自定义Format实现
直接定义读取和写入逻辑,既保留完整JSON,又正确提取指定字段:
import play.api.libs.json._ case class MyData(json: JsValue, id: Int, name: String) implicit val myDataFormat: Format[MyData] = Format( // 读取时:先验证id和name的合法性,再将完整JSON传入MyData Reads[MyData] { js => for { id <- (js \ "id").validate[Int] name <- (js \ "name").validate[String] } yield MyData(js, id, name) }, // 写入时:直接输出保存的完整JSON Writes[MyData] { data => data.json } )
使用时直接调用response.json.as[MyData]即可,json字段会完整保留原始响应内容,id和name也能正确解析。
方案二:利用路径组合器简化写法
如果你偏好Play框架的组合器风格,可以直接用根路径读取完整JSON,再和子路径组合:
implicit val myDataFormat: Format[MyData] = ( JsPath.root.read[JsValue] ~ (__ \ "id").read[Int] ~ (__ \ "name").read[String] )(MyData.apply, unlift(MyData.unapply))
这种方式中,Play的组合器会对同一个输入JSON分别执行三个读取操作:根路径获取完整JSON、子路径提取id和name,最终组合成MyData实例。
问题原因说明
你之前用(__).formatNullable[JsValue]失败,是因为formatNullable是用来解析可选字段的,但根路径并非一个字段,而是整个JSON对象,改用read[JsValue]直接读取整个对象就可以避免这个问题。
内容的提问来源于stack exchange,提问作者Vlad Patryshev
相关产品推荐
相关产品推荐

