使用play.api.libs.json库,只要使用单个Reads[T]
表达式,我就无法创建JsPath.read
对象。
在下面的代码中,仅当Reads[T]
定义使用两个或更多JsPath.read
个表达式时,我才能读取文件。只使用一个,我得到以下编译器错误:
Error:(33, -1) Play 2 Compiler: C:\..\data\JsonReads.scala:33:25: overloaded method value read with alternatives: (t: Int)play.api.libs.json.Reads[Int] (implicit r: play.api.libs.json.Reads[Int])play.api.libs.json.Reads[Int] Error:(41, -1) Play 2 Compiler: C:\..\data\JsonReads.scala:41:20: overloaded method value read with alternatives: (t: JsonReads.Two)play.api.libs.json.Reads[JsonReads.Two] (implicit r: play.api.libs.json.Reads[JsonReads.Two])play.api.libs.json.Reads[JsonReads.Two]
为什么我会收到这些编译错误?
import play.api.libs.functional.syntax._
import play.api.libs.json.{JsValue, _}
import scala.io.Source
/**
* one.json:
* {
* "one" : 1
* }
*
* two.json:
* {
* "one" : 1,
* "two" : 2
* }
*
* two.single.json:
* {
* "a" : {
* "one": 1,
* "two": 2
* }
* }
*
* two.double.json
* {
* "a": {
* "one": 1,
* "two": 2
* },
* "b": {
* "one": 1,
* "two": 2
* }
* }
*
*/
object JsonReads {
case class One(one: Int)
case class Two(one: Int, two: Int)
case class SingleTwo(a: Two)
case class DoubleTwo(a: Two, b: Two)
// THIS WILL NOT COMPILE
// implicit val oneReads: Reads[One] = (
// (__ \ "one")).read[Int](One)
implicit val twoReads: Reads[Two] = (
(__ \ "one").read[Int] ~
(__ \ "two").read[Int]) (Two)
// THIS WILL NOT COMPILE
// implicit val singleTwoReads: Reads[SingleTwo] = (
// (__ \ "a").read[Two]) (SingleTwo)
implicit val doubleTwoReads: Reads[DoubleTwo] = (
(__ \ "a").read[Two] ~
(__ \ "b").read[Two]
) (DoubleTwo)
def load(name: String): JsValue = {
val url = getClass.getResource(s"/data/${name}.json")
val reader = Source.fromURL(url).bufferedReader
val text = reader.lines.toArray.mkString("")
Json.parse(text)
}
def main(a: Array[String]): Unit = {
val oneJsValue: JsValue = load("one")
/* oneJsValue.validate[One](oneReads) match {
case s: JsSuccess[One] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
} */
val twoJsValue: JsValue = load("two")
twoJsValue.validate[Two](twoReads) match {
case s: JsSuccess[Two] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
}
val singleTwoJsValue: JsValue = load("two.single")
/* twoJsValue.validate[SingleTwo](singleTwoReads) match {
case s: JsSuccess[SingleTwo] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
} */
val doubleTwoJsValue: JsValue = load("two.double")
doubleTwoJsValue.validate[DoubleTwo](doubleTwoReads) match {
case s: JsSuccess[DoubleTwo] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
}
}
}
答案 0 :(得分:0)
Reads
是一个仿函数。所以正确的代码是
implicit val oneReads: Reads[One] = (__ \ "one").read[Int].map(One)
implicit val singleTwoReads: Reads[SingleTwo] = (__ \ "a").read[Two].map(SingleTwo)
测试:
def main(a: Array[String]): Unit = {
val oneJsValue: JsValue = load("one")
oneJsValue.validate[One](oneReads) match {
case s: JsSuccess[One] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
} // Found: One(1)
val twoJsValue: JsValue = load("two")
twoJsValue.validate[Two](twoReads) match {
case s: JsSuccess[Two] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
} // Found: Two(1,2)
val singleTwoJsValue: JsValue = load("two.single")
singleTwoJsValue.validate[SingleTwo](singleTwoReads) match {
case s: JsSuccess[SingleTwo] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
} // Found: SingleTwo(Two(1,2))
val doubleTwoJsValue: JsValue = load("two.double")
doubleTwoJsValue.validate[DoubleTwo](doubleTwoReads) match {
case s: JsSuccess[DoubleTwo] => println(s"Found: ${s.get.toString}")
case e: JsError => println("Errors: " + JsError.toJson(e).toString())
} // Found: DoubleTwo(Two(1,2),Two(1,2))
}
https://www.playframework.com/documentation/2.6.x/ScalaJsonCombinators#Path-Reads