JSON Pretty-Print en Java

217

j'utilise et j'ai besoin d'imprimer les données JSON (pour les rendre plus lisibles par l'homme).

Je n'ai pas pu trouver cette fonctionnalité dans cette bibliothèque. Comment cela est-il couramment réalisé?

mabuzer
la source

Réponses:

285

GSON peut le faire d'une manière agréable:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);
Ray Hulha
la source
1
Eh bien, j'ai inclus du code pour analyser une chaîne dans un JsonElement, généralement vous l'avez déjà du travail précédent que vous faites avec les données JSON. Mais je voulais l'inclure ici pour rendre l'utilisation plus claire.
Ray Hulha
Depuis cette réponse m'a aidé. J'ai ajouté du code ci-dessous pour réduire cette déclaration à moins de lignes si c'est ce que vous recherchez. public String prettifyJson (String json) {JsonElement jsonElement = new JsonParser (). parse (json); retourne un nouveau GsonBuilder (). setPrettyPrinting (). create (). toJson (jsonElement); }
ahmad
2
Il est possible de répondre à la question de l'OP sans avoir besoin de bibliothèques supplémentaires, car vous pouvez simplement accéder à l'analyseur JSON intégré à Rhino (JDK 1.7 et supérieur). Je ne pense pas qu'il soit souhaitable d'ajouter une bibliothèque à un projet juste pour formater une sortie de débogage. scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
Agnes
1
Contrairement à l'alternative org.json, la manière GSON de la jolie impression garde l'ordre des éléments intact après la transformation.
Aydin K.
1
Merci pour le pointeur vers GsonBuilder, puisque j'utilisais, je gson.toJson(object)devais simplement changer mon instanciation de Gson gson = new Gson();à Gson gson = new GsonBuilder().setPrettyPrinting().create(); et mon code a continué à fonctionner mais a assez bien imprimé l'objet au lieu d'une seule ligne.
cptully
153

J'ai utilisé les méthodes intégrées org.json pour imprimer les données de façon jolie.

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

L'ordre des champs dans JSON est aléatoire par définition. Une commande spécifique est soumise à une implémentation de l'analyseur.

Raghu Kiran
la source
7
Je préfère également cette solution, car vous n'avez pas besoin d'importer des dépendances supplémentaires comme le suggèrent d'autres réponses.
gdrt
3
Manque une importation cruciale - import org.json.JSONObject;
MasterJoe2
existe-t-il de toute façon de NE PAS avoir les champs dans un ordre aléatoire, je le veux dans l'ordre où je les ai ajoutés?
Thomas Adrian
@ThomasAdrian ce n'est pas possible avec org.json.JSONObject.
Raghu Kiran
Underscore-java conserve l'ordre des attributs lors du formatage de json.
Valentyn Kolesnikov
37

Il semble que GSON le supporte, même si je ne sais pas si vous voulez passer de la bibliothèque que vous utilisez.

Du guide de l'utilisateur:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
BuffaloBuffalo
la source
4
Le problème avec GSON, c'est compliqué, json-simple est beaucoup plus facile.
mabuzer
1
Je n'ai pas examiné ce problème depuis plus d'un an, mais si vous êtes prêt à modifier un peu le code source, code.google.com/p/json-simple/issues/detail?id=22 contient des informations sur améliorant json-simple avec une jolie impression.
BuffaloBuffalo
Vous avez juste une chaîne sans aucun joli format d'impression :(
Cherry
il imprime la chaîne avec \ r \ n
Stone Jack
Merci. remplacement de toString () sur une seule ligne: new GsonBuilder (). setPrettyPrinting (). create (). toJson (this);
KeepAtIt
30

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

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

De: Comment activer la sortie JSON jolie impression (Jackson)

Je sais que c'est déjà dans les réponses, mais je veux l'écrire séparément ici parce que les chances sont, vous avez déjà Jackson comme dépendance et donc tout ce dont vous aurez besoin serait une ligne de code supplémentaire

oktieh
la source
21

Si vous utilisez une implémentation d'API Java pour le traitement JSON (JSR-353), vous pouvez spécifier la JsonGenerator.PRETTY_PRINTINGpropriété lorsque vous créez unJsonGeneratorFactory .

L'exemple suivant a été initialement publié sur mon article de 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();
bdoughan
la source
18

Ma situation est que mon projet utilise un analyseur JSON hérité (non JSR) qui ne prend pas en charge la jolie impression. Cependant, j'avais besoin de produire des échantillons JSON assez imprimés; cela est possible sans avoir à ajouter de bibliothèques supplémentaires tant que vous utilisez Java 7 et supérieur:

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");
Agnès
la source
3
C'est génial, utilisez le moteur js pour le faire, tellement plus simple
med116
avertissement si vous vous en souciez: le ScriptEngineManager n'est pas l'API.
nclark
18

Jolie impression avec GSON sur une seule ligne:

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

Outre la mise en ligne, cela équivaut à la réponse acceptée .

Bengt
la source
8

Maintenant, cela peut être réalisé avec la bibliothèque JSONLib:

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

Si (et seulement si) vous utilisez la toString(int indentationFactor)méthode surchargée et non la toString()méthode standard .

J'ai vérifié cela sur la version suivante de l'API:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>
Sridhar Sarnobat
la source
3
Bien que cette bibliothèque puisse aider à répondre à la question, il serait préférable d'inclure un exemple de la façon dont elle s'applique au problème avec quelques explications sur la façon dont cela fonctionne.
Francesco Menzani
1
Ok merci pour les commentaires. N'oubliez pas que des gens comme moi sont des bénévoles et ne sont pas payés pour fournir un service qui garantit le respect des normes de qualité. Nous avons peu de temps parce que nous sommes souvent au milieu du travail ou que nous avons des devoirs familiaux. C'est pourquoi "modifier" est disponible pour les lecteurs, afin que nous puissions rendre les messages des autres plus utiles.
Sridhar Sarnobat
8

La plupart des réponses existantes dépendent d'une bibliothèque externe ou nécessitent une version Java spéciale. Voici un code simple pour imprimer une chaîne JSON, en utilisant uniquement des API Java générales (disponibles dans Java 7 pour les versions supérieures; je n'ai pas essayé la version plus ancienne).

L'idée de base est de déclencher la mise en forme en fonction des caractères spéciaux dans JSON. Par exemple, si un '{' ou '[' est observé, le code créera une nouvelle ligne et augmentera le niveau de retrait.

Avis de non-responsabilité: je n'ai testé cela que pour certains cas JSON simples (paire clé-valeur de base, liste, JSON imbriqué). t etc.).

/**
 * 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("  ");
  }
}
askw0rder
la source
En première lecture, j'ai été très mécontent de cette suggestion, mais après avoir lu toutes les réponses, c'est la meilleure solution. Au moins, si ce n'est que pour une sortie de débogage, et que vous ne voulez pas faire glisser les dépendances, que vous voudrez peut-être supprimer plus tard. Merci beaucoup!
user2081279
7

En une seule ligne:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

Le libray json-io ( https://github.com/jdereg/json-io ) est une petite bibliothèque (75K) sans autres dépendances que le JDK.

En plus de la jolie impression JSON, vous pouvez sérialiser des objets Java (graphiques d'objets Java entiers avec des cycles) en JSON, ainsi que les lire.

John DeRegnaucourt
la source
6

En suivant les spécifications JSON-P 1.0 ( JSR-353 ), une solution plus actuelle pour une donnée JsonStructure( JsonObjectou JsonArray) pourrait ressembler à ceci:

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
la source
6

Dans JSONLib, vous pouvez utiliser ceci:

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

Du Javadoc :

Enrique San Martín
la source
5

Vous pouvez utiliser Gson comme ci-dessous

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

De la jolie impression JSON en utilisant Gson

Alternativement, vous pouvez utiliser Jackson comme ci-dessous

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

Extrait du post Pretty print JSON in Java (Jackson)

J'espère que cette aide!

David Pham
la source
4

Utiliser org json. Lien de référence

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

Utilisation de Gson. Lien de référence

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

Utiliser Jackson. Lien de référence

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

Utilisation de Genson. Lien de référence .

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

Cela a fonctionné pour moi, en utilisant Jackson:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
Obi Wan Kenobi
la source
D'où cela mappervient?
Sertage
0

Vous pouvez utiliser une petite bibliothèque json

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

Underscore-java a une méthode statique U.formatJson(json). Cinq types de formats sont pris en charge: 2, 3, 4, onglets et compact. Je suis le responsable du projet. Exemple en direct

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

Production:

{
  "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
la source