210

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?

Eran
  • 387,369
  • 54
  • 702
  • 768
arsenal
  • 23,366
  • 85
  • 225
  • 331

11 Answers11

313

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.

Jossef Harush Kadouri
  • 32,361
  • 10
  • 130
  • 129
StaxMan
  • 113,358
  • 34
  • 211
  • 239
  • 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. – arsenal Jan 26 '13 at 03:09
  • 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. – StaxMan Jan 26 '13 at 03:57
  • 34
    Hi, defaultPrettyPrintingWriter() has been deprecated. Since 1.9, use writerWithDefaultPrettyPrinter() instead. Refer: http://jackson.codehaus.org/1.9.0/javadoc/org/codehaus/jackson/map/ObjectMapper.html#defaultPrettyPrintingWriter() – Browny Lin Aug 06 '13 at 07:43
  • 6
    For Jackson 2, use SerializationFeature.INDENT_OUTPUT, as specified by Marcelo C. below – Mike R Oct 02 '14 at 15:09
  • any idea how to publish the amount of written value using jackson? – Reyansh Mishra Jun 21 '17 at 05:31
  • @BrownyLin Please update Javadoc link in comment: http://www.atetric.com/atetric/javadoc/org.codehaus.jackson/jackson-mapper-asl/1.9.0/org/codehaus/jackson/map/ObjectMapper.html#defaultPrettyPrintingWriter-- – dkb Jan 15 '18 at 09:17
141

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

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)
catch23
  • 17,519
  • 42
  • 144
  • 217
Marcelo C.
  • 3,822
  • 2
  • 22
  • 11
  • 28
    You can actually shorten that even further: ObjectMapper mapper = new ObjectMapper.enable(SerializationFeature.INDENT_OUTPUT); – Jason Nichols Jul 10 '16 at 14:51
28

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!

assylias
  • 321,522
  • 82
  • 660
  • 783
Marcello DeSales
  • 21,361
  • 14
  • 77
  • 80
26

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));
M. Justin
  • 14,487
  • 7
  • 91
  • 130
Praneeth
  • 559
  • 9
  • 19
  • 3
    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. – M. Justin May 21 '20 at 18:43
  • 1
    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 Feb 27 '21 at 00:54
  • 1
    @Akito I just simplified the answer even further, thanks to the addition of `toPrettyString()` in Jackson 2.10. – M. Justin Feb 27 '21 at 07:48
18

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

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
assylias
  • 321,522
  • 82
  • 660
  • 783
scalauser
  • 1,327
  • 1
  • 12
  • 34
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.

Aman Gupta - ΔMΔN
  • 2,971
  • 2
  • 19
  • 39
6

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.

Md. Sajedul Karim
  • 6,749
  • 3
  • 61
  • 87
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;}
}
Community
  • 1
  • 1
Daniel Kaplan
  • 62,768
  • 50
  • 234
  • 356
  • 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. – arsenal Jan 25 '13 at 06:05
  • Can you take a look into my POJO class that I have written from the JSON? It looks right or not? – arsenal Jan 25 '13 at 06:20
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

M. Justin
  • 14,487
  • 7
  • 91
  • 130
deFreitas
  • 4,196
  • 2
  • 33
  • 43
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;
Zon
  • 18,610
  • 7
  • 91
  • 99
0

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.