You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jackson:如何去除JSON输出中冒号左侧的空格

解决Jackson生成JSON时键与冒号间多余空格的问题

当前生成的JSON存在键名与冒号之间多一个空格的问题,示例如下:

[
    {
        "satelliteId" : 1000,
        "severity" : "RED HIGH",
        "component" : "TSTAT",
        "timestamp" : "2018-01-01T23:01:38.001Z"
    },
    {
        "satelliteId" : 1000,
        "severity" : "RED LOW",
        "component" : "BATT",
        "timestamp" : "2018-01-01T23:01:09.521Z"
    }
]

对应的生成代码(注释已转为中文):

import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class FormatAlerts {
    List<Message> alerts = new ArrayList<>();

    public FormatAlerts(List<Message> alerts){
        this.alerts = alerts;
    }

    public String formatAlerts(){

        String formattedAlerts = null;
        ObjectMapper om = new ObjectMapper();
        ArrayNode arrayNode = om.createArrayNode();

        // 创建自定义格式化器,调整括号和大括号的缩进量
        String indent = String.format("%-4s","");
        DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(indent, DefaultIndenter.SYS_LF);
        DefaultPrettyPrinter printer = new DefaultPrettyPrinter();
        printer.indentObjectsWith(indenter);
        printer.indentArraysWith(indenter);


        try {
            for (Message m : alerts) {
                // 格式化时间
                Instant t = Instant.ofEpochMilli(m.getEpochTime());
                m.setTimestamp(t.toString());

                // 将告警格式化为JSON
                String alert = om.writer(printer).writeValueAsString(m);
                // String alert = om.writerWithDefaultPrettyPrinter().writeValueAsString(m);
                ObjectNode obj = om.readValue(alert, ObjectNode.class);          
                arrayNode.add(obj);
                formattedAlerts = om.writer(printer).writeValueAsString(arrayNode);
                // formattedAlerts = om.writerWithDefaultPrettyPrinter().writeValueAsString(arrayNode);
            }
        } catch (JsonProcessingException jpe) {
            jpe.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return formattedAlerts;
    }
}

解决方案

问题根源在于DefaultPrettyPrinter的默认配置:它会在键和冒号之间添加空格(默认分隔符是": ")。要去掉这个空格,只需修改DefaultPrettyPrinter的objectFieldValueSeparator属性为":"即可。

同时原代码存在两处可优化点:

  1. 字符串格式化语句缺少闭合引号,需修正
  2. 循环内重复生成整个数组的JSON字符串,效率低下,建议循环仅添加节点,最后统一生成结果

修改后的完整代码:

import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.DefaultIndenter;
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class FormatAlerts {
    List<Message> alerts = new ArrayList<>();

    public FormatAlerts(List<Message> alerts){
        this.alerts = alerts;
    }

    public String formatAlerts(){

        String formattedAlerts = null;
        ObjectMapper om = new ObjectMapper();
        ArrayNode arrayNode = om.createArrayNode();

        // 创建自定义格式化器,调整括号和大括号的缩进量
        String indent = String.format("%-4s","");
        DefaultPrettyPrinter.Indenter indenter = new DefaultIndenter(indent, DefaultIndenter.SYS_LF);
        DefaultPrettyPrinter printer = new DefaultPrettyPrinter();
        // 移除键与冒号之间的空格
        printer.objectFieldValueSeparator(":");
        printer.indentObjectsWith(indenter);
        printer.indentArraysWith(indenter);


        try {
            for (Message m : alerts) {
                // 格式化时间
                Instant t = Instant.ofEpochMilli(m.getEpochTime());
                m.setTimestamp(t.toString());

                // 直接将对象转为ObjectNode,避免序列化后再反序列化的冗余操作
                ObjectNode obj = om.valueToTree(m);
                arrayNode.add(obj);
            }
            // 最后统一生成格式化后的JSON,提升效率
            formattedAlerts = om.writer(printer).writeValueAsString(arrayNode);
        } catch (JsonProcessingException jpe) {
            jpe.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return formattedAlerts;
    }
}

修改后生成的JSON会符合预期,键与冒号间无多余空格,同时保留原有缩进格式:

[
    {
        "satelliteId": 1000,
        "severity": "RED HIGH",
        "component": "TSTAT",
        "timestamp": "2018-01-01T23:01:38.001Z"
    },
    {
        "satelliteId": 1000,
        "severity": "RED LOW",
        "component": "BATT",
        "timestamp": "2018-01-01T23:01:09.521Z"
    }
]

内容的提问来源于stack exchange,提问作者Steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 21:17:19