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

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


当前回答

更新:new JsonParser().parse(…)已@弃用


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

使用Maven的Gson依赖:

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

参考:

JsonParser已弃用

其他回答

所以我也很喜欢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

如果您正在使用用于JSON处理(JSR-353)实现的Java API,那么您可以指定JsonGenerator。当您创建JsonGeneratorFactory时,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();

更新:new JsonParser().parse(…)已@弃用


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

使用Maven的Gson依赖:

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

参考:

JsonParser已弃用

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

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

来自Javadoc:

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

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)