Java
Convert JSON String to Pretty Print JSON output using Jackson
Working with JSON data is a common task in modern software development, and often you need to display it in a human-readable format. If you have a JSON string, you might want to convert JSON string to pretty print JSON output, which makes it easier to read and debug. This article explores how to achieve this using Jackson, a popular Java library for processing JSON. We’ll go through the steps, provide code examples, and explain the underlying concepts so you can effectively format your JSON data. By the end of this guide, you’ll be able to transform compact JSON strings into neatly formatted, indented output, enhancing your ability to work with and understand JSON data in your projects. JSON formatting becomes even more important when dealing with complex nested structures, as it drastically improves readability.
Understanding Jackson and JSON Formatting
Jackson is a high-performance, widely-used Java library for handling JSON data. It offers various features, including serialization (converting Java objects to JSON) and deserialization (converting JSON to Java objects). One of its most useful capabilities is the ability to format JSON output for better readability. When you convert JSON string to pretty print JSON using Jackson, you’re leveraging its ObjectMapper class with specific configurations to achieve a well-formatted output with indentation and line breaks. This is particularly helpful when you need to inspect JSON data for debugging or when presenting it in a user-friendly manner.
The ObjectMapper class is the core component for JSON processing in Jackson. It provides methods for reading and writing JSON data. To format JSON, you typically use methods like writeValueAsString() along with configuration settings that tell Jackson to indent the output. Pretty printing involves adding indentation and line breaks to make the JSON structure clearer. For instance, without formatting, a JSON string might look like {“name”:“John”,“age”:30,“city”:“New York”}. With pretty printing, it would be transformed into a more readable format, such as:
{ "name" : "John", "age" : 30, "city" : "New York" }
According to a study by Oracle, Jackson is one of the most popular JSON processing libraries due to its speed and flexibility [Oracle]. Using Jackson to convert JSON string to pretty print JSON can significantly improve the development workflow by making JSON data more accessible and understandable.
Steps to Convert JSON String to Pretty Print JSON using Jackson
Converting a JSON string to a pretty-printed format using Jackson involves a few key steps. First, you need to add the Jackson library to your project. This can be done by including the appropriate Maven or Gradle dependency. Once the library is set up, you can use the ObjectMapper class to parse the JSON string and then write it back out in a formatted way. The key is to configure the ObjectMapper to use pretty printing. Here’s a step-by-step guide:
- Add Jackson Dependency: Include the Jackson core dependency in your project’s build file. For Maven, this would involve adding the following to your pom.xml: ```
com.fasterxml.jackson.core jackson-databind 2.13.0 - Create ObjectMapper Instance: Instantiate the ObjectMapper class, which will handle the JSON processing.
- Read JSON String: Use the readValue() method of the ObjectMapper to parse the JSON string into a Java object (e.g., JsonNode, Map, or a custom class).
- Configure Pretty Printing: Enable pretty printing by setting the SerializationFeature.INDENT_OUTPUT feature on the ObjectMapper.
- Write Formatted Output: Use the writeValueAsString() method to convert the Java object back into a JSON string, now with proper indentation and line breaks.
Here’s an example of how you can implement this in Java:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; public class JsonFormatter { public static void main(String[] args) throws Exception { String jsonString = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}"; ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); Object json = mapper.readValue(jsonString, Object.class); String prettyJson = mapper.writeValueAsString(json); System.out.println(prettyJson); } }
This code snippet demonstrates how to convert JSON string to pretty print JSON using Jackson. It first creates an ObjectMapper, enables indentation, reads the JSON string into a generic object, and then writes it back out as a pretty-printed string. This process ensures that the output is formatted for easy reading.
Advanced Techniques for JSON Formatting with Jackson
Beyond the basic steps, Jackson offers advanced techniques to customize JSON formatting. These techniques can be useful for handling complex scenarios or specific formatting requirements. For example, you can configure how null values are handled, specify custom indentation characters, or use custom serializers and deserializers to control how specific objects are formatted. Understanding these advanced options allows you to fine-tune the JSON output to meet your exact needs.
One advanced technique involves using the DefaultPrettyPrinter class to further customize the output. This class allows you to specify the indentation character, line separator, and other formatting options. You can create a custom DefaultPrettyPrinter instance and configure it to use tabs instead of spaces for indentation, or to use a different line separator character. Here’s an example:
import com.fasterxml.jackson.core.util.DefaultPrettyPrinter; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; public class CustomJsonFormatter { public static void main(String[] args) throws Exception { String jsonString = "{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}"; ObjectMapper mapper = new ObjectMapper(); mapper.enable(SerializationFeature.INDENT_OUTPUT); DefaultPrettyPrinter prettyPrinter = new DefaultPrettyPrinter(); prettyPrinter.indentWith(new DefaultPrettyPrinter.FixedSpaceIndenter()); mapper.setDefaultPrettyPrinter(prettyPrinter); Object json = mapper.readValue(jsonString, Object.class); String prettyJson = mapper.writeValueAsString(json); System.out.println(prettyJson); } }
Another useful technique is to use Jackson’s annotations to control how Java objects are serialized into JSON. Annotations like @JsonProperty, @JsonIgnore, and @JsonInclude allow you to customize the field names, exclude fields from serialization, and control when null values are included in the output. These annotations provide a fine-grained level of control over the JSON formatting process. For more details on Jackson annotations, refer to the official Jackson documentation [Jackson Annotations].
Here are some key points to remember when using advanced formatting techniques:
- Customize indentation using DefaultPrettyPrinter.
- Use Jackson annotations for fine-grained control over serialization.
- Handle null values according to your application’s requirements.
Best Practices and Common Pitfalls
When you convert JSON string to pretty print JSON using Jackson, following best practices can help you avoid common pitfalls and ensure your code is efficient and maintainable. One important practice is to handle exceptions properly. JSON parsing and formatting operations can throw exceptions if the JSON string is invalid or if there are issues with the ObjectMapper configuration. Wrapping your code in try-catch blocks and handling these exceptions gracefully can prevent your application from crashing and provide useful error messages.
Another best practice is to reuse the ObjectMapper instance whenever possible. Creating a new ObjectMapper for each JSON processing operation can be inefficient, especially in high-performance applications. Instead, create a single ObjectMapper instance and reuse it throughout your application. This can significantly improve performance by reducing the overhead of creating and initializing the object mapper.
Here’s a featured snippet-optimized paragraph: When working with JSON, ensure your input JSON string is valid. Invalid JSON can lead to parsing errors and unexpected behavior. Use online JSON validators to check your JSON strings before processing them with Jackson. Validating your JSON beforehand ensures smoother processing and helps prevent runtime errors, allowing you to convert JSON string to pretty print JSON without issues. A well-formed JSON structure is crucial for successful formatting.
Common pitfalls to avoid include:
- Not handling exceptions when parsing or formatting JSON.
- Creating a new ObjectMapper instance for each operation.
- Ignoring the importance of valid JSON input.
According to a Stack Overflow survey, exception handling is a critical aspect of software development [Stack Overflow Survey 2023]. Implementing proper exception handling can significantly improve the reliability and robustness of your JSON processing code. Also, consider using a JSON linter as part of your development process to catch invalid JSON early on. Using an internal link will improve SEO, check out the great options available here.
- **Q: How do I add the Jackson dependency to my Maven project?**
- A: Add the following dependency to your pom.xml file: ```
```com.fasterxml.jackson.core jackson-databind 2.13.0 - **Q: Can I use tabs instead of spaces for indentation?**
- A: Yes, you can customize the indentation character using the DefaultPrettyPrinter class.
- **Q: How do I handle null values in the JSON output?**
- A: Use Jackson annotations like @JsonInclude to control when null values are included in the output.
- **Q: Why is my JSON not formatting correctly?**
- A: Ensure that you have enabled the SerializationFeature.INDENT\_OUTPUT feature on the ObjectMapper and that your input JSON is valid.
{"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?
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.