How do I make Jackson's build() method pretty-print its JSON output? Here is an example that pretty-prints the ugly form of JSON code. I need to take the nice version of
With the streaming API, you can use JsonGenerator.copyCurrentEvent() to easily re-output the token stream with whatever pretty-printing applied you want, including the default of no whitespace; this avoids buffering the entire document in memory and building a tree for the document.
// source and out can be streams, readers/writers, etc.
String source = " { \"hello\" : \" world \" } ";
StringWriter out = new StringWriter();
JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(source);
try (JsonGenerator gen = factory.createGenerator(out)) {
while (parser.nextToken() != null) {
gen.copyCurrentEvent(parser);
}
}
System.out.println(out.getBuffer().toString()); // {"hello":" world "}
You can use the same approach to pretty-print a JSON document in a streaming fashion:
// reindent
gen.setPrettyPrinter(new DefaultPrettyPrinter());
Jackosn-core is one way of solving but I prefer to use org.json
which is a very simple but standard json lib for java. Open source code here -> stleary/JSON-java.
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20160810</version>
</dependency>
String payload = "{\n" +
" \"fact1\": \"Java is verbose.\", \n" +
" \"fact2\" : \"C has pointers\"\n" +
"}";
System.out.println(new JSONObject(payload));
You'll get compact json {"fact2":"C has pointers","fact1":"Java is verbose."}
in one line.
Jackson allows you to read from a JSON string, so read the pretty-printed string back into Jackson and then output it again with pretty-print disabled.
See converting a String to JSON
Simple Example
String prettyJsonString = "{ \"Hello\" : \"world\"}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readValue(prettyJsonString, JsonNode.class);
System.out.println(jsonNode.toString());
Requires
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.3</version>
</dependency>
The safe way is to read the data using the "Raw" data binding and just write it out again without enabling the pretty printer. The Streaming API is probably your friend here.
Using a regexp does also work if you use this pattern: \s*\n\s*
This doesn't create the most compact form (i.e. you will still have some spaces between elements) but it's a cheap solution if you already have the JSON as a String. The reason why this pattern is safe is that new lines are invalid in String values (they must be escaped using \n
) so you can safely remove whitespace around them.