java - 带有 JsonDeserializer 的龙目岛
问题描述
我有一个想要反序列化为类的 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) {
...
}
}
谢谢!
阿西姆
解决方案
您实际上不需要自定义反序列化器和@JsonDeserialize
注释。提供ObjectMapper
了一个配置来启用包装/解包根值,可以使用@JsonRootName
Wrapper 对象类上的注释来提供该根值。
@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
问题中的部分,为此,您可以使用其他答案中提到的自定义反序列化器。
推荐阅读
- javascript - 在 www.facebook.com 上运行的浏览器扩展的 Facebook 登录
- c - How to write C program that attaches/detaches from Unix terminal?
- python - TypeError: 不支持的操作数类型 -: 'int' and 'str' with a datetime module
- javascript - 如何从 HTML 输入字段中旋转 jpeg 文件并将其保存为 base64 字符串
- google-chrome - A2HS 停止触发任何 PWA。是否有触发 A2HS 的实际规格?
- travis-ci - 如何设置 .travis.yml 在子文件夹中构建项目?
- cmake - CMake 找不到 ROS 包
- mysql - 用于获取不同类别和相关子类别 Laravel 的嵌套查询
- angular - Angular 延迟加载 - Chrome 和 Firefox 之间的区别
- python - Jaspersoft - Python - LXML - CSV - 变量子标签