Reputation: 3449
How do I make Jackson's build() method pretty-print its JSON output? is an example that pretty-prints the JSON string.
I need to take the pretty-printed version of JSON string and then convert it to the compact/minified form. How can it be done?
I need to convert this:
{
"one" : "AAA",
"two" : [ "B B", "CCC" ],
"three" : {
"four" : "D D",
"five" : [ "EEE", "FFF" ]
}
}
to this:
{"one":"AAA","two":["B B","CCC"],"three":{"four":"D D","five":["EEE","FFF"]}}
I tried to remove '\n', '\t', and ' ' characters; but there may be some of these characters in values so I can't do that.
What else can be done?
Upvotes: 33
Views: 47972
Reputation: 15879
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.
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>
Upvotes: 36
Reputation: 328624
The safe way is to read the data using the JsonNode API and just write it out again without enabling the pretty printer.
ObjectMapper m = new ObjectMapper();
JsonNode rootNode = m.readTree(payload);
String compressed = rootNode.toString();
If the object is huge, the Streaming API can help.
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.
Upvotes: 9
Reputation: 31232
Jackosn-core is one way of pretty printing json. You can read the answer here https://stackoverflow.com/a/12174201/432903
You can also use org.json
library, 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.
Upvotes: 7
Reputation: 32478
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());
Upvotes: 9