2017-11-20 1 views
0

ich so ein json Validierungen für einen Filter implemente versuchen:Scala Prüft rekursive JSON mit Liest (Play Framework)

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 _) 
} 

, wie Sie auf meine LogicalClause sehen können, könnte meine Kinder die eine json mit der sein das gleiche Format einer LogicalClause oder eines JSons mit dem Format eines ComparisonClause, aber ich kann es uns vorstellen, wie dies funktioniert.

Irgendwelche Vorschläge?

Ich erhalte die folgende Fehlermeldung:

No Json deserializer found for type com.userzoom.analytics.explorerapi.models.LogicalClause. Try to implement an implicit Reads or Format for this type. [error]
((JsPath \ "children").read[LogicalClause] or (JsPath \ "children").read[ComparisonClause])

+0

Geben Sie einen Verweis auf die implizite Instanz selbst beim Aufruf von '.Read [SameType] (myImplicit)' für ein Kind Eigenschaft – cchantep

+0

@cchantep ich so versucht: ((JsPath \ "children"). Lies [List [LogicalClause]] oder (JsPath \ "children"). LazyRead (Reads.list [IFilterClause] (ComparisonClause))) aber es funktioniert nicht, der Code beschwert sich über den Typ – Jean

Antwort

0

Zuerst sollten Sie Ihre implicit s im Begleitobjekt setzen, nicht in Ihrem case class. Sie können diesen Code versuchen, sollte es kompilieren:

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 
    } 
} 
Verwandte Themen