仅适用于嵌套 class 的自定义 jackson 解串器
Custom jackson deserializer only for nested class
我有一个 vehicle
Java class 定义如下:
public final class Vehicle {
private Integer id;
private String description;
private Location start;
private Location end;
private List<Integer> capacity;
private List<Integer> skills;
private TimeWindow timeWindow;
private List<Break> breaks;
public Vehicle(Integer id, String description, Location start,
Location end, List<Integer> capacity,
List<Integer> skills, TimeWindow timeWindow,
List<Break> breaks) {
this.id = id;
this.description = description;
this.start = start;
this.end = end;
this.capacity = capacity;
this.skills = skills;
this.timeWindow = timeWindow;
this.breaks = breaks;
}
TimeWindow
定义如下:
public final class Location {
private final Double latitude;
private final Double longitude;
public Location(Double latitude, Double longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
现在,我得到的 JSON 没有为位置定义 latitude
和 longitude
(start
和 end
);此信息仅编码为一个数组,请参见例如:
// vehicle.json
{
"id" : 0,
"description" : "vehicle 0",
"start" : [
12.304373066846503,
51.62270653765847
],
"end" : [
12.304373066846503,
51.62270653765847
],
"capacity" : [
9
],
"skills" : [
],
"time_window" : [
1644188400,
1644274800
],
"breaks" : [
]
}
在那种情况下,我如何才能为 Location
(与 TimeWindow
有同样的问题)编写自定义反序列化器?如果可能的话,我不想为整个 Vehicle
class.
编写自定义解串器
我试过这个:
@JsonDeserialize(
using = LocationJsonDeserializer.class
)
public final class Location {
// ....
public class LocationJsonDeserializer extends JsonDeserializer<Location> {
@Override
public Location deserialize(JsonParser p, DeserializationContext ctxt) {
final var longitude = 0d;
final var latitude = 0d;
// what to do here?
return new Location(latitude, longitude);
}
在我看来,我正在将整个 Vehicle
传递到我的 deserialize
方法中,而不仅仅是 Location
部分。我在这里做错了什么吗?使用 Jackson 这种方法可行吗?
您可以使用 @JsonCreator
标记和 Double[]
参数 start
和 end
将构造函数添加到 Vehicle
class。您还需要为每个参数添加 @JsonProperty
标记。
这是一个示例,为了简单起见,我没有包含参数 time_window
和 breaks
。
@JsonCreator
public Vehicle(@JsonProperty("id") Integer id,
@JsonProperty("description") String description,
@JsonProperty("start") Double[] start,
@JsonProperty("end") Double[] end,
@JsonProperty("capacity") List<Integer> capacity,
@JsonProperty("skills") List<Integer> skills) {
this(id, description, new Location(start[0], start[1]),
new Location(end[0], end[1]), capacity, skills);
}
在没有参数 time_window
和 breaks
的问题中使用 json
进行测试:
String result = "{\"id\":0,\"description\":\"vehicle 0\",\"start\":[12.304373066846503,51.62270653765847],\"end\":[12.304373066846503,51.62270653765847],\"capacity\":[9],\"skills\":[]}";
ObjectMapper mapper = new ObjectMapper();
Vehicle vehicle = mapper.readValue(result, Vehicle.class);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(vehicle);
System.out.println(json);
输出:
{
"id" : 0,
"description" : "vehicle 0",
"start" : {
"latitude" : 12.304373066846503,
"longitude" : 51.62270653765847
},
"end" : {
"latitude" : 12.304373066846503,
"longitude" : 51.62270653765847
},
"capacity" : [ 9 ],
"skills" : [ ]
}
我有一个 vehicle
Java class 定义如下:
public final class Vehicle {
private Integer id;
private String description;
private Location start;
private Location end;
private List<Integer> capacity;
private List<Integer> skills;
private TimeWindow timeWindow;
private List<Break> breaks;
public Vehicle(Integer id, String description, Location start,
Location end, List<Integer> capacity,
List<Integer> skills, TimeWindow timeWindow,
List<Break> breaks) {
this.id = id;
this.description = description;
this.start = start;
this.end = end;
this.capacity = capacity;
this.skills = skills;
this.timeWindow = timeWindow;
this.breaks = breaks;
}
TimeWindow
定义如下:
public final class Location {
private final Double latitude;
private final Double longitude;
public Location(Double latitude, Double longitude) {
this.latitude = latitude;
this.longitude = longitude;
}
现在,我得到的 JSON 没有为位置定义 latitude
和 longitude
(start
和 end
);此信息仅编码为一个数组,请参见例如:
// vehicle.json
{
"id" : 0,
"description" : "vehicle 0",
"start" : [
12.304373066846503,
51.62270653765847
],
"end" : [
12.304373066846503,
51.62270653765847
],
"capacity" : [
9
],
"skills" : [
],
"time_window" : [
1644188400,
1644274800
],
"breaks" : [
]
}
在那种情况下,我如何才能为 Location
(与 TimeWindow
有同样的问题)编写自定义反序列化器?如果可能的话,我不想为整个 Vehicle
class.
我试过这个:
@JsonDeserialize(
using = LocationJsonDeserializer.class
)
public final class Location {
// ....
public class LocationJsonDeserializer extends JsonDeserializer<Location> {
@Override
public Location deserialize(JsonParser p, DeserializationContext ctxt) {
final var longitude = 0d;
final var latitude = 0d;
// what to do here?
return new Location(latitude, longitude);
}
在我看来,我正在将整个 Vehicle
传递到我的 deserialize
方法中,而不仅仅是 Location
部分。我在这里做错了什么吗?使用 Jackson 这种方法可行吗?
您可以使用 @JsonCreator
标记和 Double[]
参数 start
和 end
将构造函数添加到 Vehicle
class。您还需要为每个参数添加 @JsonProperty
标记。
这是一个示例,为了简单起见,我没有包含参数 time_window
和 breaks
。
@JsonCreator
public Vehicle(@JsonProperty("id") Integer id,
@JsonProperty("description") String description,
@JsonProperty("start") Double[] start,
@JsonProperty("end") Double[] end,
@JsonProperty("capacity") List<Integer> capacity,
@JsonProperty("skills") List<Integer> skills) {
this(id, description, new Location(start[0], start[1]),
new Location(end[0], end[1]), capacity, skills);
}
在没有参数 time_window
和 breaks
的问题中使用 json
进行测试:
String result = "{\"id\":0,\"description\":\"vehicle 0\",\"start\":[12.304373066846503,51.62270653765847],\"end\":[12.304373066846503,51.62270653765847],\"capacity\":[9],\"skills\":[]}";
ObjectMapper mapper = new ObjectMapper();
Vehicle vehicle = mapper.readValue(result, Vehicle.class);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(vehicle);
System.out.println(json);
输出:
{
"id" : 0,
"description" : "vehicle 0",
"start" : {
"latitude" : 12.304373066846503,
"longitude" : 51.62270653765847
},
"end" : {
"latitude" : 12.304373066846503,
"longitude" : 51.62270653765847
},
"capacity" : [ 9 ],
"skills" : [ ]
}