我使用JSON -simple,我需要漂亮地打印JSON数据(使其更易于阅读)。
我还没能在那个库中找到这个功能。 这通常是如何实现的?
我使用JSON -simple,我需要漂亮地打印JSON数据(使其更易于阅读)。
我还没能在那个库中找到这个功能。 这通常是如何实现的?
当前回答
现在这可以通过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>
其他回答
漂亮的打印与GSON一行:
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(new JsonParser().parse(jsonString)));
除了内联之外,这等价于已接受的答案。
在JSONLib中,你可以这样使用:
String jsonTxt = JSONUtils.valueToString(json, 8, 4);
来自Javadoc:
这招对我很管用,用了杰克逊的话:
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(" ");
}
}
所以我也很喜欢json-simple lib,并研究了如何打印它的输出。不幸的是,虽然这是一个悬而未决的问题,但我找不到它的任何代码。所以我想我应该试一试,这是我想出的(使用他们自己的来源)..
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());
}
}
}
它适用于JSONObject和JSONArray,即使它没有依赖于他们..因为这些是常规的Map和List对象。(事实代码是从同一个库中提取的)。
https://github.com/crums-io/io-util/blob/master/src/main/java/io/crums/util/json/JsonPrinter.java