scala - json4s parse json partially -
i have json model, contents of attribute depend on other attribute. this:
"paymentmethod": "credit_card", "metadata": { "cardtype": "visa", "panprefix": "", "pansuffix": "", "cardholder": "", "expirydate": "" } so when paymentmethod equals credit_card, metadata object contain attributes described. in case of other payment method, there'll different metadata.
i want handle situation in future-proof way. i'm trying not parse metadata field right away, keep somehow "unparsed" until i've parsed paymentmethod field. i'd take metadata , applied appropriate parsing approach.
however don't know type use scala class field such "late parsed" attributes. i've tried string, jsoninput, jobject, , not suitable (either don't compile or can't parsed). ideas type can use? or, in other words:
case class creditcardmetadata( cardtype: string, panprefix: string, pansuffix: string, cardholder: string, expirydate: string) case class paypalmetadata(...) // etc. case class paymentgatewayresponse( paymentmethod: string, metadata: ???)
you create customserializer parse metadata directly. :
case class paymentresponse(payment: payment, otherfield: string) sealed trait payment case class creditcardpayment(cardtype: string, expirydate: string) extends payment case class paypalpayment(email: string) extends payment object paymentresponseserializer extends customserializer[paymentresponse]( format => ( { case jobject(list( jfield("paymentmethod", jstring(method)), jfield("metadata", metadata), jfield("otherfield", jstring(otherfield)) )) => implicit val formats = defaultformats val payment = method match { case "credit_card" => metadata.extract[creditcardpayment] case "paypal" => metadata.extract[paypalpayment] } paymentresponse(payment, otherfield) }, { case _ => throw new unsupportedoperationexception } // no serialization json )) which can used as:
implicit val formats = defaultformats + paymentresponseserializer val json = parse(""" { "paymentmethod": "credit_card", "metadata": { "cardtype": "visa", "expirydate": "2015" }, "otherfield": "hello" } """) val json2 = parse(""" { "paymentmethod": "paypal", "metadata": { "email": "foo@bar.com" }, "otherfield": "world" } """) val cc = json.extract[paymentresponse] // paymentresponse(creditcardpayment(visa,2015),hello) val pp = json2.extract[paymentresponse] // paymentresponse(paypalpayment(foo@bar.com),world)
Comments
Post a Comment