How to convert JSON fields into a JAVA map using GSON

Viewed 3661

I have a JSON data which looks like this:

{
 "status": "status",
 "date": "01/10/2019",
 "time": "10:30 AM",
 "labels": {
     "field1": "value1",
     "field2": "value2",
     ...
     "field100": "value100"
 }
 "description": "some description"
}

In my Java code, I have two classes:

  1. Alerts class which has the following fields - status, date, time, description and Labels class.

  2. The inner Labels class which is supposed to hold all the fields from field1 through field100 (and more)

I'm parsing this JSON into GSON like this:

Alerts myAlert = gson.fromJson(alertJSON, Alert.class);

The above code parses the JSON into the Alert object and the Labels object.

Question: Instead of mapping the fields (field1, field2, etc) inside Labels object as individual String fields, how can I parse them into a map?

For example, the Labels object would look like this:

public class Labels {

   // I want to parse all the fields (field1, field2, etc) into 
   // this map
   Map<String, String> fields = new HashMap<>(); 

}

How do I do this?

3 Answers

Declaring Alert object like this:

public class Alert {
    private String description;
    private String status;
    private Map<String, String> labels;
    ...
}

works for me and this code

Alert myAlert = gson.fromJson(alertJSON, Alert.class);
System.out.println(myAlert.getLabels());

prints the map as {field1=value1, field2=value2, field100=value100}

So that no intermediate object is required

You can use TypeToken to directly specify labels.

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

Type mapType = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> myMap = gson.fromJson("{'field1':'value1','field2':'value2'}", mapType);

For general cases - some more flexible way: gson can register type adapters:

Gson gson = new GsonBuilder().registerTypeAdapter(Labels.class, new LabelsDeserializer()).create();

And deserializer for your case is:

public class LabelsDeserializer implements JsonDeserializer<Labels>
{
    @Override
    public Labels deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException
    {
        if (!jsonElement.isJsonNull())
        {
            Labels label = new Labels();
            jsonElement.getAsJsonObject().entrySet().forEach(entry -> label.getFields().put(entry.getKey(), entry.getValue().getAsString()));

            return label;
        }
        else
        {
            return null;
        }
    }
}

For serlializing it's needed to implement JsonSerializer<...>

Related