228

This is the JSON string I have:

{"attributes":[{"nm":"ACCOUNT","lv":[{"v":{"Id":null,"State":null},"vt":"java.util.Map","cn":1}],"vt":"java.util.Map","status":"SUCCESS","lmd":13585},{"nm":"PROFILE","lv":[{"v":{"Party":null,"Ads":null},"vt":"java.util.Map","cn":2}],"vt":"java.util.Map","status":"SUCCESS","lmd":41962}]}

I need to convert the above JSON String into Pretty Print JSON Output (using Jackson), like below:

{
    "attributes": [
        {
            "nm": "ACCOUNT",
            "lv": [
                {
                    "v": {
                        "Id": null,
                        "State": null
                    },
                    "vt": "java.util.Map",
                    "cn": 1
                }
            ],
            "vt": "java.util.Map",
            "status": "SUCCESS",
            "lmd": 13585
        },
        {
            "nm": "PROFILE
            "lv": [
                {
                    "v": {
                        "Party": null,
                        "Ads": null
                    },
                    "vt": "java.util.Map",
                    "cn": 2
                }
            ],
            "vt": "java.util.Map",
            "status": "SUCCESS",
            "lmd": 41962
        }
    ]
}

Can anyone provide me an example based on my example above? How to achieve this scenario? I know there are lot of examples, but I am not able to understand those properly. Any help will be appreciated with a simple example.

Updated:

Below is the code I am using:

ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.defaultPrettyPrintingWriter().writeValueAsString(jsonString));

But this doesn't works with the way I needed the output as mentioned above.

Here's is the POJO I am using for the above JSON:

public class UrlInfo implements Serializable {

    private List<Attributes> attribute;

}

class Attributes {

    private String nm;
    private List<ValueList> lv;
    private String vt;
    private String status;
    private String lmd;

}


class ValueList {
    private String vt;
    private String cn;
    private List<String> v;
}

Can anyone tell me whether I got the right POJO for the JSON or not?

Updated:

String result = restTemplate.getForObject(url.toString(), String.class);

ObjectMapper mapper = new ObjectMapper();
Object json = mapper.readValue(result, Object.class);

String indented = mapper.defaultPrettyPrintingWriter().writeValueAsString(json);

System.out.println(indented);//This print statement show correct way I need

model.addAttribute("response", (indented));

Below line prints out something like this:

System.out.println(indented);


{
  "attributes" : [ {
    "nm" : "ACCOUNT",
    "error" : "null SYS00019CancellationException in CoreImpl fetchAttributes\n java.util.concurrent.CancellationException\n\tat java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat java.util.concurrent.FutureTask.",
    "status" : "ERROR"
  } ]
}

which is the way I needed to be shown. But when I add it to model like this:

model.addAttribute("response", (indented));

And then shows it out in a resultform jsp page like below:

    <fieldset>
        <legend>Response:</legend>
            <strong>${response}</strong><br />

    </fieldset>

I get something like this:

{ "attributes" : [ { "nm" : "ACCOUNT", "error" : "null    
SYS00019CancellationException in CoreImpl fetchAttributes\n 
java.util.concurrent.CancellationException\n\tat 
java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:231)\n\tat 
java.util.concurrent.FutureTask.", "status" : "ERROR" } ] }

which I don't need. I needed the way it got printed out above. Can anyone tell me why it happened this way?

0

12 Answers 12

338

To indent any old JSON, just bind it as Object, like:

Object json = mapper.readValue(input, Object.class);

and then write it out with indentation:

String indented = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(json);

this avoids your having to define actual POJO to map data to.

Or you can use JsonNode (JSON Tree) as well.

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks StaxMan, I guess this is working. When I print indented out I get in the way I needed. But when I use indented to add into the Model so that I can show them in resultform page. It still gets printed in two three lines. I have updated the question, maybe you will get some more idea what's happening now.
The problem is with Spring then -- I guess it expects a POJO as attribute, and not a pre-formatted String. So instead of trying to format it yourself, you'd need to tell Spring to do this. When using Jackson, it should be possible to configure it to use indentation. Although to be honest, I am not sure why you even need to indent it for response.
For Jackson 2, use SerializationFeature.INDENT_OUTPUT, as specified by Marcelo C. below
any idea how to publish the amount of written value using jackson?
@BrownyLin Please update Javadoc link in comment: atetric.com/atetric/javadoc/org.codehaus.jackson/…
149

The simplest and also the most compact solution (for v2.3.3):

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)

1 Comment

You can actually shorten that even further: ObjectMapper mapper = new ObjectMapper.enable(SerializationFeature.INDENT_OUTPUT);
40

ObjectMapper.readTree() can do this in one line:

mapper.readTree(json).toPrettyString();

Since readTree produces a JsonNode, this should pretty much always produce equivalent pretty-formatted JSON, as it JsonNode is a direct tree representation of the underlying JSON string.

Prior to Jackson 2.10

The JsonNode.toPrettyString() method was added in Jackson 2.10. Prior to that, a second call to the ObjectMapper was needed to write the pretty formatted result:

mapper.writerWithDefaultPrettyPrinter()
        .writeValueAsString(mapper.readTree(json));

4 Comments

The reason I like this answer is that it doesn't do any object conversion at all other than direct mapping to JSON types. So long as the input string is valid JSON, we know the output string will be semantically equivalent JSON.
This should be the accepted answer, because, as already mentioned by @M.Justin, we don't do any object conversion, which is a must, if the JSON could be anything. Why make life as hard as proposed in the other answers, when you can have it as easy as proposed in this answer...
@Akito I just simplified the answer even further, thanks to the addition of toPrettyString() in Jackson 2.10.
This is the best answer and should be the accepted one. I'm finding a short, simple, no variable declaration code to create a debug custom render on InteliJ. And base on your answer, the render expression can be "new com.fasterxml.jackson.databind.ObjectMapper().readTree(this).toPrettyString()". It's much shorter than other answer. Thanks for your answer
30

The new way using Jackson 1.9+ is the following:

Object json = OBJECT_MAPPER.readValue(diffResponseJson, Object.class);
String indented = OBJECT_MAPPER.writerWithDefaultPrettyPrinter()
                               .writeValueAsString(json);

The output will be correctly formatted!

3 Comments

Unfortunately, that doesn't help if my input is a runtime created object, not another json.
@Innokenty Then skip the first line.
@muttonUp Yeah, obviously. I even have done it, I don't know why I left such a stupid comment =)
18

For Jackson 1.9, We can use the following code for pretty print.

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);

Comments

17

I think, this is the simplest technique to beautify the json data,

String indented = (new JSONObject(Response)).toString(4);

where Response is a String.

Simply pass the 4(indentSpaces) in toString() method.

Note: It works fine in the android without any library. But in java you have to use the org.json library.

4 Comments

Worth noting this is using the JSON in Java (org.json) library.
In android, it can use direclty without any libraray.
String json = new GsonBuilder().setPrettyPrinting().create().toJson(map); String indentedJson = (new JSONObject(json)).toString(4); for some reason the second one is losing the order of keys
The current approach, unfortunately, doesn't handle list of json objects. I mean [{"id":"1"}, {"id":"2"}]
7

You can achieve this using bellow ways:

1. Using Jackson

    String formattedData=new ObjectMapper().writerWithDefaultPrettyPrinter()
.writeValueAsString(YOUR_JSON_OBJECT);

Import bellow class:

import com.fasterxml.jackson.databind.ObjectMapper;

It's gradle dependency is :

compile 'com.fasterxml.jackson.core:jackson-core:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.7.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.7.3'

2. Using Gson from Google

String formattedData=new GsonBuilder().setPrettyPrinting()
    .create().toJson(YOUR_OBJECT);

Import bellow class:

import com.google.gson.Gson;

It's gradle is:

compile 'com.google.code.gson:gson:2.8.2'

Here, you can also download correct updated version from repository.

Comments

4

This looks like it might be the answer to your question. It says it's using Spring, but I think that should still help you in your case. Let me inline the code here so it's more convenient:

import java.io.FileReader;

import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.ObjectWriter;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    ObjectMapper mapper = new ObjectMapper();
    MyClass myObject = mapper.readValue(new FileReader("input.json"), MyClass.class);
    // this is Jackson 1.x API only: 
    ObjectWriter writer = mapper.defaultPrettyPrintingWriter();
    // ***IMPORTANT!!!*** for Jackson 2.x use the line below instead of the one above: 
    // ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
    System.out.println(writer.writeValueAsString(myObject));
  }
}

class MyClass
{
  String one;
  String[] two;
  MyOtherClass three;

  public String getOne() {return one;}
  void setOne(String one) {this.one = one;}
  public String[] getTwo() {return two;}
  void setTwo(String[] two) {this.two = two;}
  public MyOtherClass getThree() {return three;}
  void setThree(MyOtherClass three) {this.three = three;}
}

class MyOtherClass
{
  String four;
  String[] five;

  public String getFour() {return four;}
  void setFour(String four) {this.four = four;}
  public String[] getFive() {return five;}
  void setFive(String[] five) {this.five = five;}
}

2 Comments

Thanks Daniel for the help. The toughest part I am having is how to model my JSON into a Class? If I get that part working, I can easily code rest of it.
Can you take a look into my POJO class that I have written from the JSON? It looks right or not?
3

Since jackson-databind:2.10 JsonNode has the toPrettyString() method to easily format JSON:

objectMapper
  .readTree("{}")
  .toPrettyString()
;

From the docs:

public String toPrettyString()

Alternative to toString() that will serialize this node using Jackson default pretty-printer.

Since:
2.10

Comments

1

Anyone using POJO, DDO, or response class for returning their JSON can use spring.jackson.serialization.indent-output=true in their property file. It auto-formats the response.

Comments

0

If you format the string and return object like RestApiResponse<String>, you'll get unwanted characters like escaping etc: \n, \". Solution is to convert your JSON-string into Jackson JsonNode object and return RestApiResponse<JsonNode>:

ObjectMapper mapper = new ObjectMapper();
JsonNode tree = objectMapper.readTree(jsonString);
RestApiResponse<JsonNode> response = new RestApiResponse<>();
apiResponse.setData(tree);
return response;

Comments

0

To pretty print JSON in Java using Jackson

String sampleJsonString = ""; // JSON String
objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(sampleJsonString);

Similarly you can pass any Java Type

Object javaType = any java Type; // Could be String, Map, List
objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(javaType);

If you would like to enable the pretty print one time or globally in your code

objectMapper.enable(SerializationFeature.INDENT_OUTPUT);

Optionally if you are parsing JSON with comments or a file with jsonc extension

Enable this setting for your JACKSON ObjectMapper

objectMapper.configure(JsonParser.Feature.ALLOW_COMMENTS, true);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.