1

I have a json string:

val message = "{\"me\":\"a\",
    \"version\":\"1.0\",
    \"message_metadata\": \"{
                          \"event_type\":\"UpdateName\",
                          \"start_date\":\"1515\"}\"
    }"

I want to extract the value of the field event_type from this json string. I have used below code to extract the value:

val mapper = new ObjectMapper
val root = mapper.readTree(message)
val metadata =root.at("/message_metadata").asText()
val root1 = mapper.readTree(metadata)
val event_type =root1.at("/event_type").asText()
print("eventType:" + event_type.toString) //UpdateName

This works fine and I get the value as UpdateName. But I when I want to get the event type in a single line as below:

val mapper = new ObjectMapper
val root = mapper.readTree(message)
val event_type =root.at("/message_metadata/event_type").asText()
print("eventType:" + event_type.toString) //Empty string

Here event type returns a empty sting. This might be because of the message_metadata has Json object as a string value. Is there a way I can get the value of event_type in a single line?

3 Answers 3

1

The problem is that your JSON message contains an object who's message_metadata field itself contains JSON, so it must be decoded separately. I'd suggest that you don't put JSON into JSON but only encode the data structure once.

Example:

val message = "{\"me\":\"a\",
    \"version\":\"1.0\",
    \"message_metadata\": {
                          \"event_type\":\"UpdateName\",
                          \"start_date\":\"1515\"
    }
}"
Sign up to request clarification or add additional context in comments.

4 Comments

This input json comes from an external service and can not change the format. Is there any other way to parse it and the value?
No, using the simple version you tried is impossible because the message format requires two steps for decoding, since it is JSON nested inside JSON.
Any other alternative approach?
Well, you do have a workaround there already. I don't see any other approach considering the structure of the message. I'd try to get the sender to change their format though, in particular since they themselves have the same issue because they need two separate calls to encode the data.
0

You can parse your JSON using case classes and then get your event_type field from there.

case class Json(me: String, version: String, message_metadata: Message)

case class Message(event_type: String, start_date: String)

object Mapping {

  def main(args: Array[String]): Unit = {

    import com.fasterxml.jackson.databind.ObjectMapper
    import com.fasterxml.jackson.module.scala.DefaultScalaModule
    import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper

    val objectMapper = new ObjectMapper() with ScalaObjectMapper
    objectMapper.registerModule(DefaultScalaModule)
    val str = "{\n  \"me\": \"a\",\n  \"version\": \"1.0\",\n  \"message_metadata\": {\n    \"event_type\": \"UpdateName\",\n    \"start_date\": \"1515\"\n  }\n}"
    val json = objectMapper.readValue(str, classOf[Json])
    //to print event_type
    println(json.message_metadata.event_type)
    //output: UpdateName

  }

}

Comments

0
  • You can even convert a JSON to Scala Case Class and then get the particular field from the case class.

  • Please find a working and detailed answer which I have provided using generics here.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.