Playframework - JSON 解析具有单个字段的对象 - 定义问题
Playframework - JSON parsing object with single field - definition issue
当反序列化对象只有一个字段时,我找不到如何让它工作的方法 - 我无法编译代码。似乎 and
运算符做了一些转换,我找不到调用方法来做同样的事情。
我关注json:
{"total": 53, "max_score": 3.2948244, "hits": [
{
"_index": "h",
"_type": "B",
"_id": "3413569628",
"_score": 3.2948244,
"_source": {
"fotky": [
{
"popisek":" ",
"localFileSystemLocation":" ",
"isMain": true,
"originalLocation": ""
}
]
}
}
]
}
我尝试将以下数据模型反序列化为:
case class SearchLikeThisResult(total: Int, max_score: Double, hits: Seq[Hits])
case class Hits(_index: String, _type: String, _id: String, _score: Double, _source: Source)
case class Source(fotky: Seq[Photo])
case class Photo(isMain: Boolean, originalLocation: Option[String], localFileSystemLocation: Option[String], popisek: Option[String])
隐式如下:
object SearchLikeThisHits {
import play.api.libs.functional.syntax._
implicit val photoReads: Reads[Photo] = (
(JsPath \ "isMain").read[Boolean] and
(JsPath \ "originalLocation").readNullable[String] and
(JsPath \ "localFileSystemLocation").readNullable[String] and
(JsPath \ "popisek").readNullable[String]
)(Photo.apply _)
implicit val sourceReads: Reads[Source] = (
(JsPath \ "fotky").read[Seq[Photo]]
)(Source.apply _)
implicit val hitsReads: Reads[Hits] = (
(JsPath \ "_index").read[String] and
(JsPath \ "_type").read[String] and
(JsPath \ "_id").read[String] and
(JsPath \ "_score").read[Double] and
(JsPath \ "_source").read[Source]
)(Hits.apply _)
implicit val searchLikeThisResult: Reads[SearchLikeThisResult] = (
(JsPath \ "total").read[Int] and
(JsPath \ "max_score").read[Double] and
(JsPath \ "hits").read[Seq[Hits]]
)(SearchLikeThisResult.apply _)
}
我真正纠结的是_source:
implicit val sourceReads: Reads[Source] = (
(JsPath \ "fotky").read[Seq[Photo]]
)(Source.apply _)
其中读取被报告为未知符号 - 在其他情况下 and
执行一些转换。
内联定义也无济于事。
有人遇到过这个问题吗?
您可以通过使用 Json.reads
自动生成您的 Reads
来省去一些麻烦(前提是 class 的定义与 Json 对象完全相同- 这就是你的情况)。
implicit val photoReads = Json.reads[Photo]
implicit val sourceReads = Json.reads[Source]
implicit val hitsReads = Json.reads[Hits]
implicit val searchResultReads = Json.reads[SearchLikeThisResult]
有关详细信息,请参阅 https://www.playframework.com/documentation/2.1.1/ScalaJsonInception
花哨的应用程序构建器语法(and
等)很不错,但它可能掩盖了 Reads
是一元的并且与 map
完美配合的事实,flatMap
, for
-理解等
因此,虽然应用构建器语法不适用于单个值,但普通的旧 map
可以:
implicit val sourceReads: Reads[Source] =
(JsPath \ "fotky").read[Seq[Photo]].map(Source(_))
这里的关键是 (JsPath \ "fotky").read[Seq[Photo]]
是一个 Reads[Seq[Photo]]
,而你想要一个 Reads[Source]
。 map
为您提供了一种从一个到另一个的方法,就像您可以使用它来将 Option[Seq[Photo]]
转换为 Option[Source
,例如。
当反序列化对象只有一个字段时,我找不到如何让它工作的方法 - 我无法编译代码。似乎 and
运算符做了一些转换,我找不到调用方法来做同样的事情。
我关注json:
{"total": 53, "max_score": 3.2948244, "hits": [
{
"_index": "h",
"_type": "B",
"_id": "3413569628",
"_score": 3.2948244,
"_source": {
"fotky": [
{
"popisek":" ",
"localFileSystemLocation":" ",
"isMain": true,
"originalLocation": ""
}
]
}
}
]
}
我尝试将以下数据模型反序列化为:
case class SearchLikeThisResult(total: Int, max_score: Double, hits: Seq[Hits])
case class Hits(_index: String, _type: String, _id: String, _score: Double, _source: Source)
case class Source(fotky: Seq[Photo])
case class Photo(isMain: Boolean, originalLocation: Option[String], localFileSystemLocation: Option[String], popisek: Option[String])
隐式如下:
object SearchLikeThisHits {
import play.api.libs.functional.syntax._
implicit val photoReads: Reads[Photo] = (
(JsPath \ "isMain").read[Boolean] and
(JsPath \ "originalLocation").readNullable[String] and
(JsPath \ "localFileSystemLocation").readNullable[String] and
(JsPath \ "popisek").readNullable[String]
)(Photo.apply _)
implicit val sourceReads: Reads[Source] = (
(JsPath \ "fotky").read[Seq[Photo]]
)(Source.apply _)
implicit val hitsReads: Reads[Hits] = (
(JsPath \ "_index").read[String] and
(JsPath \ "_type").read[String] and
(JsPath \ "_id").read[String] and
(JsPath \ "_score").read[Double] and
(JsPath \ "_source").read[Source]
)(Hits.apply _)
implicit val searchLikeThisResult: Reads[SearchLikeThisResult] = (
(JsPath \ "total").read[Int] and
(JsPath \ "max_score").read[Double] and
(JsPath \ "hits").read[Seq[Hits]]
)(SearchLikeThisResult.apply _)
}
我真正纠结的是_source:
implicit val sourceReads: Reads[Source] = (
(JsPath \ "fotky").read[Seq[Photo]]
)(Source.apply _)
其中读取被报告为未知符号 - 在其他情况下 and
执行一些转换。
内联定义也无济于事。
有人遇到过这个问题吗?
您可以通过使用 Json.reads
自动生成您的 Reads
来省去一些麻烦(前提是 class 的定义与 Json 对象完全相同- 这就是你的情况)。
implicit val photoReads = Json.reads[Photo]
implicit val sourceReads = Json.reads[Source]
implicit val hitsReads = Json.reads[Hits]
implicit val searchResultReads = Json.reads[SearchLikeThisResult]
有关详细信息,请参阅 https://www.playframework.com/documentation/2.1.1/ScalaJsonInception
花哨的应用程序构建器语法(and
等)很不错,但它可能掩盖了 Reads
是一元的并且与 map
完美配合的事实,flatMap
, for
-理解等
因此,虽然应用构建器语法不适用于单个值,但普通的旧 map
可以:
implicit val sourceReads: Reads[Source] =
(JsPath \ "fotky").read[Seq[Photo]].map(Source(_))
这里的关键是 (JsPath \ "fotky").read[Seq[Photo]]
是一个 Reads[Seq[Photo]]
,而你想要一个 Reads[Source]
。 map
为您提供了一种从一个到另一个的方法,就像您可以使用它来将 Option[Seq[Photo]]
转换为 Option[Source
,例如。