将JSON映射到Scala对象的最有效方法是什么?

将JSON映射到Scala对象的最有效方法是什么?,json,scala,playframework,playframework-2.0,Json,Scala,Playframework,Playframework 2.0,我想用Play库解析一些“复杂”的JSON import play.api.libs.json._ 假设我从一个服务器获得了一个包含许多JSON对象的数组,我无法修改它。每个条目看起来都与此相似: { "id": 1, "urn": "urn:article:5", "key": "post", "foo": "useless" } 最后,我想将此结构映射到具有以下值的Scala对象: id:Int=1 urn:String=“urn:user:5” 类型:String=“

我想用Play库解析一些“复杂”的JSON

import play.api.libs.json._
假设我从一个服务器获得了一个包含许多JSON对象的数组,我无法修改它。每个条目看起来都与此相似:

{
  "id": 1,
  "urn": "urn:article:5",
  "key": "post",
  "foo": "useless"
}
最后,我想将此结构映射到具有以下值的Scala对象:

  • id:Int=1
  • urn:String=“urn:user:5”
  • 类型:String=“article\u post”//logic:urn.split(“:”)(1)+“\u”+键
最有效的方法是什么?将JSON框架中的结构映射到我的需要,或者应该尽快使用中间案例类将它们映射到我的自定义结构中

我看了一遍,但他们似乎没有讨论这个问题


目前,我将创建一个中间case类,它只从JSON中提取相关属性(id、urn、key),并在下面的步骤中将这些对象映射到我所需的自定义结构。不知何故,我觉得这不是一个好办法。

您可以在自定义读/写序列化程序中添加这种逻辑。请参阅我关于如何添加自定义项的回答。在这种情况下,我会执行一个
写入
,在您的情况下,您会创建一个
读取
,因为您正在读取JSON并转换为一个类的实例,很可能是一个case类

比如说

case class Wombat(id: Int, urn: String, `type`: String)
implicit val myWombatReads = new Reads[Wombat] {
  def reads(js: JsValue): JsResult[Wombat] = {
    val id = (js \ "id").as[Int]
    val urn = (js \ "urn").as[String]
    val key = (js \ "key").as[String]
    JsSuccess(Wombat(id, urn, urn.split(":")(1) + "_" + key))
  }
}

我没有测试你的自定义逻辑,但你明白了。您还可以添加验证器等。

您可以在自定义读/写序列化程序中添加此类逻辑。请参阅我关于如何添加自定义项的回答。在这种情况下,我会执行一个
写入
,在您的情况下,您会创建一个
读取
,因为您正在读取JSON并转换为一个类的实例,很可能是一个case类

比如说

case class Wombat(id: Int, urn: String, `type`: String)
implicit val myWombatReads = new Reads[Wombat] {
  def reads(js: JsValue): JsResult[Wombat] = {
    val id = (js \ "id").as[Int]
    val urn = (js \ "urn").as[String]
    val key = (js \ "key").as[String]
    JsSuccess(Wombat(id, urn, urn.split(":")(1) + "_" + key))
  }
}
我没有测试你的自定义逻辑,但你明白了。您还可以添加验证器等。

您需要使用

您的转换结果示例:

json.transform(t)

scala> json: play.api.libs.json.JsValue = {"id":1,"urn":"urn:article:5","key":"post","foo":"useless"}

scala> res2: play.api.libs.json.JsResult[play.api.libs.json.JsObject] = JsSuccess({"id":1,"urn":"urn:article:5","type":"article_post"},)
还可以添加一些验证。非常适合。

您需要使用

您的转换结果示例:

json.transform(t)

scala> json: play.api.libs.json.JsValue = {"id":1,"urn":"urn:article:5","key":"post","foo":"useless"}

scala> res2: play.api.libs.json.JsResult[play.api.libs.json.JsObject] = JsSuccess({"id":1,"urn":"urn:article:5","type":"article_post"},)

还可以添加一些验证。非常适合。

小心
因为[XXXX]
抛出异常。是的,这就是为什么我建议验证程序如果你不控制客户端。小心
因为[XXXX]
抛出异常。是的,这就是为什么我建议验证程序如果你不控制客户端。据我所知,你需要验证。对于transformers,你不需要holder类。据我所知,你需要验证。与变压器,你不需要持有人类。