杰克逊2.2的ObjectMapper如何漂亮地打印JSON

169

我现在有一个org.fasterxml.jackson.databind.ObjectMapper的实例,想要得到一个漂亮的JSON字符串。我的所有谷歌搜索结果都是使用Jackson 1.x版本的方式,我似乎找不到用2.2版本正确且未弃用的方法来做到这一点。虽然我不认为代码对于这个问题绝对必要,但是这是我目前拥有的:

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
8个回答

312

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

mapper.enable(SerializationFeature.INDENT_OUTPUT);

1
我也尝试过这个,但似乎SerializationConfig被解析了,但SerializationConfig.Feature没有。除非我漏掉了什么,否则这似乎是另一种已弃用的漂亮打印方法。有一个单独的Feature类,但内部没有INDENT_OUTPUT常量。 :( - Anthony Atkinson
2
我查看了我的一个项目,但似乎它也在这里:https://github.com/FasterXML/jackson-databind 的“常用功能”下。 - gregwhitaker
需要导入的相关内容是 import com.fasterxml.jackson.databind.{SerializationFeature, ObjectMapper} - dgh
2
在2.2.1版本中,这是我的代码:import org.codehaus.jackson.map.SerializationConfig.Feature;mapper.enable(Feature.INDENT_OUTPUT); - harschware
这在2.5.3 API上不起作用,我已经在我的答案中添加了更新的API调用。 - Rian
显示剩余2条评论

52

根据mkyong的说法,让JSON内容更易读的魔法咒语是defaultPrintingWriterpretty print JSON

更新版本:

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

旧版本:

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

看起来我有点过于心急了。您可以尝试gson,它的构造函数支持美观的打印输出:

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

希望这能有所帮助...


1
我发现了这篇文章,但很失望地发现这是一种已经被弃用的 pretty printing 方法。defaultPrettyPrintingWriter()ObjectMapper 类上已不再可用(即使作为一个弃用的方法)。 - Anthony Atkinson
我其实也考虑过这个,但我的应用程序已经非常依赖于Jackson,并且所有的功能都已经完成了。这个Web应用程序服务器已经被很大程度上占用了,我不想为了记录请求和响应而加载额外的库。不过我一定会给你的答案点赞的。 - Anthony Atkinson
8
在Jackson 2.3中,有一个方法叫做 ObjectMapper.writerWithDefaultPrettyPrinter() - matt b

39

jackson API 已经发生了变化:

new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(new HashMap<String, Object>());

3
在使用Jackson 2.7.6时,仍然可以使用new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writer().writeValueAsString(new HashMap<String, Object>());。只需确保使用配置的ObjectMapper获取的writer即可。 - Martin

4
IDENT_OUTPUT 对我没有任何作用,为了给出一个完整的答案并且适用于我的 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。希望我能给你一百万个赞! - Ajay Kumar

0
如果你想在一个进程中默认开启所有ObjectMapper实例的此功能,这里有一个小技巧可以将INDENT_OUTPUT的默认值设置为true:
val indentOutput = SerializationFeature.INDENT_OUTPUT
val defaultStateField = indentOutput.getClass.getDeclaredField("_defaultState")
defaultStateField.setAccessible(true)
defaultStateField.set(indentOutput, true)

0
如果你正在使用Spring和Jackson的组合,你可以按照以下方式来做。我正在遵循@gregwhitaker的建议,但是以Spring的风格来实现。

<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>

0
如果其他人只有一个JSON字符串(而不是对象),那么您可以将其放入HashMap中,仍然可以让ObjectMapper工作。变量“result”是您的JSON字符串。
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();
} 

-7

试试这个。

 objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);

14
在7个月后复制所选答案并不是真正有用的。 - Igor Rodriguez
1
可能会对某些人有所帮助,正如我在一行中提到的那样,分享我所知道的让我感觉很好。 - Nagappa L M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接