jackson中JSON字符串节点遍历和修改

 有些场景下,在实现一些基础服务和拦截器的时候,我们可能需要在不知道JSON字符串所属对象类型的情况下,对JSON字符串中的某些属性进行遍历和修改,比如,设置或查询一些报文头字段。

在jackson中,使用最多的JsonNode抽象类并没有提供修改节点值的方法,而是在ObjectNode节点中提供修改接口,这个节点在官方的说明中,一般用于创建新的节点。

假设packet.getDecryptRequestBody()中是一个json字符串,可以通过如下代码查看

JsonNode rootNode = mapper.readTree(packet.getDecryptRequestBody());                    
JsonNode targetNode = null;
targetNode = rootNode.findValue("rpcMsgId"); // 查找第一级的rpcMsgId属性,如果属性不存在,则返回null,属性值如果为明确的null,返回NullNode,否则返回正常的JsonNode

// 注:JsonNode还提供了find/path/get等获取节点的方法,但是这三种方法都不能明确的区分节点不存在、为明确的null。所以,应该使用findValue方法。

如果只是纯粹的遍历和类似JsonTree的构造,网上各种文章一堆,主要是对原json中属性的修改。可通过如下方式进行修改:


((ObjectNode)targetNode).put("rpcMsgId","abcdefg1234567890"); // 通过强制转换为ObjectNode,就可以对当前节点进行修改,其他的XXXNode均没有提供相关的API接口 String modifiedJsonStr = mapper.writeValueAsString(rootNode); // 最后重新生成json字符串,这跟dom4j修改xml一样,只能重新生成,内置不支持直接修改原文件

完整的例子如下:

复制代码
public class PacketHead {
private String serviceId;
    private String rpcMsgId;private Map<String,String> spiderOpts;
       //此处getter/setter省去
}
public class SpiderRequest {
    
    private PacketHead spiderPacketHead;
    
    private String requestBody;
    
    private String resultInfo;

    public SpiderPacketHead getSpiderPacketHead() {
        return spiderPacketHead;
    }

    public void setSpiderPacketHead(SpiderPacketHead spiderPacketHead) {
        this.spiderPacketHead = spiderPacketHead;
    }

    public String getRequestBody() {
        return requestBody;
    }

    public void setRequestBody(String requestBody) {
        this.requestBody = requestBody;
    }
    
    @JsonIgnore
    public String getRequestId() {
        return spiderPacketHead.getRpcMsgId();
    }

    public String getResultInfo() {
        return resultInfo;
    }

    public void setResultInfo(String resultInfo) {
        this.resultInfo = resultInfo;
    }

    public static void main(String[] args) throws JsonProcessingException, IOException {
        SpiderRequest req = new SpiderRequest();
        req.setSpiderPacketHead(new SpiderPacketHead());
        String json = JsonUtils.toJson(req);
        System.out.println(json);
        JsonNode node = mapper.readTree(json);
        JsonNode node1 = node.findValue("spiderPacketHead");
        ObjectNode node2 = (ObjectNode) node1;
        node2.put("rpcMsgId", "abc");
        System.out.println(mapper.writeValueAsString(node));
    }
复制代码

 

posted @   zhjh256  阅读(18429)  评论(1编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示