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.