Pretty-Print JSON di Jawa

217

saya menggunakan dan saya perlu cukup mencetak data JSON (membuatnya lebih mudah dibaca manusia).

Saya belum dapat menemukan fungsi ini di dalam perpustakaan itu. Bagaimana ini biasanya dicapai?

mabuzer
sumber

Jawaban:

284

GSON dapat melakukan ini dengan cara yang baik:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);
Ray Hulha
sumber
1
Yah saya memasukkan kode untuk mengurai string ke JsonElement, biasanya Anda sudah memiliki itu dari pekerjaan sebelumnya yang Anda lakukan dengan data JSON. Tapi saya ingin memasukkannya di sini untuk memperjelas penggunaannya.
Ray Hulha
Karena jawaban ini membantu saya. Saya telah menambahkan kode di bawah ini untuk mengecilkan pernyataan ini ke baris yang lebih sedikit jika ini yang Anda cari. public String prettifyJson (String json) {JsonElement jsonElement = new JsonParser (). parse (json); mengembalikan GsonBuilder baru (). setPrettyPrinting (). create (). toJson (jsonElement); }
ahmad
2
Dimungkinkan untuk menjawab pertanyaan OP tanpa perlu pustaka tambahan, karena Anda cukup mengakses parser JSON yang disematkan dalam Rhino (JDK 1.7 dan lebih tinggi). Saya tidak berpikir diinginkan untuk menambahkan perpustakaan ke proyek hanya untuk memformat beberapa output debugging. scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
Agnes
1
Berbeda dengan alternatif org.json, cara pencetakan cantik GSON menjaga urutan elemen tetap utuh setelah transformasi.
Aydin K.
1
Terima kasih untuk penunjuknya GsonBuilder, karena saya menggunakan gson.toJson(object)saya hanya harus mengubah instantiasi saya dari Gson gson = new Gson();ke Gson gson = new GsonBuilder().setPrettyPrinting().create(); dan kode saya terus bekerja tetapi cukup mencetak objek bukannya satu baris.
cptully
153

Saya menggunakan metode bawaan org.json untuk mencetak data dengan cantik.

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

Urutan bidang dalam JSON adalah acak per definisi. Pesanan tertentu tunduk pada implementasi parser.

Raghu Kiran
sumber
7
Saya juga lebih suka solusi ini, karena Anda tidak perlu mengimpor dependensi tambahan seperti saran jawaban lain.
gdrt
3
Tidak ada impor penting - impor org.json.JSONObject;
MasterJoe2
adakah di sana TIDAK untuk memiliki bidang dalam urutan acak, saya ingin itu dalam urutan saya menambahkannya?
Thomas Adrian
@ThomasAdrian tidak mungkin dengan org.json.JSONObject.
Raghu Kiran
Underscore-java menjaga urutan atribut saat memformat json.
Valentyn Kolesnikov
37

Sepertinya GSON mendukung ini, walaupun saya tidak tahu apakah Anda ingin beralih dari perpustakaan yang Anda gunakan.

Dari buku petunjuk:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
BuffaloBuffalo
sumber
4
Masalah dengan GSON, rumit, json-sederhana jauh lebih mudah.
mabuzer
1
Saya belum melihat masalah ini lebih dari setahun, tetapi jika Anda bersedia sedikit mengubah kode sumber, code.google.com/p/json-simple/issues/detail?id=22 memiliki beberapa informasi tentang meningkatkan json-simple dengan pencetakan cantik.
BuffaloBuffalo
Hanya punya string tanpa format cetak cantik :(
Cherry
itu mencetak String dengan \ r \ n
Stone Jack
Terima kasih. toString () menimpa dalam satu baris: new GsonBuilder (). setPrettyPrinting (). create (). toJson (this);
KeepAtIt
30

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

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

Dari: Cara mengaktifkan hasil cetak JSON yang cantik (Jackson)

Saya tahu ini sudah ada dalam jawaban, tetapi saya ingin menulisnya secara terpisah di sini karena kemungkinan besar, Anda sudah memiliki Jackson sebagai ketergantungan dan semua yang Anda perlukan akan menjadi baris kode tambahan.

oktieh
sumber
21

Jika Anda menggunakan Java API untuk implementasi JSON Processing (JSR-353) maka Anda dapat menentukan JsonGenerator.PRETTY_PRINTINGproperti ketika Anda membuat a JsonGeneratorFactory.

Contoh berikut ini awalnya diterbitkan di posting blog saya .

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();
bdoughan
sumber
18

Situasi saya adalah proyek saya menggunakan parser JSON lawas (non-JSR) yang tidak mendukung pencetakan cantik. Namun, saya perlu membuat sampel JSON yang dicetak cantik; ini dimungkinkan tanpa harus menambahkan pustaka tambahan selama Anda menggunakan Java 7 dan di atasnya:

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");
Agnes
sumber
3
Ini luar biasa, gunakan mesin js untuk melakukannya, jauh lebih sederhana
med116
peringatan jika Anda peduli: ScriptEngineManager bukan API.
nclark
18

Pencetakan cantik dengan GSON dalam satu baris:

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

Selain inlining, ini setara dengan jawaban yang diterima .

Bengt
sumber
8

Sebagian besar jawaban yang ada tergantung pada pustaka eksternal, atau memerlukan versi Java khusus. Berikut ini adalah kode sederhana untuk mencetak string JSON, hanya menggunakan Java API umum (tersedia di Java 7 untuk yang lebih tinggi; belum pernah mencoba versi yang lebih lama).

Ide dasarnya adalah untuk memadukan format berdasarkan karakter khusus di JSON. Misalnya, jika '{' atau '[' diamati, kode akan membuat baris baru dan meningkatkan level indentasi.

Penafian: Saya hanya menguji ini untuk beberapa kasus JSON sederhana (pasangan nilai kunci dasar, daftar, JSON bersarang) sehingga mungkin perlu beberapa pekerjaan untuk teks JSON yang lebih umum, seperti nilai string dengan kutipan di dalam, atau karakter khusus (\ n, \ t dll).

/**
 * 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("  ");
  }
}
asksw0rder
sumber
Pada bacaan pertama saya sangat tidak senang dengan saran ini, tetapi setelah membaca semua jawaban, ini adalah solusi terbaik. Paling tidak, jika itu hanya untuk beberapa hasil debug, dan Anda tidak ingin menyeret dependensi, yang mungkin ingin Anda hapus nanti. Terima kasih banyak!
user2081279
7

Dalam satu baris:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

Json-io libray ( https://github.com/jdereg/json-io ) adalah perpustakaan kecil (75K) tanpa dependensi selain JDK.

Selain JSON yang cukup mencetak, Anda dapat membuat serial objek Java (seluruh grafik objek Java dengan siklus) ke JSON, serta membacanya di.

John DeRegnaucourt
sumber
7

Sekarang ini dapat dicapai dengan perpustakaan JSONLib:

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

Jika (dan hanya jika) Anda menggunakan toString(int indentationFactor)metode kelebihan beban dan bukan toString()metode standar .

Saya telah memverifikasi ini pada versi API berikut:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>
Sridhar Sarnobat
sumber
3
Meskipun perpustakaan ini dapat membantu menjawab pertanyaan, akan lebih baik untuk memasukkan contoh bagaimana itu berlaku untuk masalah dengan beberapa penjelasan tentang cara kerjanya.
Francesco Menzani
1
Ok terima kasih atas umpan baliknya. Meskipun ingat, orang-orang seperti saya adalah sukarelawan dan tidak dibayar untuk menyediakan layanan yang menjamin memenuhi standar kualitas. Kami memiliki waktu yang terbatas karena kami sering berada di tengah pekerjaan, atau memiliki tugas keluarga. Itu sebabnya "edit" tersedia untuk pembaca, sehingga kami dapat membuat posting satu sama lain lebih bermanfaat.
Sridhar Sarnobat
6

Mengikuti spesifikasi JSON-P 1.0 ( JSR-353 ) solusi yang lebih terkini untuk yang diberikan JsonStructure( JsonObjectatau JsonArray) dapat terlihat seperti ini:

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

}
Jens Piegsa
sumber
6

Di JSONLib Anda dapat menggunakan ini:

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

Dari Javadoc :

Enrique San Martín
sumber
5

Anda dapat menggunakan Gson seperti di bawah ini

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

Dari pos JSON cukup cetak menggunakan Gson

Atau, Anda dapat menggunakan Jackson seperti di bawah ini

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

Dari pos Pretty print JSON in Java (Jackson)

Semoga bantuan ini!

David Pham
sumber
4

Menggunakan org json. Tautan referensi

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

Menggunakan Gson. Tautan referensi

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

Menggunakan Jackson. Tautan referensi

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

Menggunakan Genson. Tautan referensi .

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

Ini bekerja untuk saya, menggunakan Jackson:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
ObiWanKenobi
sumber
Dari mana ini mapperberasal?
Sertage
0

Anda dapat menggunakan perpustakaan json kecil

String jsonstring = ....;
JsonValue json = JsonParser.parse(jsonstring);
String jsonIndendedByTwoSpaces = json.toPrettyString("  ");
Anton Straka
sumber
-2

Underscore-java memiliki metode statis U.formatJson(json). Lima jenis format didukung: 2, 3, 4, tab dan kompak. Saya adalah pengelola proyek. Contoh langsung

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

Keluaran:

{
  "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"
    }
}    
Valentyn Kolesnikov
sumber