Pretty-Print JSON in Java

217

Ich benutze und ich muss JSON-Daten hübsch drucken (sie besser lesbar machen).

Ich konnte diese Funktionalität in dieser Bibliothek nicht finden. Wie wird dies gemeinsam erreicht?

Mabuzer
quelle

Antworten:

284

GSON kann dies auf nette Weise tun:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);
Ray Hulha
quelle
1
Nun, ich habe Code zum Parsen eines Strings in ein JsonElement eingefügt. Normalerweise haben Sie bereits Code aus früheren Arbeiten, die Sie mit den JSON-Daten durchgeführt haben. Aber ich wollte es hier aufnehmen, um die Verwendung klarer zu machen.
Ray Hulha
Da hat mir diese Antwort geholfen. Ich habe unten Code hinzugefügt, um diese Anweisung auf weniger Zeilen zu verkleinern, wenn Sie danach suchen. public String prettifyJson (String json) {JsonElement jsonElement = new JsonParser (). parse (json); return new GsonBuilder (). setPrettyPrinting (). create (). toJson (jsonElement); }
Ahmad
2
Es ist möglich, die Frage des OP zu beantworten, ohne zusätzliche Bibliotheken zu benötigen, da Sie einfach auf den in Rhino eingebetteten JSON-Parser zugreifen können (JDK 1.7 und höher). Ich halte es nicht für wünschenswert, einem Projekt eine Bibliothek hinzuzufügen, nur um eine Debugging-Ausgabe zu formatieren. scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
Agnes
1
Im Gegensatz zur org.json-Alternative behält die GSON-Methode des hübschen Druckens die Reihenfolge der Elemente nach der Transformation bei.
Aydin K.
1
Vielen Dank für den Zeiger auf GsonBuilder, da war ich mit gson.toJson(object)ich einfach aus mußte meine Instanziierung ändern Gson gson = new Gson();zu Gson gson = new GsonBuilder().setPrettyPrinting().create(); und mein Code Arbeit fortgesetzt , aber ziemlich das Objekt statt einer einzigen Zeile gedruckt.
Cptully
153

Ich habe die in org.json integrierten Methoden verwendet, um die Daten hübsch auszudrucken.

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

Die Reihenfolge der Felder in JSON ist per Definition zufällig. Eine bestimmte Reihenfolge unterliegt der Parser-Implementierung.

Raghu Kiran
quelle
7
Ich bevorzuge diese Lösung auch, da Sie keine zusätzlichen Abhängigkeiten importieren müssen, wie andere Antworten vermuten lassen.
GDRT
3
Fehlen eines entscheidenden Imports - import org.json.JSONObject;
MasterJoe2
Gibt es sowieso keine Felder in zufälliger Reihenfolge, ich möchte es in der Reihenfolge, in der ich sie hinzugefügt habe?
Thomas Adrian
@ThomasAdrian ist mit org.json.JSONObject nicht möglich.
Raghu Kiran
Underscore-java behält die Attributreihenfolge bei, während json formatiert wird.
Valentyn Kolesnikov
37

Es scheint, dass GSON dies unterstützt, obwohl ich nicht weiß, ob Sie von der verwendeten Bibliothek wechseln möchten.

Aus der Bedienungsanleitung:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
BuffaloBuffalo
quelle
4
Das Problem mit GSON ist kompliziert, json-simple ist viel einfacher.
Mabuzer
1
Ich habe mir dieses Problem seit über einem Jahr nicht mehr angesehen, aber wenn Sie bereit sind, den Quellcode ein wenig zu ändern, finden Sie unter code.google.com/p/json-simple/issues/detail?id=22 einige Informationen Verbesserung von json-simple durch hübsches Drucken.
BuffaloBuffalo
Habe gerade einen String ohne hübsche Druckformatierung :(
Cherry
es druckt String mit \ r \ n
Stone Jack
Vielen Dank. toString () überschreiben in einer Zeile: new GsonBuilder (). setPrettyPrinting (). create (). toJson (this);
KeepAtIt
30

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

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

Von: So aktivieren Sie die hübsche JSON-Druckausgabe (Jackson)

Ich weiß, dass dies bereits in den Antworten enthalten ist, aber ich möchte es hier separat schreiben, da Sie wahrscheinlich bereits Jackson als Abhängigkeit haben und daher nur eine zusätzliche Codezeile benötigen

oktieh
quelle
21

Wenn Sie eine Java-API für die Implementierung der JSON-Verarbeitung (JSR-353) verwenden, können Sie die JsonGenerator.PRETTY_PRINTINGEigenschaft beim Erstellen einer angeben JsonGeneratorFactory.

Das folgende Beispiel wurde ursprünglich in meinem Blogbeitrag veröffentlicht .

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
quelle
18

Meine Situation ist, dass mein Projekt einen älteren JSON-Parser (nicht JSR) verwendet, der kein hübsches Drucken unterstützt. Ich musste jedoch hübsch gedruckte JSON-Beispiele erstellen. Dies ist möglich, ohne dass zusätzliche Bibliotheken hinzugefügt werden müssen, solange Sie Java 7 und höher verwenden:

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
quelle
3
Dies ist super, verwenden Sie die js-Engine, um es zu tun, so viel einfacher
med116
Warnung, wenn Sie sich interessieren: Der ScriptEngineManager ist keine API.
nclark
18

Hübscher Druck mit GSON in einer Zeile:

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

Dies entspricht neben dem Inlining der akzeptierten Antwort .

Bengt
quelle
8

Die meisten vorhandenen Antworten hängen entweder von einer externen Bibliothek ab oder erfordern eine spezielle Java-Version. Hier ist ein einfacher Code zum hübschen Drucken einer JSON-Zeichenfolge, wobei nur allgemeine Java-APIs verwendet werden (verfügbar in Java 7 für höhere Versionen; ältere Version wurde jedoch nicht ausprobiert).

Die Grundidee besteht darin, die Formatierung basierend auf Sonderzeichen in JSON zu aktivieren. Wenn beispielsweise ein '{' oder '[' beobachtet wird, erstellt der Code eine neue Zeile und erhöht die Einrückungsstufe.

Haftungsausschluss: Ich habe dies nur für einige einfache JSON-Fälle getestet (grundlegendes Schlüssel-Wert-Paar, Liste, verschachteltes JSON), sodass möglicherweise Arbeit für allgemeineren JSON-Text erforderlich ist, z. B. Zeichenfolgenwert mit Anführungszeichen oder Sonderzeichen (\ n, \ t usw.).

/**
 * 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("  ");
  }
}
fragtw0rder
quelle
Bei der ersten Lesung war ich sehr unzufrieden mit diesem Vorschlag, aber nachdem ich alle Antworten gelesen habe, ist dies die beste Lösung. Zumindest, wenn es sich nur um eine Debugging-Ausgabe handelt und Sie keine Abhängigkeiten ziehen möchten, möchten Sie diese möglicherweise später wieder entfernen. Vielen Dank!
user2081279
7

In einer Zeile:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

Das json-io libray ( https://github.com/jdereg/json-io ) ist eine kleine Bibliothek (75 KB ) ohne andere Abhängigkeiten als das JDK.

Zusätzlich zum hübschen Drucken von JSON können Sie Java-Objekte (ganze Java-Objektdiagramme mit Zyklen) in JSON serialisieren und einlesen.

John DeRegnaucourt
quelle
7

Dies kann nun mit der JSONLib-Bibliothek erreicht werden:

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

Wenn (und nur wenn) Sie die überladene toString(int indentationFactor)Methode und nicht die Standardmethode toString()verwenden.

Ich habe dies in der folgenden Version der API überprüft:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>
Sridhar Sarnobat
quelle
3
Diese Bibliothek kann zwar zur Beantwortung der Frage beitragen, es ist jedoch besser, ein Beispiel für die Anwendbarkeit auf das Problem mit einer Erläuterung der Funktionsweise beizufügen.
Francesco Menzani
1
Ok danke für das Feedback. Denken Sie jedoch daran, dass Menschen wie ich Freiwillige sind und nicht dafür bezahlt werden, einen Service anzubieten, der die Einhaltung von Qualitätsstandards garantiert. Wir haben nur eine begrenzte Zeit, weil wir oft mitten in der Arbeit sind oder familiäre Pflichten haben. Aus diesem Grund steht den Lesern "Bearbeiten" zur Verfügung, damit wir die Beiträge der anderen hilfreicher gestalten können.
Sridhar Sarnobat
6

Nach den JSON-P 1.0-Spezifikationen ( JSR-353 ) könnte eine aktuellere Lösung für ein bestimmtes JsonStructure( JsonObjectoder JsonArray) wie folgt aussehen:

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
quelle
6

In JSONLib können Sie Folgendes verwenden:

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

Aus dem Javadoc :

Enrique San Martín
quelle
5

Sie können Gson wie unten verwenden

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

Aus dem Post- JSON-Druck mit Gson

Alternativ können Sie Jackson wie unten verwenden

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

Aus dem Beitrag Pretty Print JSON in Java (Jackson)

Ich hoffe das hilft!

David Pham
quelle
4

Verwenden von org json. Referenz - Link

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

Mit Gson. Referenz - Link

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

Mit Jackson. Referenz - Link

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

Mit Genson. Referenz Link .

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

Das hat bei mir mit Jackson funktioniert:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
Obi Wan Kenobi
quelle
Woher mapperkam das?
Sertage
0

Sie können eine kleine JSON- Bibliothek verwenden

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

Unterstrich-Java hat statische Methode U.formatJson(json). Es werden fünf Formattypen unterstützt: 2, 3, 4, Registerkarten und Kompakt. Ich bin der Betreuer des Projekts. Live Beispiel

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

Ausgabe:

{
  "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
quelle