-1

I need help deserialising JSON in the following format in Java:

data.json

{
   "tokens":[
      {
         "position":1,
         "text":"hello",
         "suggestions":[
            {
               "suggestion":"hi",
               "points":0.534
            },
            {
               "suggestion":"howdy",
               "points":0.734
            }
         ]
      },
   ]
}

I've created two classes, one called Token and another called Suggestion, with attributes matching the JSON format.

Token.java

public class Token {
    private int position;
    private String text;
    private List<Suggestion> suggestions;

    public Token(int position, String text, List<Suggestion> suggestions) {
        this.position = position;
        this.text = text;
        this.suggestions = suggestions;
    }
}

Suggestion.java

public class Suggestion {
    private String suggestion;
    private double points;

    public Suggestion(String suggestion, double points) {
        this.suggestion = suggestion;
        this.points = points;
    }

}

How do I "unpack" the JSON into a list of Tokens, each of which has the two required strings and a list of Suggestion objects as its attributes? (Ideally, it would be using the Gson library)

I've tried this, but it doesn't work:

Gson gson = new Gson();
Type listType = new TypeToken<List<Token>>(){}.getType();

List<Token> tokenList = gson.fromJson(jsonString, listType);

System.out.println(tokenList.get(0));

Thanks

alexcons
  • 531
  • 3
  • 8
  • 18

3 Answers3

2

You have to create another class say Output as

import java.util.List;

public class Output {
    public List<Token> getTokens() {
        return tokens;
    }

    public void setTokens(List<Token> tokens) {
        this.tokens = tokens;
    }

    private List<Token> tokens;
}

and then use

Output output = new Gson().fromJson(json, Output.class);

then you can use output to get list of tokens and go further for suggestion etc

Ratish Bansal
  • 1,982
  • 1
  • 10
  • 19
  • This works and it gets rid of the error I had, but when I print output.getTokens(), I get null – alexcons Feb 04 '19 at 18:15
  • I tried this code myself and my output is containing token. Please try this to get token output.getTokens().get(0).Also can you please share the code after output. – Ratish Bansal Feb 04 '19 at 18:17
  • JSONOutput output = new Gson().fromJson(jsonString, JSONOutput.class); System.out.println(output.getTokens().get(0)); that's the code I have and I get java.lang.NullPointerException – alexcons Feb 04 '19 at 18:20
  • `output.getTokens().get(0)` will give you token object. Since you have not overriden toString it will not work.You can print token members like output.getTokens().get(0).getText() – Ratish Bansal Feb 04 '19 at 18:21
  • Still doesn't work, I've even tried output.getTokens.get(0).getToken() which is the getter for the String token attribute and still null. – alexcons Feb 04 '19 at 18:25
  • There is no String token in you token object.There is text,position etc.So use output.getTokens.get(0).getText() – Ratish Bansal Feb 04 '19 at 18:26
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/187880/discussion-between-ratish-bansal-and-alexcons). – Ratish Bansal Feb 04 '19 at 18:28
  • Sorry, I meant .getText() because my attributes are named slightly different to what I said in the example. – alexcons Feb 04 '19 at 18:28
1

You can use Jackson's TypeReference to achieve this, e.g.:

ObjectMapper objectMapper = new ObjectMapper();
TypeReference<List<Token>> typeReference = new TypeReference<List<Token>>() {};
List<Token> tokens = objectMapper.readValue("<json_stribg>", typeReference);

You can read more about TypeReference here.

Darshan Mehta
  • 30,102
  • 11
  • 68
  • 102
  • `Gson` and `Jackson` are two different libraries. – Darshan Mehta Feb 04 '19 at 17:53
  • My bad, I've installed jackson and added this code but I'm getting an error: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token – alexcons Feb 04 '19 at 18:03
-1

If you use Jackson, you should use @JsonProperty above fields. Try write your files as below:

public class Token {

@JsonProperty
private int position;

@JsonProperty
private String text;

@JsonProperty
private List<Suggestion> suggestions;

//getters/setters

}

public class Suggestion {

@JsonProperty
private String suggestion;

@JsonProperty
private double points;

// getters/setters

}