播放Json-复杂的对象创建

杰夫

我正在尝试在我的Play框架应用程序(Scala)中创建Json阅读器。问题是,我的Json的一部分有点时髦,需要进一步处理才能检索值。例如:

{  
  "field1":"value1",
  "field2":"value/1",
  "num2":2
}

与案例类:

case class Field1(text: String, fields: Field2)
case class Field2(text: String, num: Int, num2: Int)

基本上,textandnum字段Field2value/1通过拆分文本从该值派生的。这是分离器功能:

def splitter(path: String, num2: Int): Field2 = {
  val split = path.split("\\")
  Field2(split(0), split(1).toInt, num2)
}

这非常简单,实际的拆分器功能要复杂得多。基本上,构造此对象的唯一方法Field2是将单个字符串传递给吐出所需对象的函数。

如何为创建阅读器Field2(并通过扩展为Field1)?

这是我到目前为止的内容:

object Field1 {
    implicit val reader = (
        (__ \ "field1").read[String] and
        (__).read[Field2]
    ) (Field1.apply _)
}

object Field2 {
    implicit val reader = (
        splitter((__ \ "field2").read[String], (__ \ "num2"))
    ) // Obviously incorrect syntax + type mismatch, but this is roughly what I'm trying to accomplish.
}
格雷格兹

如果您使用非功能组合器语法,我认为它会变得简单一些:

object Field2 {
  implicit val reader = Reads[Field2] { json =>
    for {
      path <- (json \ "field2").validate[String]
      num2 <- (json \ "num2").validate[Int]
    } yield splitter(path, num2)
  }
}

另外,如果您希望拆分器进一步验证输入,请让其返回JsResult[Field2]类似以下内容的内容:

def splitter(path: String, num2: Int): JsResult[Field2] = {
  val split = path.split("\\")
  if (split.size != 2) {
    JsError(s"$path must be of the form: {field}\\{num}")
  } else {
    Try(Field2(split(0), split(1).toInt, num2)).map(JsSuccess(_)).getOrElse {
      JsError(s"${split(1)} is not a valid Int")
    }
  }
}

然后修改阅读器:

object Field2 {
  implicit val reader = Reads[Field2] { json =>
    for {
      path <- (json \ "field2").validate[String]
      num2 <- (json \ "num2").validate[Int]
      field2 <- splitter(path, num2)
    } yield field2
  }
}

如果您仍然喜欢使用函数语法,并且不介意缺少验证器,那么splitter可以尝试以下操作:

def splitter(path: String, num2: Int): Field2 = {
  val split = path.split("\\")
  Field2(split(0), split(1).toInt, num2)
}

implicit val reader = (
  (__ \ "field2").read[String] and
  (__ \ "num2").read[Int]
)(splitter _)

我建议不要这样做,因为这是不安全的(split(1)并且toInt两者都可能引发异常),并且函数语法可能会出现性能问题。参见https://www.lucidchart.com/techblog/2016/08/29/speeding-up-restful-services-in-play-framework/

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章