168

Right now I have an instance of org.fasterxml.jackson.databind.ObjectMapper and would like to get a String with pretty JSON. All of the results of my Google searches have come up with Jackson 1.x ways of doing this and I can't seem to find the proper, non-deprecated way of doing this with 2.2. Even though I don't believe that code is absolutely necessary for this question, here's what I have right now:

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
System.out.println("\n\n----------REQUEST-----------");
StringWriter sw = new StringWriter();
mapper.writeValue(sw, jsonObject);
// Want pretty version of sw.toString() here
Anthony Atkinson
  • 3,101
  • 3
  • 20
  • 22

8 Answers8

309

You can enable pretty-printing by setting the SerializationFeature.INDENT_OUTPUT on your ObjectMapper like so:

mapper.enable(SerializationFeature.INDENT_OUTPUT);
gregwhitaker
  • 13,124
  • 7
  • 69
  • 78
  • 1
    I have also tried this but it seems that `SerializationConfig` is resolved but `SerializationConfig.Feature` is not. This seems to be another method of pretty printing that's also deprecated unless I'm missing something. There is a `Feature` class that's separated out on its own, but does not have an `INDENT_OUTPUT` constant inside. :( – Anthony Atkinson Jul 12 '13 at 15:02
  • Excellent! I'd love to know how you found that ;) – Anthony Atkinson Jul 12 '13 at 15:15
  • 2
    I looked at one of my projects, but it appears that it is also here: https://github.com/FasterXML/jackson-databind under "Commonly used Features" – gregwhitaker Jul 12 '13 at 15:18
  • The relevant import needed is import com.fasterxml.jackson.databind.{SerializationFeature, ObjectMapper} – dgh Aug 26 '13 at 06:49
  • 2
    on 2.2.1 this is what it took for me: import org.codehaus.jackson.map.SerializationConfig.Feature; mapper.enable(Feature.INDENT_OUTPUT); – harschware Dec 16 '13 at 20:31
  • This did not work for with the 2.5.3 api, I've added the updated api call in my answer – Rian May 23 '15 at 09:45
  • ObjectMapper mapper = new ObjectMapper(); mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject)); – Learn More Jun 14 '22 at 09:38
52

According to mkyong, the magic incantation is defaultPrintingWriter to pretty print JSON:

Newer versions:

System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonInstance));

Older versions:

System.out.println(mapper.defaultPrettyPrintingWriter().writeValueAsString(jsonInstance));

Seems I jumped the gun a tad quickly. You could try gson, whose constructor supports pretty-printing:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);

Hope this helps...

NicolasMoise
  • 7,261
  • 10
  • 44
  • 65
hd1
  • 33,938
  • 5
  • 80
  • 91
  • 1
    I found this article and was disappointed to find that this is one of those deprecated ways of pretty printing. `defaultPrettyPrintingWriter()` is no longer available (even as a deprecated method) on the `ObjectMapper` class. – Anthony Atkinson Jul 12 '13 at 14:39
  • I was actually thinking about doing this, but my application is already heavily Jackson-oriented and all of the functionality is actually complete. The web application server that this will be hosted on is already being taxed pretty heavily, and I wouldn't want to load extra libraries simply for logging requests and responses. I will definitely up-vote your answer, though. – Anthony Atkinson Jul 12 '13 at 14:59
  • 8
    @AnthonyAtkinson in Jackson 2.3 there is a method `ObjectMapper.writerWithDefaultPrettyPrinter()` – matt b Jan 21 '14 at 22:41
39

The jackson API has changed:

new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(new HashMap<String, Object>());
Rian
  • 1,243
  • 2
  • 17
  • 22
  • 3
    It’s still possible (with Jackson 2.7.6) to use `new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writer().writeValueAsString(new HashMap());`. You just have to make sure to use the writer you get from the configured `ObjectMapper`. – Martin Jul 11 '17 at 14:04
4

the IDENT_OUTPUT did not do anything for me, and to give a complete answer that works with my jackson 2.2.3 jars:

public static void main(String[] args) throws IOException {

byte[] jsonBytes = Files.readAllBytes(Paths.get("C:\\data\\testfiles\\single-line.json"));

ObjectMapper objectMapper = new ObjectMapper();

Object json = objectMapper.readValue( jsonBytes, Object.class );

System.out.println( objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString( json ) );
}
Stan Towianski
  • 411
  • 2
  • 6
0

If you'd like to turn this on by default for ALL ObjectMapper instances in a process, here's a little hack that will set the default value of INDENT_OUTPUT to true:

val indentOutput = SerializationFeature.INDENT_OUTPUT
val defaultStateField = indentOutput.getClass.getDeclaredField("_defaultState")
defaultStateField.setAccessible(true)
defaultStateField.set(indentOutput, true)
Graham Lea
  • 5,797
  • 3
  • 40
  • 55
0

if you are using spring and jackson combination you can do it as following. I'm following @gregwhitaker as suggested but implementing in spring style.

<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
    <property name="dateFormat">
        <bean class="java.text.SimpleDateFormat">
            <constructor-arg value="yyyy-MM-dd" />
            <property name="lenient" value="false" />
        </bean>
    </property>
    <property name="serializationInclusion">
        <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">
            NON_NULL
        </value>
    </property>
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref bean="objectMapper" />
    </property>
    <property name="targetMethod">
        <value>enable</value>
    </property>
    <property name="arguments">
        <value type="com.fasterxml.jackson.databind.SerializationFeature">
            INDENT_OUTPUT
        </value>
    </property>
</bean>
MohanaRao SV
  • 1,117
  • 1
  • 8
  • 22
0

If others who view this question only have a JSON string (not in an object), then you can put it into a HashMap and still get the ObjectMapper to work. The result variable is your JSON string.

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;

// Pretty-print the JSON result
try {
    ObjectMapper objectMapper = new ObjectMapper();
    Map<String, Object> response = objectMapper.readValue(result, HashMap.class);
    System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(response));
} catch (JsonParseException e) {
    e.printStackTrace();
} catch (JsonMappingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} 
Azurespot
  • 3,066
  • 3
  • 45
  • 73
-8

Try this.

 objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);
Mayank Jain
  • 5,663
  • 7
  • 32
  • 65
Nagappa L M
  • 1,452
  • 4
  • 20
  • 33