java - Gson 如何解析单个数组中的不同数据类型?
问题描述
我有一个 API 响应,其中包括 METAR 天气数据以及字符串错误响应,它们都包含在同一个“数据”数组中。我正在使用 Gson 来解析 Android 上的 json 响应。这很好用,直到我收到字符串错误响应。我已经尝试过尝试编写自定义 Gson 反序列化器,但没有成功。有人可以给我一个工作示例或为我指出如何处理此问题的正确方向吗?
响应如下所示:
{
"results": 4,
"data": [
{
"icao": "KAJO",
"name": "Corona Municipal",
"observed": "05-11-2018 @ 18:56Z",
"raw_text": "KAJO 051856Z AUTO VRB03KT 10SM CLR 23/08 A2989 RMK AO2 SLP129 T02330078 $",
"barometer": {
"hg": 29.890000000000001,
"kpa": 101.22,
"mb": 1012.9
},
"clouds": [
{
"code": "CLR",
"text": "Clear skies",
"base_feet_agl": 0,
"base_meters_agl": 0
}
],
"dewpoint": {
"celsius": 8,
"fahrenheit": 46
},
"elevation": {
"feet": 535,
"meters": 163
},
"flight_category": "VFR",
"humidity_percent": 38,
"temperature": {
"celsius": 23,
"fahrenheit": 73
},
"visibility": {
"miles": "10",
"meters": "16,093"
},
"wind": {
"degrees": 0,
"speed_kts": 3,
"speed_mph": 3,
"speed_mps": 2
}
},
"KGNG METAR Currently Unavailable",
"CXCY Invalid Station ICAO"
]
}
如您所见,“数据”数组可能会返回一个元对象(我有这部分工作)或一个未命名的错误字符串。当我收到返回的错误字符串时,我的解析失败了。
作为测试,我写了以下内容。但它也不起作用。如何解析原始未命名字符串和元对象?
import com.google.gson.*;
import java.lang.reflect.Type;
import java.util.List;
public class Main {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Response.class, new MyDeserializer())
.registerTypeAdapter(String.class, new String())
.create();
Response response = gson.fromJson(str_json, Response.class);
System.out.println("Hello World!");
}
static class MyDeserializer implements JsonDeserializer<Response> {
@Override
public Response deserialize(JsonElement json, Type typeOfT
,JsonDeserializationContext context) throws JsonParseException {
// Get the "data" element from the parsed json
JsonElement data = json.getAsJsonObject().get("data ");
// Deserialize it. You use a new instance of Gson to avoid
// infinite recursion
return new Gson().fromJson(data, Response.class);
}
}
/*===============================
* Data Definitions
*==============================*/
class Response {
public String results;
public List<Station> Stations;
}
class Station {
public String name;
public String icao;
}
public static String str_json = "{\n" +
" \"results\": 3,\n" +
" \"data\": [\n" +
" {\n" +
" \"name\": \"Billings Logan Intl\"," +
" \"icao\":\"KBIL\"," +
" },\n" +
" \"CYPG METAR Currently Unavailable\",\n" +
" \"KGNG METAR Currently Unavailable\"\n" +
" ]\n" +
"}";
}
解决方案
首先,如果您稍微更改一下 DTO,它会让事情变得更简单,因为Response
public class Response {
public String results;
public List<Station> data; // it is named data in JSON not Stations
}
然后根据您希望如何处理错误文本来完成其余的工作。一种简单的方法是将错误字段添加到您的Station
,这样它将是:
public class Station {
public String name;
public String icao;
public String error; // used if there is only error string
}
使用自定义反序列化器,例如:
public class StationDeserializer implements JsonDeserializer<Station> {
private final Gson gson = new Gson();
@Override
public Station deserialize(JsonElement json, Type typeOfT
,JsonDeserializationContext context)
throws JsonParseException {
try {
return gson.fromJson(json, Station.class);
} catch (JsonSyntaxException e) {
// it was not a Station object
Station station = new Station();
// so try to set the error string
station.error = json.getAsString();
return station;
}
}
}
尝试反序列化:
Response response = new GsonBuilder()
.registerTypeAdapter(Station.class, new StationDeserializer())
.create()
.fromJson(str_json, Response.class);
检查 a 中是否有error
字符串,Station
您可以查看数据是否有效。
推荐阅读
- python - LED 矩阵到阵列的图像
- docker - Winlogbeat 设置错误:x509 证书适用于
, 不是 - ocr - 强制 Tesseract (with pytesseract) 识别指定模式
- python - 结合两列给出一个nan输出
- angular - 'NgIf' 既不是 'ComponentType' 也不是 'DirectiveType'
- r - 如何使用伽马分布方程
- python - 将位置处的布尔掩码应用于 2D numpy 数组
- php - PHP - MySql rowCount() 问题,不列出用户名
- python - 如何使用 QDoubleSpinBoxes 更改 QDoubleSpinBoxes 中的值?
- nginx - AWS Lightsail - Nginx Bitnami React 应用程序 - 更改主页