我有一個 JSON 字串,我想將其反序列化為一個類。JSON 如下所示:
{ "data": { "name": "Box 1", "size": "10x20" } }
我可以將其反序列化為以下類:
@Builder
@Value
@JsonDeserialize(builder = Box1.Box1Builder.class)
public class Box1 {
@JsonProperty("data")
Box1Data data;
public static Box1 of(String json) throws IOException {
return new ObjectMapper().readValue(json, Box1.class);
}
@Builder
@Value
@JsonDeserialize(builder = Box1Data.Box1DataBuilder.class)
static class Box1Data {
@JsonProperty("name")
String name;
@JsonProperty("size")
String size;
}
}
上面的類看起來很笨拙,因為它有一個無用的data. 我可以像這樣擺脫它:
@Builder
@Value
@JsonDeserialize(using = Box2Deserializer.class)
public class Box2 {
@JsonProperty("name")
String name;
@JsonProperty("size")
String size;
public static Box2 of(String json) throws IOException {
return new ObjectMapper().readValue(json, Box2.class);
}
static class Box2Deserializer extends JsonDeserializer<Box2> {
@Override
public Box2 deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
var node = jsonParser.getCodec().readTree(jsonParser);
var dataNode = node.get("data");
return Box2.builder()
.name(dataNode.get("name").toString())
.size(dataNode.get("size").toString())
.build();
}
}
}
但在這里,我遇到了死胡同。我希望該size欄位被決議為一個Dimension實體。我可以撰寫一個自定義反序列化器來size決議 aString并回傳一個正確的Dimension,但我不能通過欄位注釋使用它(@JsonDeserialize(using = SizeDeserializer.class)因為JsonDeserialize類注釋的存在迫使它在 for 的情況下被忽略Box1,而在 for 的情況下Box2,它被忽略,因為我正在手動構建盒子。
有沒有一個優雅的解決方案來解決所有這些混亂?我想要的是將給定的 JSON 讀入這樣的類:
@Builder
@Value
public class Box3 {
@JsonProperty("name")
String name;
@JsonProperty("size")
Dimension size;
public static Box3 of(String json) {
...
}
}
謝謝!
阿西姆
uj5u.com熱心網友回復:
我將添加到@Iprakashv 解決方案中,除了JsonRootName根節點包裝僅需要型別注釋和映射器序列化/反序列化之外,您只需要一個從原始型別到自定義型別的自定義型別轉換器:
@Builder
@Value
@JsonRootName("data")
public class Box {
@JsonProperty("name")
String name;
@JsonDeserialize(converter = StringToDimensionConverter.class)
@JsonProperty("size")
Dimension size;
public static Box of(String json) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
mapper.enable(SerializationFeature.WRAP_ROOT_VALUE);
return mapper.readValue(json, Box.class);
}
private static class StringToDimensionConverter extends StdConverter<String, Dimension> {
@Override
public DataWrapper.Box1Data.Dimension convert(String s) {
return new DataWrapper.Box1Data.Dimension(s);
}
}
}
uj5u.com熱心網友回復:
您實際上不需要自定義反序列化器和@JsonDeserialize注釋。在ObjectMapper提供了一個配置,以使纏繞/展開,其可以使用可提供一個根值@JsonRootName在包裝物件類注釋。
@Builder
@Value
@JsonRootName("data")
public class Box {
@JsonProperty("name")
String name;
@JsonProperty("size")
String size;
public static Box of(String json) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE);
return mapper.readValue(json, Box.class);
}
}
PS:完全錯過了Dimension問題中的部分,為此,您可以使用其他答案中提到的自定義解串器。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/333857.html
