#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».