score:4
You could create a CustomSerializer
to parse the metadata directly. Something like :
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 to json
))
Which can be 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)
score:0
You can use a Map[String, String]
.
It will contain anything you may need.
score:0
The answer by Peter Neyens has inspired me to implement my own solution. It's not as generic as his, but in my case I needed something really simple and ad-hoc. Here's what I've done:
It's possible to define a case class with the field of unknown type is represented by a JObject
type. Something like this:
case class PaymentGatewayResponse(
default: Boolean,
paymentMethod: String,
visibleForCustomer: Boolean,
active: Boolean,
metaData: JObject)
When such json is parsed into such case class, this field is not parsed immediately, but contains all the necessary information. Then it's possible parse it in a separate step:
case class CreditCardMetadata(
cardType: String,
cardObfuscatedNumber: String,
cardHolder: String,
expiryDate: String)
val response: PaymentGatewayResponse = doRequest(...)
response.map { r =>
r.paymentMethod match {
case "CREDIT_CARD" => r.metaData.extract[CreditCardMetadata]
case unsupportedType: String => throw new UnsupportedPaymentMethodException(unsupportedType)
}
}
Source: stackoverflow.com
Related Query
- json4s parse json partially
- How to parse and extract information from json array using json4s
- How to parse json using json4s so that let primitive values become custom case class?
- Parse JSON in Scala using JSON4S
- How to parse JSON in Scala using standard Scala classes?
- How can I construct and parse a JSON string in Scala / Lift
- Scala: Parse JSON directly into a case class
- Scala/Play: parse JSON into Map instead of JsObject
- What is the most straightforward way to parse JSON in Scala?
- Map[String,Any] to compact json string using json4s
- scala - parse json of more than 22 elements into case class
- Can I use the Scala lift-json library to parse a JSON into a Map?
- Can't parse a json to a `ProvinceJson` class, with lift-json
- Spark non-serializable exception when parsing JSON with json4s
- How to serialize JSON with json4s with UTF-8 characters?
- Spray-Json: How to parse a Json Array?
- How to use Spark SQL to parse the JSON array of objects
- Circe parse json from snake case keys
- Scala Dynamic Parse Json using case class No Manifest available for T
- How to parse JSON with variable keys in Scala Play?
- Parse JSON array using Scala Argonaut
- How do you parse a JSON request with Dispatch?
- Scala dispatch GET request, fail to parse response to json
- Validation error while trying to parse a json array to List[Object] in Scala
- How to parse JSON data in Scala?
- Parse Json List with 1 element (Scala/liftweb)
- How to parse json list or array in scala for play framework 2.2
- scala play reads parse nested json
- How to read a json response from a akka-http response entity using json4s
- How do I catch json parse error when using acceptWithActor?
More Query from same tag
- Could we use sleuth without spring cloud?
- scala - count every line in which a word occurs
- Shrink macro for case class
- How can I create a component-based message handling system with traits?
- Slick join two tables and get result of both
- scala: shortest way to convert List[ Tuple3[A,B,C] ] to Foo(A, B, List[C])
- Math.abs function in Select statement in Scala
- How to save and use Spark History Server logs in AWS S3
- How to use Spark cosmos.oltp datasource/format. Is that configuration a datasource or a format?
- How to enforce a Collection (Seq, List etc.) to accept only positive integers - Scala
- object scalatest is not a member of package org
- Google PubSub Java (Scala) Client Gets Excessive Amount of Resent Messages
- Using Phantom 2 with an existing Cassandra session
- Neo4j: Which internal module responsible for verifying WHERE conditions from cypher?
- Alphanumeric identifiers and '$' character
- How to wait for Akka actor to start during tests?
- How to write datetime with microseconds to Cassandra with Spark?
- Scala ClassTag & classOf and type parameter. Strange case of generics
- Tell IntelliJ IDEA I want library sources for a Scala project after the fact
- Log Parsing using Scala
- Scala PLAY same routes
- How does the extractor work when the `unapply` function returns Boolean instead of Option?
- Compilation issue when accessing parameter value in Scala macro
- Spark: Repartition strategy after reading text file
- Trigger IF Statement only when two Spark dataframe meet the conditions
- Scala functional literals
- Scala Generic inference
- activator fails to load project after IDE restart (scala, play, intellij idea)
- Alternative to the use of the 'withColumn' function in Spark Scala
- How to maintain an immutable list when you impact object linked to each other into this list