Convert JSON String to Pretty Print JSON output using Jackson
Asked Answered
S

11

221

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?

Seizure answered 25/1, 2013 at 5:37 Comment(0)
S
323

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.

Sheenasheeny answered 26/1, 2013 at 0:25 Comment(5)
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.Seizure
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.Sheenasheeny
For Jackson 2, use SerializationFeature.INDENT_OUTPUT, as specified by Marcelo C. belowRecord
any idea how to publish the amount of written value using jackson?Puglia
@BrownyLin Please update Javadoc link in comment: atetric.com/atetric/javadoc/org.codehaus.jackson/…Mcglothlin
S
146

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

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.writeValueAsString(obj)
Stokowski answered 1/6, 2014 at 17:32 Comment(1)
You can actually shorten that even further: ObjectMapper mapper = new ObjectMapper.enable(SerializationFeature.INDENT_OUTPUT);Venesection
A
35

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));
Ascidium answered 15/5, 2020 at 22:38 Comment(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.Cartoon
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...Godin
@Godin I just simplified the answer even further, thanks to the addition of toPrettyString() in Jackson 2.10.Cartoon
D
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!

Daladier answered 14/1, 2014 at 2:49 Comment(3)
Unfortunately, that doesn't help if my input is a runtime created object, not another json.Libava
@Libava Then skip the first line.Gawky
@Gawky Yeah, obviously. I even have done it, I don't know why I left such a stupid comment =)Libava
F
18

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

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
Feeling answered 26/2, 2014 at 5:42 Comment(0)
L
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.

Leveridge answered 29/7, 2016 at 8:2 Comment(4)
Worth noting this is using the JSON in Java (org.json) library.Antiperistalsis
In android, it can use direclty without any libraray.Acervate
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 keysKassey
The current approach, unfortunately, doesn't handle list of json objects. I mean [{"id":"1"}, {"id":"2"}]Sierrasiesser
N
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.

Nevlin answered 5/12, 2018 at 8:47 Comment(0)
M
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;}
}
Montane answered 25/1, 2013 at 6:3 Comment(2)
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.Seizure
Can you take a look into my POJO class that I have written from the JSON? It looks right or not?Seizure
I
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

Inveigh answered 2/9, 2020 at 22:50 Comment(0)
K
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.

Kollwitz answered 17/11, 2022 at 8:41 Comment(0)
D
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;
Disunity answered 23/2, 2021 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.