Java中的漂亮打印JSON

我使用,我需要漂亮地打印JSON数据(使其更易于阅读)。

我还没能在那个库中找到这个功能。 这通常是如何实现的?< / p >

354199 次浏览

GSON似乎支持这一点,尽管我不知道你是否想从你正在使用的库切换。

来自用户指南:

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

谷歌的GSON可以以一种很好的方式做到这一点:

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

或者因为现在推荐使用来自JsonParser的静态解析方法,你也可以使用这个代替:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonElement je = JsonParser.parseString​(uglyJsonString);
String prettyJsonString = gson.toJson(je);

下面是导入语句:

import com.google.gson.*;

这是Gradle的依赖项:

implementation 'com.google.code.gson:gson:2.8.7'

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

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

JSON中每个定义的字段顺序是随机的。具体的顺序取决于解析器的实现。

在JSONLib中,你可以这样使用:

String jsonTxt = JSONUtils.valueToString(json, 8, 4);

Javadoc:

 ></a></p></div>
                                                                            </div>
                                </div>
                            </div>
                        </div>
                                                <div class=

在一行中使用GSON漂亮地打印:

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

除了内联,它等价于公认的答案

如果你正在使用JSON处理(JSR-353)实现的Java API,那么你可以在创建JsonGeneratorFactory时指定JsonGenerator.PRETTY_PRINTING属性。

下面的例子最初发表在我的博客上。

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();

现在这可以通过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>

我的情况是我的项目使用了不支持漂亮打印的遗留(非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");

根据JSON-P 1.0规范(jsr - 353),对于给定的JsonStructure (JsonObjectJsonArray),当前的解决方案可能是这样的:

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


}

你可以像下面这样使用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 JSON打印(Jackson)

希望这对你有所帮助!

与Jackson (com.fasterxml.jackson.databind):

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

来自:如何启用漂亮的JSON输出(Jackson)

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

这招对我很管用,用了杰克逊的话:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)

大多数现有的答案要么依赖于一些外部库,要么需要一个特殊的Java版本。下面是一个简单的代码来漂亮地打印一个JSON字符串,只使用一般的Java api(在Java 7中更高;虽然还没有尝试过旧版本)。

基本思想是基于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("  ");
}
}

Underscore-java有静态方法U.formatJson(json)。 支持5种格式类型:2,3,4,制表符和压缩。生活的例子 < / p >

import com.github.underscore.U;


import static com.github.underscore.Json.JsonStringBuilder.Step.TABS;
import static com.github.underscore.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"
}
}

你可以使用小型json

String jsonstring = ....;
JsonValue json = JsonParser.parse(jsonstring);
String jsonIndendedByTwoSpaces = json.toPrettyString("  ");

使用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);

使用javax.json。参考链接

Map<String, Boolean> config = new HashMap<>();


config.put(JsonGenerator.PRETTY_PRINTING, true);


JsonWriterFactory writerFactory = Json.createWriterFactory(config);
Writer writer = new StringWriter();


writerFactory.createWriter(writer).write(jsonObject);


String json = writer.toString();

使用Moshi库。参考链接

String json = jsonAdapter.indent("  ").toJson(emp1);

(或)

Buffer buffer = new Buffer();
JsonWriter jsonWriter = JsonWriter.of(buffer);
jsonWriter.setIndent("   ");


jsonAdapter.toJson(jsonWriter, emp1);


json = buffer.readUtf8();

更新:new JsonParser().parse(...)@deprecated


基于Gson 2.8.6的javadoc:

不需要实例化这个类,而是使用静态方法。

JsonParser静态方法:

JsonParser.parseString​(jsonString);
JsonParser.parseReader​(reader);

包:

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParser;

例子:

private Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static String getPerfectJSON(String unformattedJSON) {
String perfectJSON = GSON.toJson(JsonParser.parseString(unformattedJSON));
return perfectJSON;
}

谷歌Gson依赖使用Maven:

<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>

参考:

我还使用org.json.simple包。我只是简单地编写了格式化程序,但由于在我编写的程序中的JSON对象中没有空值、数字或布尔值,所以我只编写了字符串、对象和数组。如果有人感兴趣,就让它成为公共领域。欢迎您添加缺少的数据类型(在注释“it's a string”中)。此外,您可以添加缩进作为参数,而我的只有两个空格。请在您测试了您的改进后重新分享。

使用: printJsonObject(jsonObject, "");

功能:

    public static void printJsonObject(JSONObject object, String prefix) {
boolean notFirst = false;
System.out.println(prefix + "{");
for (Object key : object.keySet()) {
if (notFirst) {
System.out.println(", ");
}
notFirst = true;
Object value = object.get(key);
System.out.print(prefix + "  " + "\"" + key + "\"" + ": ");
if (value instanceof JSONObject) {
printJsonObject((JSONObject) value, prefix + "  ");
} else if (value instanceof JSONArray) {
printJsonArray((JSONArray) value, prefix + "  ");
} else {  // it's a string
System.out.print("\"" + value + "\"");
}
}
System.out.println("");
System.out.print(prefix + "}");
}


public static void printJsonArray(JSONArray array, String prefix) {
boolean notFirst = false;
System.out.println("[");
for (Object item : array) {
if (notFirst) {
System.out.println(", ");
}
notFirst = true;
if (item instanceof JSONObject) {
printJsonObject((JSONObject) item, prefix + "  ");
} else if (item instanceof JSONArray) {
printJsonArray((JSONArray) item, prefix + "  ");
} else {
System.out.print(prefix + "  " + "\"" + item + "\"");
}
}
System.out.println("");
System.out.print(prefix + "]");
}


所以我也喜欢json-simple库,并查看了漂亮的打印它的输出。不幸的是,虽然它是这是一个公开的问题,但我找不到它的任何代码。所以我想我应该试一试,这是我想出的(使用他们自己的来源)..

public class JsonPrinter {
  

  

  

public static String toJson(Map<?,?> map) {
StringBuilder out = new StringBuilder(32);
new JsonPrinter(out).print(map);
return out.toString();
}
  

  

public static String toJson(List<?> list) {
StringBuilder out = new StringBuilder(32);
new JsonPrinter(out).print(list);
return out.toString();
}
  

  

  

  

  

  

  

private final Appendable out;
private final String indentUnit;
private final String newLine;
  

  

private int indents;
  

public JsonPrinter(Appendable out) {
this(out, "  ", System.lineSeparator());
}


/**
*
*/
public JsonPrinter(Appendable out, String indentUnit, String newLine) {
this.out = Objects.requireNonNull(out, "null out");
this.indentUnit = Objects.requireNonNull(indentUnit, "null indentUnit");
this.newLine = Objects.requireNonNull(newLine, "null newLine");
    

if (!indentUnit.isBlank())
throw new IllegalArgumentException(
"indentUnit must be a blank sequence (quoted): '" + indentUnit + "'");
if (!"\r\n".equals(newLine) && ! "\n".equals(newLine))
throw new IllegalArgumentException(
"unrecognized newLine (quoted): '" + newLine + "'");
}
  

  

public void print(List<?> list) throws UncheckedIOException {
try {
assert indents == 0;
printImpl(list);
assert indents == 0;
} catch (IOException iox) {
throw new UncheckedIOException("on print(List): " + list, iox);
}
}
  

  

public void print(Map<?,?> map) throws UncheckedIOException {
try {
assert indents == 0;
printImpl(map);
assert indents == 0;
} catch (IOException iox) {
throw new UncheckedIOException("on print(Map): " + map, iox);
}
}
  

  

protected void printImpl(List<?> list) throws IOException {
if (list == null) {
out.append("null");
return;
}
    

    

boolean first = true;
var iter = list.iterator();
    

open('[');
while (iter.hasNext()) {
if (first)
first = false;
else
out.append(',');
      

out.append(newLine);
appendIndents();
      

appendValue(iter.next());
}
close(']');
}
  

  

protected void printImpl(Map<?, ?> map) throws IOException {
if (map == null) {
out.append("null");
return;
}
    

    

boolean first = true;
var iter = map.entrySet().iterator();
    

open('{');
while (iter.hasNext()) {
if (first)
first = false;
else
out.append(',');
      

out.append(newLine);
appendIndents();
      

var entry = iter.next();
print(entry.getKey().toString(), entry.getValue());
}
close('}');
}
  

  

private void open(char c) throws IOException {
out.append(c);
++indents;
}
  

private void close(char c) throws IOException {
--indents;
out.append(newLine);
appendIndents();
out.append(c);
}
  

private void appendIndents() throws IOException {
for (int count = indents; count-- > 0; )
out.append(indentUnit);
}
  

  

  

private void print(String key, Object value) throws IOException {
out.append('"');
appendString(key);
out.append('"').append(':').append(' ');
appendValue(value);
}
  

  

  

private void appendString(String s) throws IOException {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
switch(ch){
case '"':
out.append("\\\"");
break;
case '\\':
out.append("\\\\");
break;
case '\b':
out.append("\\b");
break;
case '\f':
out.append("\\f");
break;
case '\n':
out.append("\\n");
break;
case '\r':
out.append("\\r");
break;
case '\t':
out.append("\\t");
break;
case '/':
out.append("\\/");
break;
default:
//Reference: http://www.unicode.org/versions/Unicode5.1.0/
if ((ch>='\u0000' && ch<='\u001F') || (ch>='\u007F' && ch<='\u009F') || (ch>='\u2000' && ch<='\u20FF')) {
String ss = Integer.toHexString(ch);
out.append("\\u");
for (int k=0; k < 4-ss.length(); k++) {
out.append('0');
}
out.append(ss.toUpperCase());
}
else{
out.append(ch);
}
}
}//for
}
  

  

private void appendValue(Object value) throws IOException {
if (value == null) {
out.append("null");
      

} else if (value instanceof String) {
out.append('"');
appendString(value.toString());
out.append('"');
      

} else if (value instanceof Double) {
var num = (Double) value;
if (num.isInfinite() || num.isNaN())
out.append("null");
else
out.append(value.toString());
      

} else if (value instanceof Float) {
var num = (Float) value;
if (num.isInfinite() || num.isNaN())
out.append("null");
else
out.append(value.toString());
      

} else if (value instanceof Map) {
printImpl((Map<?,?>) value);
      

} else if (value instanceof List) {
printImpl((List<?>) value);
      

//    } else if (value instanceof Number || value instanceof Boolean) {
//      out.append(value.toString());
      

} else {
out.append(value.toString());
      

}
}


}

它适用于JSONObjectJSONArray,即使它不依赖于它们。因为这些是常规的MapList对象。(事实代码是从同一个库中提取的)。

https://github.com/crums-io/io-util/blob/master/src/main/java/io/crums/util/json/JsonPrinter.java

这将是一个公共方法,用于打印对象的漂亮版本(你需要安装Gson依赖项:

import com.google.gson.GsonBuilder;
...


public void printMe(){
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String prettyJSON = gson.toJson(this);
System.out.println(printable);
}