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
相关产品推荐
相关产品推荐

