Как преобразовать ответ JSON, как показано ниже, в POJO с использованием Gson?

#json #gson #pojo

#json #gson #pojo

Вопрос:

Формат моего JSON :

 {"abc": [{
  "field_1": "string_1",
  "value": 0.304
},
{
  "field_1": "string_2",
  "value": 0.193
}]}
  

«abc» — это переменная, «field_1» и «value» — это имена полей. Мне нужен класс на Java, который хранит этот JSON в некотором формате, например:

  String t;                      // should store "abc"
 List<myClass> myClassObject;   // myClass should contain "field_1" and "value"
  

myClass.java

 String field_1;              // should store "string_1" and "string_2"
Double value;                // should store 0.304 and 0.193
  

Я хочу, чтобы класс myClass.java потому что в будущем я, возможно, захочу добавить больше метаданных в ответ JSON. Это сложное сопоставление объектов, но я не могу понять, как должен выглядеть мой класс, чтобы сохранить ответ JSON.

Ответ №1:

Для корневого объекта не создавайте новый, POJO просто используйте Map . Пример может выглядеть следующим образом:

 import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;

import java.io.File;
import java.io.FileReader;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class GsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        Gson gson = new GsonBuilder().create();

        Type mapType = new TypeToken<Map<String, List<Item>>>() {
        }.getType();
        Map<String, List<Item>> map = gson.fromJson(new FileReader(jsonFile), mapType);
        Map.Entry<String, List<Item>> first = map.entrySet().stream().findFirst().get();
        Items items = new Items(first.getKey(), first.getValue());

        System.out.println(items);
    }
}

class Items {
    private final String key;
    private final List<Item> items;

    public Items(String key, List<Item> items) {
        this.key = key;
        this.items = items;
    }

    public String getKey() {
        return key;
    }

    public List<Item> getItems() {
        return items;
    }

    @Override
    public String toString() {
        return "Items{"  
                "key='"   key   '''  
                ", items="   items  
                '}';
    }
}

class Item {

    @SerializedName("field_1")
    private String field;
    private Double value;

    public String getField() {
        return field;
    }

    public void setField(String field) {
        this.field = field;
    }

    public Double getValue() {
        return value;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "Item{"  
                "field='"   field   '''  
                ", value="   value  
                '}';
    }
}
  

Приведенный выше код выводит:

 Items{key='abc', items=[Item{field='string_1', value=0.304}, Item{field='string_2', value=0.193}]}
  

Комментарии:

1. Но я хочу POJO для корневого объекта. Не могли бы вы, пожалуйста, рассказать мне, как это сделать? Я хочу, чтобы результат был таким, каким я поделился выше. Мне не нужно сопоставление строки с объектом.

2. Или если бы я мог сохранить Map<Строка, объект> в классе в качестве переменной непосредственно с помощью Gson?

3. @YashUbale, если вам действительно нужен root класс, взгляните на мой отредактированный ответ.

4. @YashUbale, вы видели мои изменения. У вас это сработало?

5. На самом деле «abc» — это динамическое поле, вы можете десериализовать его в константу, но можете десериализовать его в Map<String, ?>, с этим разобрались

Ответ №2:

Я делюсь с вами примером кода:

Основной метод:

 import com.google.gson.Gson;
public class GsonConversion {
public static void main(String[] args) {
    String json = "{"abc": [{"   
            "  "field_1": "string_1","   
            "  "value": 0.304"   
            "},"   
            "{"   
            "  "field_1": "string_2","   
            "  "value": 0.193"   
            "}]}";
    Gson gson = new Gson();
    Type mapType = new TypeToken<Map<String, List<Data>>>() {
        }.getType();
        Map<String, List<Data>> map = gson.fromJson(json, mapType);
        Model model= new Model();
        map.entrySet().stream().forEach(entry->{
            model.setT(entry.getKey());
            model.setAbc(entry.getValue());
        });
        System.out.println("Key:" model.getT());
        model.getAbc().stream().forEach(x->{
            System.out.println("Field:" x.getField_1() " Value:" x.getValue());
        });
   }
}
  

Объекты родительской модели:
i) Класс модели

 import java.util.ArrayList;

public class Model {
   private String t;
   private ArrayList<Data> abc = new ArrayList<>();

   public String getT() {
        return t;
   }

   public void setT(String t) {
       this.t = t;
   }

   public ArrayList<Data> getAbc() {
         return abc;
   }

   public void setAbc(ArrayList<Data> abc) {
       this.abc = abc;
   }
}
  

ii) Класс данных

 public class Data {
   private String field_1;
   private Double value;

   public Data() {
   }

   public String getField_1() {
       return field_1;
   }

    public void setField_1(String field_1) {
       this.field_1 = field_1;
   }

    public Double getValue() {
       return value;
   }

   public void setValue(Double value) {
       this.value = value;
   }
}
  

Комментарии:

1. В приведенном выше JSON, которым я поделился, «abc» не является константой. Это может измениться. Класс модели предназначен только для «abc».