mtyurt
mtyurt

Reputation: 3449

How do I get the compact/minified form of pretty-printed JSON in Java?

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

Answers (4)

Brad
Brad

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.


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>

Upvotes: 36

Aaron Digulla
Aaron Digulla

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

prayagupadhyay
prayagupadhyay

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.

maven dependency

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20160810</version>
</dependency>

usage

        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

Miles
Miles

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

Related Questions