Am getting a JSON in
{
"segment": {
"134": "34",
"154": "342"
}
}
all I am trying to do is map the keys as value i.e convert it into format like
{
"segment ": [{
"segmentationStrategyId ": 134,
"segmentID ": 34
}, {
"segmentationStrategyId ": 154,
"segmentID ": 342
}]
}
Tried using json4s parser but as key are diff I cannot map it to case class.
You can use spary.json to convert the json.
If you use SBT you can include spray-json in your project with
libraryDependencies += "io.spray" %% "spray-json" % "1.3.3"
Define the case class for your input and output.
case class InputJson(segment: Map[String, String])
case class OutputSegment(segmentationStrategyId: Int, segmentId: Int)
case class OutputJson(segment: List[OutputSegment])
Define the protocol through convert case class to json and json to case class
import spray.json._
object MyProtocol extends DefaultJsonProtocol {
implicit val inputJsonFormat = jsonFormat1(InputJson.apply)
implicit val outputSegmentFormat = jsonFormat2(OutputSegment.apply)
implicit val outputJsonFormat = jsonFormat1(OutputJson.apply)
}
Input json:
val jsonString: String =
"""{
| "segment": {
| "134": "34",
| "154": "342"
| }
|}""".stripMargin
parse the json String into JsValue
val jsonVal: JsValue = jsonString.parseJson
convert the JsValue into Case Class
val jsonInput: InputJson = jsonVal.convertTo[InputJson]
Now, you can map the Map[String,String] segment into OutputSegment format.
val outputSegments: List[OutputSegment] = jsonInput.segment.flatMap {
case (key, value) => Try(OutputSegment(key.toInt, value.toInt)).toOption
}.toList
create the OutputJson and get the equivalent Json String.
val outputJson: String = OutputJson(outputSegments).toJson.prettyPrint
Output Json String:
{
"segment": [{
"segmentationStrategyId": 134,
"segmentId": 34
}, {
"segmentationStrategyId": 154,
"segmentId": 342
}]
}
Final full code sample:
import spray.json._
import scala.util.Try
object Test
extends App {
// case class
case class InputJson(segment: Map[String, String])
case class OutputSegment(segmentationStrategyId: Int, segmentId: Int)
case class OutputJson(segment: List[OutputSegment])
// protocol for json conversion
object MyProtocol extends DefaultJsonProtocol {
implicit val inputJsonFormat = jsonFormat1(InputJson.apply)
implicit val outputSegmentFormat = jsonFormat2(OutputSegment.apply)
implicit val outputJsonFormat = jsonFormat1(OutputJson.apply)
}
// input json
val jsonString: String =
"""{
| "segment": {
| "134": "34",
| "154": "342"
| }
|}""".stripMargin
import MyProtocol._
val jsonVal: JsValue = jsonString.parseJson
val jsonInput: InputJson = jsonVal.convertTo[InputJson]
val outputSegments: List[OutputSegment] = jsonInput.segment.flatMap {
case (key, value) => Try(OutputSegment(key.toInt, value.toInt)).toOption
}.toList
val outputJson: String = OutputJson(outputSegments).toJson.prettyPrint
println(outputJson)
}
Reference link: https://github.com/spray/spray-json
I am not familiar with json4s but managed to write this out quickly, might help:
import org.json4s._
import org.json4s.native.JsonMethods._
case class Segment(segmentationStrategyId: Int, segmentId: Int)
object Test {
implicit val formats: DefaultFormats.type = DefaultFormats
val json: String =
"""
| {
| "segment": {
| "134": "34",
| "154": "342"
| }
|}
""".stripMargin
def main(args: Array[String]): Unit = {
val originalSegments = for {
JObject(o) <- parse(json)
JField("segment", JObject(segment)) <- o
} yield segment
val originalSegment = originalSegments.head
val newSegments = originalSegment.map(
s => Segment(s._1.toInt, s._2.extract[String].toInt)
)
println(newSegments)
}
}
Prints out
List(Segment(134,34), Segment(154,342))
So you now have a list of case classes that you should be able to ransform into your JSON
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With