DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Newsletter
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Jackson vs Gson: Edge Cases in JSON Parsing for Java Apps
  • JSON Handling With GSON in Java With OOP Essence
  • Let's Unblock: Read Json Using GSON in Scala

Trending

  • Agentic Test Creation: From Plain-Language Requirements to End-to-End Test Cases
  • Delegated Transport, Forked Authorization: Where Chat and AI-Agent Integrations Actually Break
  • A Field Guide to AI Agent Frameworks
  • Build a Voice Assistant With Gemini Live API

Draft This article hasn't been published, so readers can't see it.

In moderation This article is waiting for review, so readers can't see it yet.

Deleted This article has been deleted, so readers can't see it.

Gson: Deserialization of Generic Types

JSON, Gson, and Java: take a look at this handy tutorial on deserialization methods in Gson.

By 
Anton Berezin
·
May. 10, 16 · Tutorial
Post on X (opens in a new tab) Share on LinkedIn (opens in a new tab)
66.6K Views

Join the DZone community Save articles, join the discussion, and download Refcards and Trend Reports with a free account.

Join for free Already a member? Log in

Let's imagine that we are developing a wrapper library for an API, which returns JSON documents as a response. And there are many endpoints that have similar structures, except some fragment and may have a different structure. 

Let's go ahead with a simple example. This is what some personal data could look like:

{
  "status": "success",
  "message": "Data was retrieved",
  "data": {
    "name" : "John",
    "surname": "Smith"
  }
}

And here is an example for some department data:

{
  "status": "success",
  "message": "Data was retrieved",
  "data": {
    "name" : "Agriculture",
    "peopleCount" : 42
  }
}

As we can see, only the "data" fragment has a different structure, while the general structure of both documents is the same.

It is obvious that it is better to reuse this general structure and for each document to provide only the remaining part—the "data" subdocument structure. One of the possible solutions could look like:

public class FooResponse<T> {
    private final String status;
    private final String message;
    private final T data;
    // constructor, getters
}
...

public class Person {
    private final String name;
    private final String surname;
    // constructor, getters
}
...

public class Department {
    private final String name;
    private final int peopleCount;
    // constructor, getters
}

If we dealt with a class without generics, our code deserializing the string response would look like:

FooResponse<Person> person = gson.fromJson(rawPerson, FooResponse.class);

But in our case it will fail to deserialize the data field, because Gson simply does not know which parameter type to use.

How can we tell Gson about it? There is an alternative signature of the deserialization method—fromJson(String json, Type typeOfT) where Type is java.lang.reflect. Type which may contain information about parametrization too.  

One of the ways to extract the type from parametrized class is to use Gson's TypeToken class, which uses reflection magic in order to do this. Our code now will look like this:

FooResponse<Person> person = gson.fromJson(rawPerson, new TypeToken<FooResponse<Person>>(){}.getType())

As we can see, we create an anonymous subclass of TypeToken in this way, and we make its parametrization accessible (for more details, please refer to TypeToken implementation code, it might be an interesting way to learn something new about Java reflection).

This solution works fine, but if you develop a library that will be used by other developers, you might want to hide all Gson usage details inside your implementation code, so using TypeToken as a parameter might be not an option.

Fortunately, it is not a hard task to compose a Type instance with Java's standard library. All we have to do is make our implementation of ParametrizedType interface and make sure it returns the correct type argument. And we can create a function which would return such Type instance.

Type getType(Class<?> rawClass, Class<?> parameter) {
  return new ParametrizedType() {
    @Override
    public Type[] getActualTypeArguments() {
       return new Type[] {parameter};
    }

    @Override
    public Type getRawType() {
      return rawClass;
    }

    @Override
    public Type getOwnerType() {
      return null;
    }   
  }
}

That's it. Now we can use Gson this way:

FooResponse<Person> person = gson.fromJson(rawResponse, getType(FooResponse.class, Person.class))

And our library can have a method that is easy to use by other developer teams:

public <T> FooResponse<T> getResponse(/* parameters for retrieval ,*/ final Class<T> dataClass) {
    final String rawResponse = getRawResponse(); // ... e.g. via some http client library
    return gson.fromJson(rawResponse, getType(FooResponse.class, dataClass));
}

Here is a GitHub repository with an example illustrated described approach:

https://github.com/AntonBerezin/gson-deserialization-example

Gson

Opinions expressed by DZone contributors are their own.

Related

  • Jackson vs Gson: Edge Cases in JSON Parsing for Java Apps
  • JSON Handling With GSON in Java With OOP Essence
  • Let's Unblock: Read Json Using GSON in Scala

Partner Resources

×

Comments

Loading comments

The comments didn't load

Please try again in a moment.

Likes

Loading

The next likes didn't load. Please try again.

The likes didn't load

Please try again in a moment.

See who liked this

Log in or join DZone for free to see who liked this article.

Log in Join for free
  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook