Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert JSON String to generic object in JAVA (with GSON)

Tags:

java

gson

I have an Api that returns JSON. The response is in some format that can fit into an object called ApiResult and contains a Context <T> and an int Code.

ApiResult is declared in a generic way, e.g. ApiResult<SomeObject>

I would like to know how to get GSON to convert the incoming JSON String to ApiResult<T>

So far I have:

Type apiResultType = new TypeToken<ApiResult<T>>() { }.getType();
ApiResult<T> result = gson.fromJson(json, apiResultType);

But this still returns converts the Context to a LinkedHashMap instead (which I assume its what GSON falls back to)

like image 302
Yannis Avatar asked Jul 17 '13 23:07

Yannis


People also ask

Can we convert JSON to Java object?

We can convert a JSON to Java Object using the readValue() method of ObjectMapper class, this method deserializes a JSON content from given JSON content String.

What does GSON toJson do?

Gson is the main actor class of Google Gson library. It provides functionalities to convert Java objects to matching JSON constructs and vice versa. Gson is first constructed using GsonBuilder and then toJson(Object) or fromJson(String, Class) methods are used to read/write JSON constructs.

What is difference between fromJson and toJson?

There are two parameters in the fromJson() method, the first parameter is JSON String which we want to parse and the second parameter is Java class to parse JSON string. We can pass one parameter into the toJson() method is the Java object which we want to convert into a JSON string.


1 Answers

You have to know what T is going to be. The incoming JSON is fundamentally just text. GSON has no idea what object you want it to become. If there's something in that JSON that you can clue off of to create your T instance, you can do something like this:

public static class MyJsonAdapter<X> implements JsonDeserializer<ApiResult<X>>
{
    public ApiResult<X> deserialize( JsonElement jsonElement, Type type, JsonDeserializationContext context )
      throws JsonParseException
    {
      String className = jsonElement.getAsJsonObject().get( "_class" ).getAsString();
      try
      {
        X myThing = context.deserialize( jsonElement, Class.forName( className ) );
        return new ApiResult<>(myThing);
      }
      catch ( ClassNotFoundException e )
      {
        throw new RuntimeException( e );
      }
    }
}

I'm using a field "_class" to decide what my X needs to be and instantiating it via reflection (similar to PomPom's example). You probably don't have such an obvious field, but there has to be some way for you to look at the JsonElement and decide based on what's itn it what type of X it should be.

This code is a hacked version of something similar I did with GSON a while back, see line 184+ at: https://github.com/chriskessel/MyHex/blob/master/src/kessel/hex/domain/GameItem.java

like image 111
Chris Kessel Avatar answered Sep 22 '22 12:09

Chris Kessel