我尝试为这样的过滤器实现json验证:
import play.api.libs.json._
import play.api.libs.functional.syntax._
trait IFilterClause
case class ComparisonClause(operand: String, operator: String, value: String, valueType: String) extends IFilterClause{
implicit val comparisonClauseReads: Reads[ComparisonClause] = (
(JsPath \ "operand").read[String] and
(JsPath \ "operator").read[String] and
(JsPath \ "value").read[String] and
(JsPath \ "value_type").read[String]
)(ComparisonClause.apply _)
}
case class LogicalClause(operator: String, children: List[IFilterClause]) extends IFilterClause {
implicit lazy val logicalClauseReads: Reads[IFilterClause] = (
(JsPath \ "logical_operator").read[String] and
((JsPath \ "children").read[LogicalClause] or (JsPath \ "children").read[ComparisonClause])
)(LogicalClause.apply _)
}
正如你在我的LogicalClause上看到的那样,我的孩子们可能是一个具有相同格式的LogicalClause的json或者一个具有ComparisonClause格式的json,但我可以想象它是如何使这个工作的。
有任何建议吗?
我收到以下错误:
找不到类型的Json反序列化器 com.userzoom.analytics.explorerapi.models.LogicalClause。尝试 为此类型实现隐式读取或格式。 [错误]
((JsPath \“children”)。读取[LogicalClause]或(JsPath \ “儿童”)。读[ComparisonClause])
答案 0 :(得分:0)
首先,您应该将implicit
放在随播对象中,而不是放在case class
中。你可以尝试这段代码,它应该编译:
import play.api.libs.json._
import play.api.libs.functional.syntax._
trait IFilterClause
case class ComparisonClause(operand: String, operator: String, value: String, valueType: String) extends IFilterClause
object ComparisonClause {
implicit val comparisonClauseReads: Reads[ComparisonClause] = (
(JsPath \ "operand").read[String] and
(JsPath \ "operator").read[String] and
(JsPath \ "value").read[String] and
(JsPath \ "value_type").read[String]
)(ComparisonClause.apply _)
}
case class LogicalClause(operator: String, children: List[IFilterClause]) extends IFilterClause
object LogicalClause {
implicit lazy val logicalClauseReads: Reads[LogicalClause] = (
(JsPath \ "logical_operator").read[String] and
(JsPath \ "children").read[List[IFilterClause]]
)(LogicalClause.apply _)
}
object IFilterClause {
implicit lazy val reader: Reads[IFilterClause] = {
// needed because Reads is invariant
val reader1 = ComparisonClause.comparisonClauseReads.map(f => f: IFilterClause)
lazy val reader2 = LogicalClause.logicalClauseReads.map(f => f: IFilterClause)
reader1 orElse reader2
}
}