在Jackson中将JsonNode序列化为非常特定的JSON格式

我有JsonNode结果,我想要打印出来。 到目前为止,我正在使用:

 ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); File outputFile = new File( getCurOutputDir(), String.format("out.json", getClass().getSimpleName()) ); mapper.writeValue(new FileOutputStream(outputFile), resultNode); 

输出如下:

 { "A" : [ { "Ai" : { "Ai1" : 42, "Ai2" : 55 } } ], "B" : [ 86 ] } 

但我需要它采用这种特定的格式:

 { "A" : [ { "Ai" : { "Ai1" : 42, "Ai2" : 55 } } ], "B" : [ 86 ] } 

对于上下文,我正在从JSONObject转换到Jackson,因此第二个输出是由JSONObject.serialize()输出的输出。

另外,上面列出的每种格式都有名称吗? 它似乎遵守不同的标准。

您可以自定义Jackson缩进输出的方式。 根据您使用的Jackson版本,有不同的方法可以实现它。

jackson2.5及更新版本

请执行下列操作:

 DefaultPrettyPrinter printer = new DefaultPrettyPrinter(); Indenter indenter = new DefaultIndenter(); printer.indentObjectsWith(indenter); // Indent JSON objects printer.indentArraysWith(indenter); // Indent JSON arrays ObjectMapper mapper = new ObjectMapper(); mapper.writer(printer).writeValue(new FileOutputStream(outputFile), node); 

默认情况下,将使用2个空格。 对于不同数量的空格,使用DefaultIndenter构造函数接收字符串以缩进级别和行分隔符:

 Indenter indenter = new DefaultIndenter(" ", DefaultIndenter.SYS_LF); 

jackson2.4及更早版本

请执行下列操作:

 DefaultPrettyPrinter printer = new DefaultPrettyPrinter(); Indenter indenter = new Lf2SpacesIndenter(); printer.indentObjectsWith(indenter); // Indent JSON objects printer.indentArraysWith(indenter); // Indent JSON arrays ObjectMapper mapper = new ObjectMapper(); mapper.writer(printer).writeValue(new FileOutputStream(outputFile), node); 

Lf2SpacesIndenter限制为2个空格,您无法更改它。

如果您需要不同数量的空格,则需要编写自定义实现。 这是一个使用与Jackson 2.5中引入的DefaultIndenter相同的代码:

 /** * Default linefeed-based indenter. */ public class CustomSpaceIndenter extends DefaultPrettyPrinter.NopIndenter { public final static String SYS_LF; static { String lf; try { lf = System.getProperty("line.separator"); } catch (Throwable t) { lf = "\n"; // fallback when security manager denies access } SYS_LF = lf; } public static final CustomSpaceIndenter SYSTEM_LINEFEED_INSTANCE = new CustomSpaceIndenter(" ", SYS_LF); /** * We expect to rarely get indentation deeper than this number of levels, * and try not to pre-generate more indentations than needed. */ private final static int INDENT_LEVELS = 16; private final char[] indents; private final int charsPerLevel; private final String eol; /** * Indent with two spaces and the system's default line feed */ public CustomSpaceIndenter() { this(" ", SYS_LF); } /** * Create an indenter which uses the indent string to indent one level * and the eol string to separate lines. */ public CustomSpaceIndenter(String indent, String eol) { charsPerLevel = indent.length(); indents = new char[indent.length() * INDENT_LEVELS]; int offset = 0; for (int i=0; i 0) { // should we err on negative values (as there's some flaw?) level *= charsPerLevel; while (level > indents.length) { // unlike to happen but just in case jg.writeRaw(indents, 0, indents.length); level -= indents.length; } jg.writeRaw(indents, 0, level); } } } 

它可以用作以下内容:

 Indenter indenter = new CustomSpaceIndenter(" ", CustomSpaceIndenter.SYS_LF); 

您可以使用以下命令设置自定义DefaultPrettyPrinter

 DefaultPrettyPrinter pp = new DefaultPrettyPrinter(); pp.indentObjectsWith(new Lf2SpacesIndenter()); pp.indentArraysWith(new Lf2SpacesIndenter("\r\n")); mapper.writer(pp).writeValue(new FileOutputStream(outputFile), resultNode); 

看一下DefaultPrettyPrinter 这里提供的方法