我正在尝试从 JSON 反序列化两件事。第一个的格式如下:
String json = "[{\"name\":\"Random\"," +
"\"coordinates\":[[-3.1,55.4],[-3.1,55.9],[-3.7,55.3],[-3.8,55.7],[-3.0,55.8]]}]";
这是第二个:
String json2 = "[{\"name\":\"Random\"," + "\"longitude\":-3.1, \"latitude\":55}]
我的代码很简单,如下:
ObjectMapper mapper = new ObjectMapper();
var asArray = mapper.readValue(json, NoFlyZone[].class);
var asArray2 = mapper.readValue(json, LngLat.class);
NoFlyZone 类:
record NoFlyZone(LngLat[] coordinates) {
@JsonIgnoreProperties("name")
NoFlyZone (@JsonProperty("coordinates") double[][] coordinates) {
this(doubleArrayToLngLatArray(coordinates));
}
private static LngLat[] doubleArrayToLngLatArray(double[][] coordinates) {
var coordinateArray = new LngLat[coordinates.length];
for (int i = 0; i < coordinates.length; i++) {
coordinateArray[i] = new LngLat(coordinates[i][0], coordinates[i][1]);
}
System.out.println(coordinateArray);
return coordinateArray;
}
}
最后是 LngLat 类:
record LngLat(double lng, double lat) {
LngLat (@JsonProperty("longitude") double lng,
@JsonProperty("latitude") double lat) {
this.lng = lng;
this.lat = lat;
}
}
我尝试按照上面所示的方式反序列化它们,但是在尝试反序列化第一个字符串时会抛出 MismatchedInputException ,并显示错误消息“无法从数组值( token uk.ac.ed.inf.LngLat
)反序列化 JsonToken.START_ARRAY
类型的值。 ……”。我不确定为什么会发生这种情况,因此我们将不胜感激。
我也尝试过添加注释
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
并按照亚历山大的答案中详细说明的方式修复它,但是第二个字符串在尝试反序列化时会抛出错误。
最佳答案
自您记录以来LngLat
表示为 JSON 数组(如 "[-3.1, 55.4]"
),您需要自定义其反序列化。
为此,您可以使用 @JsonFormat
提供属性 shape
的注释值为 JsonFormat.Shape.ARRAY
。这将指示 Jackson 按照声明的顺序填充数组中的记录属性。
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
record LngLat(double lng, double lat) {}
并附上记录NoFlyZone
将被简化为(用于解析数组的特殊方法 LngLat
是多余的):
@JsonIgnoreProperties("name")
record NoFlyZone(LngLat[] coordinates) {}
使用示例:
String json = "[{\"name\":\"Random\"," +
"\"coordinates\":[[-3.1,55.4],[-3.1,55.9],[-3.7,55.3],[-3.8,55.7],[-3.0,55.8]]}]";
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(json, new TypeReference<List<NoFlyZone>>() {}));
输出:
注意: toString()
NoFlyZone
的方法已被覆盖以正确显示数组
[NoFlyZone{coordinates=[LngLat[lng=-3.1, lat=55.4], LngLat[lng=-3.1, lat=55.9], LngLat[lng=-3.7, lat=55.3], LngLat[lng=-3.8, lat=55.7], LngLat[lng=-3.0, lat=55.8]]}]
更新
如果需要支持两种完全不同的JSON结构,那么还需要对 NoFlyZone
进行自定义反序列化级别(因为其 JSON 形状不同)。
实现这一点的方法之一是引入用 @JsonCreator
注释的工厂方法。 。它期望有一个 Map<String, JsonNode>
类型的参数为了能够汇集所有的属性。
我们还需要设置ignoreUnknown
的属性的@JsonIgnoreProperties
至true
.
注意: LngLat
的定义保持不变(如上所示,用 @JsonFormat
注释)。
@JsonIgnoreProperties(ignoreUnknown = true)
public record NoFlyZone(LngLat[] coordinates) {
@JsonCreator
public static NoFlyZone getInstance(Map<String, JsonNode> fields) throws IOException {
boolean isArray = fields.containsKey("coordinates");
LngLat[] longLat;
if (isArray) {
ObjectReader reader = new ObjectMapper().readerFor(LngLat[].class);
longLat = reader.readValue(fields.get("coordinates")); // parsing JsonNode which corresponds to "coordinates" property
} else {
longLat = new LngLat[] { // creating a single-element array
new LngLat(
Double.parseDouble(fields.get("longitude").toString()),
Double.parseDouble(fields.get("latitude").toString())
)
};
}
return new NoFlyZone(longLat);
}
// toString()
}
使用示例:
String json1 = "[{\"name\":\"Random\"," +
"\"coordinates\":[[-3.1,55.4],[-3.1,55.9],[-3.7,55.3],[-3.8,55.7],[-3.0,55.8]]}]";
String json2 = "[{\"name\":\"Random\"," + "\"longitude\":-3.1, \"latitude\":55}]";
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(json1, new TypeReference<List<NoFlyZone>>() {}));
System.out.println(mapper.readValue(json2, new TypeReference<List<NoFlyZone>>() {}));
输出:
[NoFlyZone{coordinates=[LngLat[lng=-3.1, lat=55.4], LngLat[lng=-3.1, lat=55.9], LngLat[lng=-3.7, lat=55.3], LngLat[lng=-3.8, lat=55.7], LngLat[lng=-3.0, lat=55.8]]}]
[NoFlyZone{coordinates=[LngLat[lng=-3.1, lat=55.0]]}]
关于java - 使用 Jackson 反序列化 2D Json 数组时抛出错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74600808/