Java中的Pretty-Print JSON


Answers:


284

GSON可以通过一种很好的方式做到这一点:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);

1
好吧,我包括了将字符串解析为JsonElement的代码,通常您已经拥有使用JSON数据所做的先前工作。但是我想在这里包括它,以使用法更清晰。
Ray Hulha 2014年

由于这个答案帮助了我。我在下面添加了代码,如果需要的话,可以将该语句缩小为更少的行。public String prettifyJson(String json){JsonElement jsonElement = new JsonParser()。parse(json); 返回新的GsonBuilder()。setPrettyPrinting()。create()。toJson(jsonElement); }
ahmad 2015年

2
无需附加库就可以回答OP的问题,因为您可以直接访问Rhino中嵌入的JSON解析器(JDK 1.7及更高版本)。我认为不希望将库添加到项目中只是为了格式化一些调试输出。 scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
艾格尼丝

1
与org.json替代方法相比,GSON的漂亮打印方式在转换后可保持元素顺序不变。
艾登·K

1
感谢指向的指针GsonBuilder,因为我一直在使用,所以我gson.toJson(object)只需要将实例化从更改Gson gson = new Gson();Gson gson = new GsonBuilder().setPrettyPrinting().create(); ,代码就可以继续工作,但是可以漂亮地打印对象而不是一行。
cptully

153

我使用了org.json内置方法来漂亮地打印数据。

JSONObject json = new JSONObject(jsonString); // Convert text to object
System.out.println(json.toString(4)); // Print it with specified indentation

JSON中字段的顺序是每个定义随机的。特定顺序受解析器实现的约束。


7
我也更喜欢这种解决方案,因为您不需要像其他答案所建议的那样导入其他依赖项。
gdrt '17

3
缺少重要的导入-导入org.json.JSONObject;
MasterJoe2 '18 -10-19

无论如何,没有按随机顺序排列的字段,我想要按添加它们的顺序排列吗?
Thomas Adrian

@ThomasAdrian使用org.json.JSONObject是不可能的。
Raghu Kiran

Underscore-java在格式化json时保持属性顺序。
Valentyn Kolesnikov

37

尽管我不知道您是否要从正在使用的库中切换出来,但GSON似乎支持这一点。

从用户指南中:

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

4
GSON的问题很复杂,而json-simple要容易得多。
mabuzer 2010年

1
一年多来我一直没有考虑这个问题,但是如果您愿意稍稍修改一下源代码,则code.google.com/p/json-simple/issues/detail?id=22上有一些信息通过漂亮的打印增强json-simple。
布法罗布法罗2011年

只是字符串而没有任何漂亮的打印格式:(
樱桃

它使用\ r \ n打印字符串
Stone Jack

谢谢。toString()在一行中覆盖:new GsonBuilder()。setPrettyPrinting()。create()。toJson(this);
KeepAtIt

30

使用Jackson(com.fasterxml.jackson.databind):

ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject))

来自:如何启用漂亮的打印JSON输出(杰克逊)

我知道答案中已经有此内容,但是我想在这里单独编写它,因为有可能,您已经将Jackson当作依赖项,因此您所需要的只是一排额外的代码


21

如果您使用Java API进行JSON处理(JSR-353),则可以JsonGenerator.PRETTY_PRINTING在创建时指定该属性JsonGeneratorFactory

以下示例最初发布在我的博客文章中

import java.util.*;
import javax.json.Json;
import javax.json.stream.*;

Map<String, Object> properties = new HashMap<String, Object>(1);
properties.put(JsonGenerator.PRETTY_PRINTING, true);
JsonGeneratorFactory jgf = Json.createGeneratorFactory(properties);
JsonGenerator jg = jgf.createGenerator(System.out);

jg.writeStartObject()                    // {
    .write("name", "Jane Doe")           //    "name":"Jane Doe",
    .writeStartObject("address")         //    "address":{
        .write("type", 1)                //        "type":1,
        .write("street", "1 A Street")   //        "street":"1 A Street",
        .writeNull("city")               //        "city":null,
        .write("verified", false)        //        "verified":false
    .writeEnd()                          //    },
    .writeStartArray("phone-numbers")    //    "phone-numbers":[
        .writeStartObject()              //        {
            .write("number", "555-1111") //            "number":"555-1111",
            .write("extension", "123")   //            "extension":"123"
        .writeEnd()                      //        },
        .writeStartObject()              //        {
            .write("number", "555-2222") //            "number":"555-2222",
            .writeNull("extension")      //            "extension":null
        .writeEnd()                      //        }
    .writeEnd()                          //    ]
.writeEnd()                              // }
.close();

18

我的情况是我的项目使用了不支持漂亮打印的旧式(非JSR)JSON解析器。但是,我需要生成漂亮的JSON样本。只要您使用的是Java 7及更高版本,就可以在无需添加任何额外库的情况下实现:

ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine scriptEngine = manager.getEngineByName("JavaScript");
scriptEngine.put("jsonString", jsonStringNoWhitespace);
scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
String prettyPrintedJson = (String) scriptEngine.get("result");

3
这太棒了,使用js引擎来做,就这么简单
med116

如果您在意,请警告:ScriptEngineManager不是API。
nclark

18

GSON在一行中进行漂亮的打印:

System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(jsonString)));

除了内联之外,这等效于已接受的答案


8

现有的大多数答案要么取决于某些外部库,要么需要特殊的Java版本。这是一个简单的代码,仅使用常规Java API(可在Java 7中获得更高版本;尽管未尝试使用旧版本)来漂亮地打印JSON字符串。

基本思想是基于JSON中的特殊字符来简化格式。例如,如果观察到'{'或'[',则代码将创建新行并增加缩进级别。

免责声明:我仅在一些简单的JSON情况(基本键值对,列表,嵌套JSON)中对此进行了测试,因此对于更通用的JSON文本(例如带引号的字符串值或特殊字符(\ n,\ t等)。

/**
 * A simple implementation to pretty-print JSON file.
 *
 * @param unformattedJsonString
 * @return
 */
public static String prettyPrintJSON(String unformattedJsonString) {
  StringBuilder prettyJSONBuilder = new StringBuilder();
  int indentLevel = 0;
  boolean inQuote = false;
  for(char charFromUnformattedJson : unformattedJsonString.toCharArray()) {
    switch(charFromUnformattedJson) {
      case '"':
        // switch the quoting status
        inQuote = !inQuote;
        prettyJSONBuilder.append(charFromUnformattedJson);
        break;
      case ' ':
        // For space: ignore the space if it is not being quoted.
        if(inQuote) {
          prettyJSONBuilder.append(charFromUnformattedJson);
        }
        break;
      case '{':
      case '[':
        // Starting a new block: increase the indent level
        prettyJSONBuilder.append(charFromUnformattedJson);
        indentLevel++;
        appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        break;
      case '}':
      case ']':
        // Ending a new block; decrese the indent level
        indentLevel--;
        appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        prettyJSONBuilder.append(charFromUnformattedJson);
        break;
      case ',':
        // Ending a json item; create a new line after
        prettyJSONBuilder.append(charFromUnformattedJson);
        if(!inQuote) {
          appendIndentedNewLine(indentLevel, prettyJSONBuilder);
        }
        break;
      default:
        prettyJSONBuilder.append(charFromUnformattedJson);
    }
  }
  return prettyJSONBuilder.toString();
}

/**
 * Print a new line with indention at the beginning of the new line.
 * @param indentLevel
 * @param stringBuilder
 */
private static void appendIndentedNewLine(int indentLevel, StringBuilder stringBuilder) {
  stringBuilder.append("\n");
  for(int i = 0; i < indentLevel; i++) {
    // Assuming indention using 2 spaces
    stringBuilder.append("  ");
  }
}

初读时,我对这个建议感到非常不满,但是阅读完所有答案后,这是最好的解决方案。至少,如果它仅用于某些调试输出,并且您不想拖入依赖项,则可能需要稍后再删除。非常感谢你!
user2081279

7

一行:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

json-io libray(https://github.com/jdereg/json-io)是一个小型(75K)库,除JDK外没有其他依赖项。

除了打印精美的JSON之外,您还可以将Java对象(带有循环的整个Java对象图)序列化为JSON,并读入它们。


7

现在,这可以通过JSONLib库实现:

http://json-lib.sourceforge.net/apidocs/net/sf/json/JSONObject.html

如果(且仅)使用重载toString(int indentationFactor)方法而不是标准toString()方法。

我已经在以下版本的API上对此进行了验证:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>

3
尽管此库可能有助于回答问题,但最好提供一个示例说明该库如何适用于该问题,并提供一些有关其工作原理的解释
Francesco Menzani 2015年

1
好的,谢谢您的反馈。尽管确实记得,但像我这样的人是志愿者,没有获得提供保证质量标准服务的报酬。我们的时间有限,因为我们经常在工作中或有家庭职责。这就是为什么“编辑”可供读者使用的原因,因此我们可以使彼此的帖子更有帮助。
Sridhar Sarnobat,2016年

6

遵循JSON-P 1.0规范(JSR-353),给定JsonStructureJsonObjectJsonArray)的最新解决方案可能如下所示:

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

import javax.json.Json;
import javax.json.JsonStructure;
import javax.json.JsonWriter;
import javax.json.JsonWriterFactory;
import javax.json.stream.JsonGenerator;

public class PrettyJson {

    private static JsonWriterFactory FACTORY_INSTANCE;

    public static String toString(final JsonStructure status) {

        final StringWriter stringWriter = new StringWriter();

        final JsonWriter jsonWriter = getPrettyJsonWriterFactory()
                .createWriter(stringWriter);

        jsonWriter.write(status);
        jsonWriter.close();

        return stringWriter.toString();
    }

    private static JsonWriterFactory getPrettyJsonWriterFactory() {
        if (null == FACTORY_INSTANCE) {
            final Map<String, Object> properties = new HashMap<>(1);
            properties.put(JsonGenerator.PRETTY_PRINTING, true);
            FACTORY_INSTANCE = Json.createWriterFactory(properties);
        }
        return FACTORY_INSTANCE;
    }

}


5

您可以像下面一样使用Gson

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonString = gson.toJson(object);

Gson发布的JSON漂亮图片

另外,您可以像下面一样使用Jackson

ObjectMapper mapper = new ObjectMapper();
String perttyStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);

摘自Java的Pretty print JSON(Jackson)

希望对您有所帮助!


4

使用org json。参考链接

JSONObject jsonObject = new JSONObject(obj);
String prettyJson = jsonObject.toString(4);

使用Gson。参考链接

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(obj);

使用杰克逊。参考链接

ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String json = mapper.writeValueAsString(obj);

使用Genson。参考链接

Genson prettyGenson = new GensonBuilder().useIndentation(true).create();
String prettyJson = prettyGenson.serialize(obj);

1

使用Jackson,这对我有用:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)

mapper是哪里来的?
Sertage


-2

Underscore-java具有静态方法U.formatJson(json)。支持五种格式类型:2、3、4,制表符和紧凑格式。我是该项目的维护者。现场例子

import com.github.underscore.lodash.U;

import static com.github.underscore.lodash.Json.JsonStringBuilder.Step.TABS;
import static com.github.underscore.lodash.Json.JsonStringBuilder.Step.TWO_SPACES;

public class MyClass {

    public static void main(String args[]) {
        String json = "{\"Price\": {"
        + "    \"LineItems\": {"
        + "        \"LineItem\": {"
        + "            \"UnitOfMeasure\": \"EACH\", \"Quantity\": 2, \"ItemID\": \"ItemID\""
        + "        }"
        + "    },"
        + "    \"Currency\": \"USD\","
        + "    \"EnterpriseCode\": \"EnterpriseCode\""
        + "}}";
        System.out.println(U.formatJson(json, TWO_SPACES)); 
        System.out.println(U.formatJson(json, TABS)); 
    }
}

输出:

{
  "Price": {
    "LineItems": {
      "LineItem": {
        "UnitOfMeasure": "EACH",
        "Quantity": 2,
        "ItemID": "ItemID"
      }
    },
    "Currency": "USD",
    "EnterpriseCode": "EnterpriseCode"
  }
}
{
    "Price": {
        "LineItems": {
            "LineItem": {
                "UnitOfMeasure": "EACH",
                "Quantity": 2,
                "ItemID": "ItemID"
            }
        },
        "Currency": "USD",
        "EnterpriseCode": "EnterpriseCode"
    }
}    
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.