关于Java:从Jackson 2.2的ObjectMapper漂亮地打印JSON

Pretty printing JSON from Jackson 2.2's ObjectMapper

现在,我有一个org.fasterxml.jackson.databind.ObjectMapper实例,并希望使用漂亮的JSON获得一个String。 Google搜索的所有结果都提供了Jackson 1.x的实现方法,而我似乎找不到使用2.2的正确,不建议使用的方法。 即使我不认为代码对于这个问题绝对必要,这也是我现在所拥有的:

1
2
3
4
5
6
7
8
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
System.out.println("

----------REQUEST-----------"
);
StringWriter sw = new StringWriter();
mapper.writeValue(sw, jsonObject);
// Want pretty version of sw.toString() here

您可以通过在ObjectMapper上设置SerializationFeature.INDENT_OUTPUT来启用漂亮打印,如下所示:

1
mapper.enable(SerializationFeature.INDENT_OUTPUT);


根据mkyong的说法,魔咒是defaultPrintingWriter以漂亮地打印JSON:

较新的版本:

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

旧版本:

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

看来我快点跳了枪。您可以尝试gson,其构造函数支持漂亮的打印:

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

希望这可以帮助...


杰克逊API已更改:

1
2
3
4
new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(new HashMap<String, Object>());


IDENT_OUTPUT并没有为我做任何事情,并且给出了与我的杰克逊2.2.3罐子一起工作的完整答案:

1
2
3
4
5
6
7
8
9
10
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 ) );
}

如果查看此问题的其他人仅具有JSON字符串(不在对象中),则可以将其放入HashMap并仍然使ObjectMapper起作用。 result变量是您的JSON字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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();
}

如果您使用弹簧和杰克逊组合,则可以按照以下步骤进行操作。我按照建议遵循@gregwhitaker,但以春季风格实施。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<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>


如果您想默认为一个进程中的所有ObjectMapper实例启用此功能,则可以通过以下小技巧将INDENT_OUTPUT的默认值设置为true:

1
2
3
4
val indentOutput = SerializationFeature.INDENT_OUTPUT
val defaultStateField = indentOutput.getClass.getDeclaredField("_defaultState")
defaultStateField.setAccessible(true)
defaultStateField.set(indentOutput, true)

尝试这个。

1
 objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);