0

I have a json file

{"apple" : [
        {
            "first"    : 3,
            "second"    : 5,

        }
      ],
"orange" : [
        {
            "fst"    : 7,
            "snd"    : 8,

        }
      ],
}

a helper class for deserialization


public class Helper {

    private int num1;

    private int num2;

    public Helper(Helper other) {
        this.num1 = other.num1;
        this.num2 = other.num2;
    }

    public int getNum1() {
        return this.num1;
    }

    public int getNum2() {
        return this.num2;
    }
}

A java class for deserialization, which I need to change the JSON keys to be compatible with instance names of the Helper class.

public class MyDesClass {

    @SerializedName(value = "apple.first", alternate = "apple.num1")
    @SerializedName(value = "apple.seconds", alternate = "apple.num2")
    private final Helper[] apple;

    public MyDesClass(Helper[] apple) {
        this.apple = apple;
    }
    
}          

And, also inside main.java I have:

/* .... */
        Reader f = new FileReader( PATH_TO_THE_JSON_FILE);
        Gson gson = new Gson();
        GameBoard gameBoard = gson.fromJson(f, MyDesClass.class);
/* .... */

My question is how can I convert two values (e.g. first and second) at the same time (e.g. to num1 and num2 here) in MyDesClass? Currently, I get SerializedName is not a repeatable annotation type error.

vortex
  • 117
  • 7

1 Answers1

3

You need to use @SerializedName in Helper class (and update MyDesClass if needed):

public class Helper {

    @SerializedName(value = "first" alternate={"num1","fst"})
    private int num1;

    @SerializedName(value = "second" alternate={"num2","snd"})
    private int num2;

    public Helper(Helper other) {
        this.num1 = other.num1;
        this.num2 = other.num2;
    }

    public int getNum1() {
        return this.num1;
    }

    public int getNum2() {
        return this.num2;
    }
}

To comply with the updated JSON, MyDesClass needs to have another field orange:

public class MyDesClass {

    @SerializedName("apple")
    private final Helper[] apple;

    @SerializedName("orange")
    private final Helper[] orange;

    public MyDesClass(Helper[] apple, Helper[] orange) {
        this.apple = apple;
        this.orange = orange;
    }
// ...    
} 
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
  • thank you for your solution. However, the JSON key can be variable. sorry, if it was not clear. I extended the JSON file in my example for clarification. So, if deserialization in the `Helper` class is the only option, then is there a way to make the `value` key in `@SerializedName` variable? – vortex Jun 21 '20 at 22:09
  • I updated the response for your updated JSON - it requires to have another field `orange`. However, it's possible that you meant to apply @SerializedName to your `apple` field instead. Or use map of `>` instead of `MyDesClass` at all. – Nowhere Man Jun 21 '20 at 22:20
  • thank you very much for your answer, it solved most of my problems. Just, another question here. In my original problem, the first key in JSON is an object and the second key is an array of objects. In the JSON most entries have the order of `key1: Object, key2:[Object1, ...]`. However, in some cases the order is reverse `key1: [Object1, ...], key2:Object` and it does those entries is not deserialized. Any thoughts on fixing this? – vortex Jun 21 '20 at 22:55
  • 1
    You may need to check [an answer here](https://stackoverflow.com/questions/43868120/gson-deserialize-objects-that-can-be-a-single-object-or-an-array) – Nowhere Man Jun 21 '20 at 23:10