我正在尝试在我的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)
基本上,text
andnum
字段Field2
是value/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] 删除。
我来说两句