0

I have a JSON Data which is a collection of objects like the one given below. I have to deserialize the below given data into a list of objects

[{\"Name\": \"Initialize\", \"Library\": \"BKS\", \"Type\": \"setup\", \"Status\": \"PASS\", \"StartTime\": \"20190429 15:06:36.020\", \"EndTime\": \"20190429 15:06:39.476\", \"Environment\": \"CLC-ER\", \"ScenarioName\": \"BKS-DISVAS\", \"ElapsedTime\": 456.0},{\"Name\": \"Initialize\", \"Library\": \"BKS\", \"Type\": \"setup\", \"Status\": \"PASS\", \"StartTime\": \"20190429 15:06:36.020\", \"EndTime\": \"20190429 15:06:39.476\", \"Environment\": \"CLC-ER\", \"ScenarioName\": \"BKS-DISVAS\", \"ElapsedTime\": 456.0}]

I have tried the following code snippet, but I am getting the following error.

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at com.google.gson.Gson.fromJson(Gson.java:822) ~[gson-2.3.1.jar:na] at com.google.gson.Gson.fromJson(Gson.java:875) ~[gson-2.3.1.jar:na]

My Model class is given below

public class KeywordDetails {

    public KeywordDetails() {
    }

    @JsonProperty("Name")
    public String Name;
    @JsonProperty("Type")
    public String Type;
    @JsonProperty("Library")
    public String Library;
    @JsonProperty("StartTime")
    public String StartTime;
    @JsonProperty("EndTime")
    public String EndTime;
    @JsonProperty("Status")
    public String Status;
    @JsonProperty("ScenarioName")
    public String ScenarioName;
    @JsonProperty("Environment")
    public String Environment;
    @JsonProperty("ElapsedTime")
    public double ElapsedTime;

}

The deserialization code is given below,

    Gson serializer = new Gson();
    Type listType = new TypeToken<ArrayList<KeywordDetails>>() {
    }.getType();
    JsonParser parser = new JsonParser();
    JsonElement kwJson = parser.parse(ser.getKeywordStats());
    System.out.println(kwJson);

    List<KeywordDetails> keywordDetails = serializer.fromJson(kwJson, listType);

The ser.getKeywordStats() method is giving the above JSON.

I should be able to deserialize the JSON into the list or array of objects.

As I am new to Java, I am not able to find the root cause or fix for this issue, can anyone help me with this issue?

Juliano Macedo
  • 668
  • 8
  • 21
Saran
  • 99
  • 2
  • 14
  • I have been searching in google and found one solution to use the default constructor without any arguments, i added that one as well, but could not deserialize even then also. – Saran Sep 09 '19 at 13:32
  • I also tried by passing the JSON string to the fromJson method, but also it is not working. I am using this in a Spring boot application and also tried the `Jackson` serializer, but also could not reproduce. – Saran Sep 09 '19 at 13:34
  • 1
    did you try use List instead of ArrayList? – Egor Sep 09 '19 at 13:36
  • Does the actual String you're passing contain all those escape backslashes? Because the string you pasted is not valid JSON. It must be without the \ – kenny_k Sep 09 '19 at 13:37
  • @kenny_k, I also tried with editor in the debug mode, it looks like below which i think is correct, can you please check "[{\"Name\": \"Initialize\", \"Library\": \"Base.Keywords\", ... – Saran Sep 09 '19 at 13:49
  • When i try with the code snippet as below, `JsonElement kwJson = parser.parse(StringEscapeUtils.unescapeJava(scenarioExecutionReport.getKeywordStats()));` I am getting the below error `Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 6 path`. I think this is due to the presence of the " inside the JSON for the property names, could that be any issue? Please suggest. – Saran Sep 09 '19 at 13:53
  • 1
    I was actually sending the data from python source to java where it happened to double json encode the value. I had to fix the python code because it caused the json to be treated internally as a string even after parsing the string. After fixing the python code, all is well now. Thanks to one and all for helping resolve the issue. In a nutshell, the JSON string was the culprit, after fixing the string right, things are working fine now. – Saran Sep 09 '19 at 16:21

4 Answers4

3
  1. Why JsonProperty instead of SerializableName? Are you mixing Jackson and Gson?
  2. What is the output of ser.getKeywordStats()?

Because I have tested your code by hardcoding that json-string instead of ser.getKeywordStats(), and it worked without any issue.

enter image description here

Harsh Jatinder
  • 833
  • 9
  • 15
  • 1
    I was actually sending the data from python source to java where it happened to double json encode the value. I had to fix the python code because it caused the json to be treated internally as a string even after parsing the string. After fixing the python code, all is well now. – Saran Sep 09 '19 at 16:20
2

Here is a working snippet,

    private static final String ESCAPED_STRING =
          "[{\"Name\": \"Initialize\", \"Library\": \"BKS\", \"Type\": \"setup\", \"Status\": \"PASS\", \"StartTime\": \"20190429 15:06:36.020\", \"EndTime\": \"20190429 15:06:39.476\", \"Environment\": \"CLC-ER\", \"ScenarioName\": \"BKS-DISVAS\", \"ElapsedTime\": 456.0},{\"Name\": \"Initialize\", \"Library\": \"BKS\", \"Type\": \"setup\", \"Status\": \"PASS\", \"StartTime\": \"20190429 15:06:36.020\", \"EndTime\": \"20190429 15:06:39.476\", \"Environment\": \"CLC-ER\", \"ScenarioName\": \"BKS-DISVAS\", \"ElapsedTime\": 456.0}]";

      public static void main(String[] args) throws JsonProcessingException {
         Gson gson = new Gson();
         Type t= new TypeToken<List<KeywordDetails>>(){}.getType();
         JsonParser parser = new JsonParser();
         JsonElement jsonElements = parser.parse(ESCAPED_STRING);
         System.out.println(jsonElements);
         List<KeywordDetails> kd = gson.fromJson(jsonElements, t);
         System.out.println(kd);
      }

This has to do something with your String, the string must be void of the \ slashes to make it a valid JSON. So, I have used JsonParser to construct a valid JSON from the escaped String.

Mohamed Anees A
  • 4,119
  • 1
  • 22
  • 35
1

Use Gson or JsonParser not both. Try with this code:

Gson serializer = new Gson();
Type listType = new TypeToken<ArrayList<KeywordDetails>>() {}.getType();
List<KeywordDetails> keywordDetails = serializer.fromJson(ser.getKeywordStats(), listType);
1

I don't know @JsonProperty annotation. You can use (or not) @SerializedName instead.

Then you can simply deserialize your json like this.

String json = ...
Gson gson = new Gson();
List< KeywordDetails > keywords = gson.fromJson(json, new TypeToken<List< KeywordDetails >>(){}.getType());

Agnaramon
  • 851
  • 10
  • 15