gson 使用动态值的Json字符串到对象的Map

txu3uszq  于 2022-11-06  发布在  其他
关注(0)|答案(1)|浏览(205)

我正在使用第三方jsonString,我正在尝试解析json,但有时JSON对象“RadarReports”是一个列表,有时它是一个对象。

{"RadarReports": {
    "executionTime": "135",
"RadarReport": {
        "abc": "1116591",
        "name": "abc",
        "id": "2019050311582056119",
        "ownerId": "xyz"
    },
"size" :"1"
}}

=================

{"RadarReports": {
        "executionTime": "113",
        "RadarReport": [
            {
                 "abc": "1116591",
            "name": "abc",
            "id": "2019050311582056119",
            "ownerId": "xyz"
            },
            {
            "abc": "1116591",
            "name": "abc",
            "id": "2019050311582056119",
            "ownerId": "xyz"
            },
        ]
    "size" : "2"
    }}

我尝试在下面解析,但当单个对象进入图片时失败,需要接受单个对象和对象列表。

@Data
public class Radarreports {
    private int size;
    private ArrayList<RadarreportSet> RadarReportSet;
    private ArrayList<RadarReport> RadarReport;
}

@Data
public
class ReportsResponse {
    Radarreports RadarReports;
}

URL url = new URL(queryUrl);
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
Gson gson = new GsonBuilder().create();
ReportsResponse radarReports = gson.fromJson(br, ReportsResponse.class);
wtlkbnrh

wtlkbnrh1#

您可以使用自定义的TypeAdapterFactory来解决这个问题,它会创建一个适配器,该适配器首先查看JSON数据的类型,然后在JSON对象未被 Package 在JSON数组中的位置添加特殊处理:

// Only intended for usage with @JsonAdapter
class SingleObjectOrListAdapterFactory implements TypeAdapterFactory {
    @Override
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
        // Note: Cannot use getDelegateAdapter due to https://github.com/google/gson/issues/1028
        TypeAdapter<T> listAdapterDelegate = gson.getAdapter(type);
        TypeAdapter<JsonObject> jsonObjectAdapter = gson.getAdapter(JsonObject.class);

        return new TypeAdapter<T>() {
            @Override
            public void write(JsonWriter out, T value) throws IOException {
                listAdapterDelegate.write(out, value);
            }

            @Override
            public T read(JsonReader in) throws IOException {
                if (in.peek() == JsonToken.BEGIN_OBJECT) {
                    // Wrap JSON object in a new JSON array before parsing it
                    JsonObject jsonObject = jsonObjectAdapter.read(in);
                    JsonArray jsonArray = new JsonArray();
                    jsonArray.add(jsonObject);

                    return listAdapterDelegate.fromJsonTree(jsonArray);
                } else {
                    return listAdapterDelegate.read(in);
                }
            }
        };
    }
}

然后,可以使用@JsonAdapter为受影响的字段指定工厂:

@JsonAdapter(SingleObjectOrListAdapterFactory.class)
private ArrayList<RadarReport> RadarReport;

相关问题