首页 > 编程语言 >如何使用Jackson递归截断JSON中所有字符串值长度

如何使用Jackson递归截断JSON中所有字符串值长度

来源:互联网 2026-07-10 08:08:05

本方法采用Jackson的JsonNode递归遍历任意深度嵌套JSON,精准识别所有字符串类型叶节点,并将其值截断为最多5个字符,同时保持原始JSON结构不变,全面覆盖对象、数组、null值、空字符串等边界情况,并确保处理了空字符串及null值等特殊情况,具有健壮性。

这篇文章要聊的是,如何用Jackson的JsonNode API,遍历任意深度的嵌套JSON,把里面所有字符串类型的叶节点值,统一截成最多5个字符。不管是对象、数组还是混合结构,都覆盖到了,还会处理空值和边界情况。

一、实际开发中的JSON标准化清洗需求

在实际开发中,经常需要对动态JSON做标准化清洗——比如限制日志字段长度、脱敏显示、或者适配前端控件的显示宽度。Jackson作为主流的JSON处理库,它的树模型(JsonNode)提供了很灵活的遍历能力。下面这个方案就是通过递归遍历JsonNode,精准识别并截断所有非容器型的字符串值(也就是isTextual()为true,又不是对象或数组的节点),同时保持原始JSON结构不变。

二、递归遍历三类节点的核心逻辑

处理逻辑其实不复杂,主要分三类节点:

长期稳定更新的攒劲资源: >>>点此立即查看<<<

  • 数组节点:遍历每个元素,递归处理;
  • 对象节点:遍历所有键值对,对值节点分类处理;
  • 叶节点(字符串):只在isTextual()为true时截取前5个字符,如果原字符串长度本来就≤5,那就不动,避免报错。

三、完整可运行示例代码

以下是完整可运行示例(已增强健壮性):

import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.util.Iterator;
import java.util.Map.Entry;

public class JsonStringTruncator {
    private static final int MAX_STRING_LENGTH = 5;

    public static String truncateAllStringValues(String json) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode root = mapper.readTree(json);
        truncateStringValues(root);
        return mapper.writeValueAsString(root);
    }

    private static void truncateStringValues(JsonNode node) {
        if (node == null || node.isMissingNode()) return;
        if (node.isArray()) {
            for (JsonNode element : node) {
                truncateStringValues(element);
            }
        } else if (node.isObject()) {
            ObjectNode objectNode = (ObjectNode) node;
            Iterator> fields = objectNode.fields();
            while (fields.hasNext()) {
                Entry field = fields.next();
                JsonNode value = field.getValue();
                if (value.isTextual()) {
                    String text = value.asText();
                    String truncated = text.length() <= MAX_STRING_LENGTH 
                         text 
                        : text.substring(0, MAX_STRING_LENGTH);
                    objectNode.put(field.getKey(), truncated);
                } else if (value.isContainerNode()) {
                    truncateStringValues(value); // 递归处理嵌套对象或数组
                }
                // 忽略数字、布尔、null 等非字符串类型,保持原样
            }
        }
        // 其他类型(如数值、布尔、null)不作处理
    }

    // 使用示例
    public static void main(String[] args) throws JsonProcessingException {
        String input1 = "{"key1":"bla bla bla bla","key2":{"key21":"bla bla bla"}}";
        String input2 = "{"fname":"John Doe","address":{"street":"123 Main St","zip":10001}}";
        System.out.println("Input 1: " + input1);
        System.out.println("Output 1: " + truncateAllStringValues(input1));
        // → {"key1":"bla b","key2":{"key21":"bla b"}}
        System.out.println("Input 2: " + input2);
        System.out.println("Output 2: " + truncateAllStringValues(input2));
        // → {"fname":"John ","address":{"street":"123 M","zip":10001}}
    }
}

四、关键注意事项

有几个关键点需要特别留意:

  • 安全性优先:显式检查 isTextual() 而非 !isContainerNode(),避免将数字 123456 错误转为字符串再截断;
  • 空值防护:添加 node == null || node.isMissingNode() 判断,防止 NPE;
  • 不可变性保障:JsonNode 本身不可变,操作基于 ObjectNode(可变子类),因此需确保输入为可修改节点(readTree 返回的默认实现满足);
  • 性能提示:对超大 JSON,可考虑流式解析(JsonParser)以降低内存占用,但会显著增加实现复杂度;
  • 扩展建议:如需按 key 名过滤(如仅截断 "description" 字段),可在 field.getKey() 处添加白名单判断。

五、方案总结与应用场景

总的来说,这个方案简洁可靠,适合日志裁剪、API 响应预处理、测试数据生成这些场景,算是 Jackson 树模型的一个很实用的例子。

侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述

热游推荐

更多
湘ICP备14008430号-1 湘公网安备 43070302000280号
All Rights Reserved
本站为非盈利网站,不接受任何广告。本站所有软件,都由网友
上传,如有侵犯你的版权,请发邮件给xiayx666@163.com
抵制不良色情、反动、暴力游戏。注意自我保护,谨防受骗上当。
适度游戏益脑,沉迷游戏伤身。合理安排时间,享受健康生活。