使用Jackson解析嵌套JSON时,如何直接从uri属性开始反序列化?
如何让Jackson直接从JSON的指定嵌套属性开始反序列化?
你的问题很典型——JSON结构外层多了一个"uri"根节点,但你想直接把里面的内容解析到Uri类里,Jackson默认会把整个JSON对象当成Uri的实例,自然会因为找不到"uri"属性报错。下面是几种实用的解决办法:
方法一:用树模型先提取目标节点
这种方法不需要修改你的Uri类,先把整个JSON读成JsonNode,再提取出"uri"节点转成目标对象:
ObjectMapper mapper = new ObjectMapper(); // 先读取整个JSON为树结构 JsonNode rootNode = mapper.readTree(new URL("test2.json")); // 定位到"uri"节点 JsonNode uriNode = rootNode.get("uri"); // 将节点转成Uri对象 Uri uri = mapper.treeToValue(uriNode, Uri.class);
方法二:用@JsonRootName注解+开启解包特性
这种方式更优雅,适合长期使用:
- 首先给你的
Uri类加上@JsonRootName注解,指定根节点名称:
import com.fasterxml.jackson.annotation.JsonRootName; @JsonRootName("uri") public class Uri { private String firstname; private String lastname; private int age; // getter 和 setter }
- 然后在
ObjectMapper上开启UNWRAP_ROOT_VALUE特性,让Jackson自动识别根节点并解析内部内容:
ObjectMapper mapper = new ObjectMapper(); mapper.enable(DeserializationFeature.UNWRAP_ROOT_VALUE); Uri uri = mapper.readValue(new URL("test2.json"), Uri.class);
方法三:创建包装类匹配完整JSON结构
如果不想修改Uri类或者调整Jackson配置,可以写一个简单的包装类来对应整个JSON结构:
// 包装类,对应外层的"uri"字段 public class UriWrapper { private Uri uri; // getter 和 setter }
然后先解析到包装类,再取出Uri对象:
ObjectMapper mapper = new ObjectMapper(); UriWrapper wrapper = mapper.readValue(new URL("test2.json"), UriWrapper.class); Uri uri = wrapper.getUri();
这三种方法都能解决你的问题,你可以根据自己的场景选择——比如临时处理用方法一,项目规范里的实体类用方法二,不想改动原有代码用方法三。
内容的提问来源于stack exchange,提问作者Evgenij Reznik




