AquaProgramming
AquaProgramming

Reputation: 115

Parsing JSON object that contains another JSON String to a Object

Currently I am working on a school project where I had to build a Game in which a user could customize a deck of Cards and save this to a Database via a REST API. This part I got successfully working, however I decided to save the deck of Cards as a JSON String into my database table. Now I am having issues whilst using Gson to parse the object back to the correct Model as it is expecting a properly typed list as opposed to a Json String.

Does anyone have a good solution to easily parse this object or to extract the deck of cards from the Json String before parsing the rest of the object?

I will provide some example code to show the current structure of my object and Json:

Model to Convert to

public class CharacterModel{
private String characterName;
private int maxHp
private List<BattleCard> cardDeck

public CharacterModel(){}

//Getters and Setters for all paramters below
}

Json Format

{
  "characterName": "TestCharacter;",
  "maxHp": "4",
  "cardDeck": "{Json String with the List of Cards here}"
}

What would be the best way to resolve this? As due to the way the JSON String gets nested into the parent JSON String it is not recognized as a object by Gson when trying to convert. Any help with this problem would be very much appreciated.

Upvotes: 0

Views: 1352

Answers (1)

maio290
maio290

Reputation: 6732

Generally, nowadays it's more likely to use JSON-B and/or JSON-P since it's part of the java specification. However, GSON supports binding too. When you're working with POJOs / Entities, you usually don't have to generate or parse any JSON by hand in 2020. Binding is the word you're looking for ;)

I've implemented an example for this with JSON-B and GSON, they don't differ much anyway in this case.

    Card jsonbCard = new Card();
    jsonbCard.name = "JSON-B";
    jsonbCard.value = 9001;
    Card gsonCard = new Card();
    gsonCard.name = "GSON";
    gsonCard.value = -9001;
    
    List<Card> cardList = new ArrayList<>();
    cardList.add(jsonbCard);
    cardList.add(gsonCard);
    
    Jsonb jsonb = JsonbBuilder.create();
    String listSerialized = jsonb.toJson(cardList);
    System.out.println(listSerialized);
    
    List<Card> cardListFromJson = jsonb.fromJson(listSerialized, new ArrayList<Card>(){}.getClass().getGenericSuperclass());

    Gson gson = new Gson();  
    List<Card> cardListFromJson_GSON = gson.fromJson(listSerialized,  new TypeToken<List<Card>>(){}.getType());

This generated the following JSON string: [{"name":"JSON-B","value":9001},{"name":"GSON","value":-9001}] and deserializes the string back into a List of Card.

So in your case, you can

  1. create another class containing cardDeck as a String, bind the JSON to that, create the actual Character class and set the List by binding that cardDeck String to a List.
  2. use parsing and extract the cardDeck String from the JSON, remove it from the JSON, parse it to the object, parse the extracted cardDeck String to a List and set it on the previously arsed object.
  3. serialize properly, and you don't have this mess ;)

The main mistake is that the cardDeck in your JSON shouldn't be a String to begin with.

Upvotes: 1

Related Questions