我有JsonNode要打印的结果。到目前为止,我正在使用:
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 ] }
但我需要采用以下特定格式:
对于上下文,我要从过渡JSONObject到Jackson,因此第二个输出是的输出JSONObject.serialize()。
JSONObject
JSONObject.serialize()
另外,上面列出的每种格式都有名称吗?似乎它遵循不同的标准。
您可以自定义Jackson如何缩进输出。根据您使用的Jackson版本,有多种实现方法。
请执行下列操作:
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接收字符串以缩进级别和行分隔符的构造函数:
DefaultIndenter
Indenter indenter = new DefaultIndenter(" ", DefaultIndenter.SYS_LF);
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个空格,你不能改变它。
Lf2SpacesIndenter
如果需要不同数量的空格,则需要编写自定义实现。这是使用与DefaultIndenterJackson 2.5中引入的代码相同的代码的代码:
/** * 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 <code>indent</code> string to indent one level * and the <code>eol</code> 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<INDENT_LEVELS; i++) { indent.getChars(0, indent.length(), indents, offset); offset += indent.length(); } this.eol = eol; } public CustomSpaceIndenter withLinefeed(String lf) { if (lf.equals(eol)) { return this; } return new CustomSpaceIndenter(getIndent(), lf); } public CustomSpaceIndenter withIndent(String indent) { if (indent.equals(getIndent())) { return this; } return new CustomSpaceIndenter(indent, eol); } public String getEol() { return eol; } public String getIndent() { return new String(indents, 0, charsPerLevel); } @Override public boolean isInline() { return false; } @Override public void writeIndentation(JsonGenerator jg, int level) throws IOException { jg.writeRaw(eol); if (level > 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);