0

While processing the DialogFlow Response object, I get the below given string as textPayload. If this is a Json string, I can easily convert it to a JSONObject and then extract the values. However, could not convert this to a Json Object. How do I get the values for the keys in this string? What is a good way to parse this string in Java?

String to be processed

Dialogflow Response : id: "XXXXXXXXXXXX"
lang: "en"
session_id: "XXXXX"
timestamp: "2020-04-26T16:38:26.162Z"
result {
  source: "agent"
  resolved_query: "Yes"
  score: 1.0
  parameters {
  }
  contexts {
    name: "enaccaccountblocked-followup"
    lifespan: 1
    parameters {
    }
  }
  metadata {
    intent_id: "XXXXXXXXXXXX"
    intent_name: "EN : ACC : Freezing Process - Yes"
    end_conversation: true
    webhook_used: "false"
    webhook_for_slot_filling_used: "false"
    is_fallback_intent: "false"
  }
  fulfillment {
    speech: "Since you have been permanently blocked, please request to  unblock your account"
    messages {
      lang: "en"
      type {
        number_value: 0.0
      }
      speech {
        string_value: "Since you have been permanently blocked, please request to  unblock your account."
      }
    }
  }
}
status {
  code: 200
  error_type: "success"
}
Kabilesh
  • 1,000
  • 6
  • 22
  • 47

4 Answers4

1

If I understand you correctly the issue here is that the keys do not have quotations marks, hence, a JSON parser will reject this.

Since the keys all start on a new line with some white-space and all end with a colon : you can fix this easily with a regular expression.

See How to Fix JSON Key Values without double-quotes?

You can then parse it to a Map via

Map<String, Object> map 
  = objectMapper.readValue(json, new TypeReference<Map<String,Object>>(){});

(but I assume you are aware of this).

Christian Fries
  • 16,175
  • 10
  • 56
  • 67
1

Convert it to valid json, then map using one of the many libraries out there.

You'll only need to:

  • replace "Dialogflow Response :" with {
  • add } to the end
  • add commas between attributes, ie
    • at the end of every line with a ":"
    • after "}", except when the next non-whitespace is also "}"

Jackson (at least) can be configured to allow quotes around attribute names as optional.

Deserializing to a Map<String, Object> works for all valid json (except an array, which this isn't).

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Yeah..Need to write regex for all these. – Kabilesh Apr 27 '20 at 05:17
  • 1
    @Kabilesh the first needs no regex, or the second - just `+ "}"`. The 3rd `replaceAll("(?m)^.*:.*", "$0,")` the last `replaceAll("}\\s*([^\\s}])", "},$1")` – Bohemian Apr 27 '20 at 05:52
  • That will save a lot of time. And to add double quotes as @Chritian mentioned what will be the regex? – Kabilesh Apr 27 '20 at 05:59
  • What double quotes? where do you think you need them? – Bohemian Apr 27 '20 at 06:05
  • 1
    In a Json it should be **"lang": "en"** not **lang: "en"** right?? The key and value both should have double quotes around them. – Kabilesh Apr 27 '20 at 06:08
  • @Kabilesh as per my answer, "no", but it depends on the library you are using. I would recommend Jackson, which allows unquoted attribute name by configuring the mapper like this: `objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);`. I don't know about other libraries - they may or may not support it. You can do as you please, but my motto is "less code is good"; if you can get it working with less code, that's a good thing. – Bohemian Apr 27 '20 at 06:14
  • Okay. I was using `org.json.JSONObject` – Kabilesh Apr 27 '20 at 06:15
0

Create a class for TextPayload object like this.

public class TextPayload {
   private int session_id;
   private String lang;
   private String timestamp;
   private String[] metadata ;
   //Other attributes
   //getters setters
}

Then using an ObjectMapper extract the values from textpayload like this:

    ObjectMapper mapper = new ObjectMapper();
    TextPayload textPayload = mapper.readValue(output, User.class);

To utilize ObjectMapper and hands on with it follow this

Sarangan
  • 868
  • 1
  • 8
  • 24
  • 1
    won't work. it's too far from being valid json to be mapped – Bohemian Apr 27 '20 at 05:05
  • Yes. I Understand that. But the problem is, this is not a **Json** nor a **Json String**. This is just a **String** that is aligned properly. How can I process this with **ObjectMapper**? – Kabilesh Apr 27 '20 at 05:05
0

you can use the nodejs package parse-dialogflow-log to parse the textResponse string.

  1. replace "Dialogflow Response :" with "{"
  2. add "}" to the end
  3. run the package on the result and you'll get a nice json.