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

Jackson INDENT_OUTPUT格式化异常,求排查问题原因

Jackson序列化List格式不符合预期问题

我折腾好久没找到问题所在,需求是把JSON读取为Java对象,操作后写入新的JSON文件。相关代码如下:

POJO类

@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
public class MyPojo {

    private String comment;
    private long pos;
    private int type;
}

JSON读取方法

public List<MyPojo> readMyPojos(File srcFile) {

    List<MyPojo> jsonObjects = new LinkedList<>();

    try {
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectReader objectReader = objectMapper.readerFor(MyPojo.class);

        Iterator<MyPojo> iterator = objectReader.readValues(srcFile);
        while (iterator.hasNext()) {
            jsonObjects.add(iterator.next());
        }
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

// 操作逻辑...

    return jsonObjects;
}

JSON写入方法

public void writeNewMyPojos(File srcFile, List<MyPojo> newFileContents) {

    String srcFileName = srcFile.getName();

    int fileExtensionIndex = srcFileName.lastIndexOf('.');
    String destFileExtension = srcFileName.substring(fileExtensionIndex);
    String destFileName = srcFileName.substring(0, fileExtensionIndex) + "_updated" + destFileExtension;
    File destFile = new File(srcFile.getParentFile(), destFileName);

    try {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

        objectMapper.writeValue(destFile, newFileContents);
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}

序列化结果对比

示例输入

newFileContents = List.of(
        new MyPojo("Test1", 1, 2),
        new MyPojo("Test2", 1, 2),
        new MyPojo("Test3", 1, 2)
);

预期输出

[ 
  {
    "comment" : "Test1",
    "pos" : 1,
    "type" : 2
  }, 
  {
    "comment" : "Test2",
    "pos" : 1,
    "type" : 2
  }, 
  {
    "comment" : "Test3",
    "pos" : 1,
    "type" : 2
  } 
]

实际输出

[ {
  "comment" : "Test1",
  "pos" : 1,
  "type" : 2
}, {
  "comment" : "Test2",
  "pos" : 1,
  "type" : 2
}, {
  "comment" : "Test3",
  "pos" : 1,
  "type" : 2
} ]

我试过Jackson 2.17、2.16甚至2.13版本,结果都一样。


解决方法

Jackson默认的INDENT_OUTPUT配置不会对数组元素的排版做额外调整,要实现预期的格式,需要自定义DefaultPrettyPrinter的行为:

修改写入方法中的序列化配置部分:

try {
    ObjectMapper objectMapper = new ObjectMapper();
    // 自定义格式化器
    DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter();
    // 数组元素使用换行+2空格缩进
    prettyPrinter.indentArraysWith(new Lf2SpacesIndenter());
    // 对象属性缩进2空格
    prettyPrinter.setObjectEntryIndent("  ");
    // 数组元素分隔符改为换行+2空格
    prettyPrinter.setArrayValueSeparator("\n  ");
    
    objectMapper.writer(prettyPrinter).writeValue(destFile, newFileContents);
} catch (IOException e) {
    throw new RuntimeException(e);
}

这样配置后,序列化出来的JSON数组就会和预期格式一致,每个元素单独换行并缩进,逗号后也会换行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 04:13:18