JSON Pretty Print in Java


217

sto usando e ho bisogno di stampare graziosamente i dati JSON (renderli più leggibili dall'uomo).

Non sono stato in grado di trovare questa funzionalità all'interno di quella libreria. Come si ottiene questo comunemente?

Risposte:


285

GSON può farlo in un modo carino:

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

1
Beh, ho incluso il codice per analizzare una stringa in un JsonElement, di solito lo hai già dal lavoro precedente che fai con i dati JSON. Ma volevo includerlo qui per rendere l'uso più chiaro.
— Ray Hulha,

Da quando questa risposta mi ha aiutato. Ho aggiunto il codice qui sotto per ridurre questa affermazione a meno righe se questo è quello che stai cercando. public String prettifyJson (String json) {JsonElement jsonElement = new JsonParser (). parse (json); ritorna new GsonBuilder (). setPrettyPrinting (). create (). toJson (jsonElement); }
— ahmad, l'

2
È possibile rispondere alla domanda dell'OP senza la necessità di librerie aggiuntive, in quanto è possibile semplicemente accedere al parser JSON incorporato in Rhino (JDK 1.7 e versioni successive). Non penso che sia desiderabile aggiungere una libreria a un progetto solo per formattare un output di debug. scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
— Agnes,

1
Contrariamente all'alternativa org.json, il modo GSON di stampare graziosamente mantiene intatto l'ordine degli elementi dopo la trasformazione.
— Aydin K.,

1
Grazie per il puntatore a GsonBuilder, dato che stavo usando, gson.toJson(object)dovevo semplicemente cambiare la mia istanza da Gson gson = new Gson();a Gson gson = new GsonBuilder().setPrettyPrinting().create(); e il mio codice continuava a funzionare ma stampavo l'oggetto piuttosto che una singola riga.
— cptully

153

Ho usato i metodi integrati org.json per stampare in modo grazioso i dati.

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

L'ordine dei campi in JSON è casuale per definizione. Un ordine specifico è soggetto all'implementazione del parser.


7
Preferisco anche questa soluzione, perché non è necessario importare dipendenze aggiuntive come suggeriscono altre risposte.
— gdrt

3
Manca un'importazione cruciale - import org.json.JSONObject;
— MasterJoe2

c'è comunque di NON avere i campi in ordine casuale, lo voglio nell'ordine in cui li ho aggiunti?
— Thomas Adrian,

@ThomasAdrian non è possibile con org.json.JSONObject.
— Raghu Kiran,

Underscore-java mantiene l'ordine degli attributi durante la formattazione di json.
— Valentyn Kolesnikov,

37

Sembra che GSON lo supporti, anche se non so se si desidera passare dalla libreria in uso.

Dalla guida per l'utente:

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

4
Il problema con GSON, è complicato, json-simple è molto più semplice.
— mabuzer,

1
Non vedo questo problema da oltre un anno, ma se sei disposto a modificare un po 'il codice sorgente, code.google.com/p/json-simple/issues/detail?id=22 ha alcune informazioni su migliorando json-simple con una bella stampa.
— BuffaloBuffalo,

Ho solo una stringa senza una bella formattazione della stampa :(
— Cherry

stampa String con \ r \ n
— Stone Jack il

Grazie. toString () sovrascrive in una riga: new GsonBuilder (). setPrettyPrinting (). create (). toJson (this);
— KeepAtIt

30

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

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

Da: Come abilitare l'output JSON di Pretty Print (Jackson)

So che questo è già nelle risposte, ma voglio scriverlo separatamente qui perché è probabile che tu abbia già Jackson come dipendenza e quindi tutto ciò di cui hai bisogno sarebbe una riga di codice aggiuntiva


21

Se si utilizza un'implementazione dell'API Java per l'elaborazione JSON (JSR-353), è possibile specificare la JsonGenerator.PRETTY_PRINTINGproprietà quando si crea un JsonGeneratorFactory.

Il seguente esempio è stato originariamente pubblicato sul mio post sul blog .

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

18

La mia situazione è che il mio progetto utilizza un parser JSON legacy (non JSR) che non supporta la stampa piuttosto. Tuttavia, dovevo produrre campioni JSON piuttosto stampati; questo è possibile senza dover aggiungere ulteriori librerie purché si utilizzi Java 7 e versioni successive:

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

3
È fantastico, usa il motore js per farlo, molto più semplice
— med116

avviso se ti interessa: ScriptEngineManager non è API.
— nclark,

18

Bella stampa con GSON su una riga:

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

Oltre a sottolineare, questo equivale alla risposta accettata .


8

Ora questo può essere ottenuto con la libreria JSONLib:

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

Se (e solo se) usi il toString(int indentationFactor)metodo sovraccarico e non il toString()metodo standard .

Ho verificato questo sulla seguente versione dell'API:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>

3
Sebbene questa libreria possa aiutare a rispondere alla domanda, sarebbe meglio includere un esempio di come è applicabile al problema con alcune spiegazioni su come funziona.
— Francesco Menzani,

1
Ok grazie per il feedback. Sebbene ricordi, persone come me sono volontarie e non vengono pagate per fornire un servizio che garantisca il rispetto degli standard di qualità. Abbiamo un tempo limitato perché spesso siamo nel mezzo del lavoro o abbiamo doveri familiari. Ecco perché "modifica" è disponibile per i lettori, in modo che possiamo rendere più utili i post degli altri.
— Sridhar Sarnobat,

8

La maggior parte delle risposte esistenti dipende da alcune librerie esterne o richiede una versione speciale di Java. Ecco un semplice codice per stampare piuttosto una stringa JSON, usando solo API Java generali (disponibile in Java 7 per versioni successive; non ho provato la versione precedente però).

L'idea di base è attivare la formattazione basata su caratteri speciali in JSON. Ad esempio, se si osserva un '{' o '[', il codice creerà una nuova riga e aumenterà il livello di rientro.

Dichiarazione di non responsabilità: ho provato questo solo per alcuni semplici casi JSON (coppia chiave-valore di base, elenco, JSON nidificato), quindi potrebbe essere necessario un po 'di lavoro per un testo JSON più generale, come il valore di stringa con virgolette all'interno o caratteri speciali (\ n, \ t ecc.).

/**
 * 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("  ");
  }
}

In prima lettura sono stato molto scontento di questo suggerimento, ma dopo aver letto tutte le risposte, questa è la soluzione migliore. Almeno, se è solo per un output di debug e non si desidera trascinare le dipendenze, è possibile rimuoverlo in seguito. Grazie mille!
— user2081279

7

In una riga:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

La libray json-io ( https://github.com/jdereg/json-io ) è una piccola libreria (75K) senza altre dipendenze rispetto al JDK.

Oltre a stampare piuttosto JSON, è possibile serializzare oggetti Java (interi grafici di oggetti Java con cicli) su JSON, nonché leggerli in.


6

Seguendo le specifiche JSON-P 1.0 ( JSR-353 ) una soluzione più attuale per un dato JsonStructure( JsonObjecto JsonArray) potrebbe apparire così:

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

}


5

Puoi usare Gson come di seguito

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

Dal post bella stampa JSON usando Gson

In alternativa, puoi usare Jackson come di seguito

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

Dal post Pretty print JSON in Java (Jackson)

Spero che questo aiuto!


4

Usando org json. Link di riferimento

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

Usando Gson. Link di riferimento

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

Usando Jackson. Link di riferimento

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

Usando Genson. Link di riferimento .

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

1

Questo ha funzionato per me, usando Jackson:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)

Da dove mapperviene?
— Sertage

0

Puoi usare una piccola libreria json

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

-2

Underscore-java ha un metodo statico U.formatJson(json). Sono supportati cinque tipi di formato: 2, 3, 4, schede e compatto. Sono il manutentore del progetto. Esempio dal vivo

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

Produzione:

{
  "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"
    }
}    
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.