0

I am working on a project that calls a REST API to retrieve data.

Once I retrieve the data, I use Google's GSON API in order to convert the JSON data into objects I can use within my application.

Say I have these three types available from the REST API:

Person JSON

{
    "person_key_01":"person_value_01",
    "person_key_02":"person_value_02",
    "person_key_03":"person_value_03"
}

Matching Person.class

public class Person {
    private key_01;
    private key_02;
    private key_03;

    // getters and setters
}

Place JSON

{
        "place_key_01":"place_value_01",
        "place_key_02":"place_value_02",
        "place_key_03":"place_value_03"
}

Matching Place.class

public class Place {
    private key_01;
    private key_02;
    private key_03;

    // getters and setters
}

Thing JSON

{
        "thing_key_01":"thing_value_01",
        "thing_key_02":"thing_value_02",
        "thing_key_03":"thing_value_03"
}

Matching Thing.class

public class Thing{
    private key_01;
    private key_02;
    private key_03;

    // getters and setters
}

What I would like to do is have a single method that will take any of these three JSON strings and convert it to the proper object. I have tried [different variations] of the following with no luck:

public class UtilityClass {

    public static Object jsonToObjectOne(String receivedJSON){
        Gson gson = new GsonBuilder().create();
        Object object = gson.fromJson(receivedJSON, Object.class);
        if(object instanceof Person){
            return (Person)object;
        } else if(object instanceof Place) {
            return (Person)object;
        } else if(object instanceof Thing) {
            return (Person)object;
        }

        return null;
    }

    // I also tried this:

    public static Object jsonToObjectTwo(String receivedJSON){
        Gson gson = new GsonBuilder().create();
        Object object = gson.fromJson(receivedJSON, Object.class);
        if((Person)object instanceof Person){
            return (Person)object;
        } else if((Place)object instanceof Place) {
            return (Person)object;
        } else if((Thing)object instanceof Thing) {
            return (Person)object;
        }

        return null;
    }
}

As you can guess, this is not working for me.

Is there a way to take in a String of one the three types and return a specific Java object of that specific type?

Thanks!

Brian
  • 1,726
  • 2
  • 24
  • 62
  • What happens if you replace 6 x (Person) by appropriate casting operations? Why are you trying to cast anything before you checked it with `instanceof`? – Andrey Tyukin Jan 22 '18 at 20:10
  • Not sure what you mean by "replace 6 x (Person) by appropriate casting operations". I tried to cast before I checked because I got desperate. – Brian Jan 22 '18 at 20:11
  • Ehm... Your function returns an `Object`. Why are you casting anything at all? What's the point of checking the type and then casting, if you immediately forget the information, and return an object? – Andrey Tyukin Jan 22 '18 at 20:11
  • @AndreyTyukin I tried `instanceof` on the other side (i.e., not casting before return) but that didn't work either. – Brian Jan 22 '18 at 20:13
  • Is there any type information in the JSON string? Or any other information that distinguishes those three types? – QBrute Jan 22 '18 at 20:15
  • Yes ... one JSON string has 2 parameters and the other has 3 parameters. They both, however, have one parameter in common. – Brian Jan 22 '18 at 20:17
  • You're JSON is a map. In each class just define `private Map map` – jiveturkey Jan 22 '18 at 20:24
  • @jiveturkey My actual JSON is more complex than what I have in my post here; not just Strings. – Brian Jan 22 '18 at 20:25
  • Ok. But rethink how the JSON is actually mapped to a class because GSON would not map "key01:value01" to `private String value`. – jiveturkey Jan 22 '18 at 20:30
  • Ok, apparently, GSON doesn't work well when you want to serialize disjoint unions... Why bother with GSON at all then? Wouldn't it be simpler to adjust the serialization strategy, and write proper deserializers by yourself? Related: https://stackoverflow.com/questions/32451666/how-parse-json-array-with-multiple-objects-by-gson – Andrey Tyukin Jan 22 '18 at 20:33
  • @jiveturkey If I pass a JSON string that I know is "Person" to a method that is expecting a "Person" and convert it there, everything works flawlessly. – Brian Jan 22 '18 at 20:33
  • Is the REST API fixed or can you change it? – pirho Jan 22 '18 at 20:47
  • Have you tried to call `gson.fromJson(receivedJSON, Person.class);`? If yes what are you getting? – tsolakp Jan 22 '18 at 20:55
  • @pirho Unfortunately it is fixed. – Brian Jan 23 '18 at 03:47
  • @tsolakp If I make your change, then it works fine. However, that doesn't give me the general solution I am looking for. – Brian Jan 23 '18 at 03:48
  • `Gson.fromJson` is unable to determine the type of object to parse the JSON string to without you telling it. You either need to pass the specific Class you are expecting the JSON to represent or fallback to `Object.class` wihc most likely will give you an instance of `Map`. – tsolakp Jan 23 '18 at 17:04

0 Answers0