Pretty-Imprimir JSON en Java


Estoy usando json-simple y necesito bastante-imprimir datos JSON (hacerlo más legible por humanos).

No he podido encontrar esta funcionalidad dentro de esa biblioteca. ¿Cómo se logra esto comúnmente?

Author: Francesco Menzani, 2010-11-05

14 answers

GSON puede hacer esto de una manera agradable:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);
 217
Author: Ray Hulha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 15:13:59

Usé org.json métodos integrados para imprimir los datos.

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

El orden de los campos en JSON es aleatorio por definición. Un orden específico está sujeto a la implementación del analizador sintáctico.

 108
Author: Raghu Kiran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 15:22:32

Parece que GSON soporta esto, aunque no se si quieres cambiar de la biblioteca que estás usando.

De la guía del usuario:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
 26
Author: BuffaloBuffalo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 15:17:55

Si está utilizando una API Java para la implementación de Procesamiento JSON (JSR-353), puede especificar la propiedad JsonGenerator.PRETTY_PRINTING cuando cree un JsonGeneratorFactory.

El siguiente ejemplo ha sido publicado originalmente en mi entrada 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();
 17
Author: Blaise Doughan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 15:38:25

Bonita impresión con GSON en una línea:

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

Además de la inserción, esto es equivalente a la respuesta aceptada.

 17
Author: Bengt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:41

Mi situación es que mi proyecto utiliza un analizador JSON heredado (que no es JSR) que no admite la impresión bonita. Sin embargo, necesitaba producir muestras JSON bastante impresas; esto es posible sin tener que agregar ninguna biblioteca adicional, siempre y cuando esté utilizando Java 7 y superior:

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");
 14
Author: Agnes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-17 10:40:37

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

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

De: Cómo habilitar la salida JSON pretty print (Jackson)

Sé que esto ya está en las respuestas, pero quiero escribirlo por separado aquí porque lo más probable es que ya tengas Jackson como dependencia y por lo tanto todo lo que necesitarás sería una línea adicional de código

 9
Author: oktieh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-21 20:23:54

En JSONLib puedes usar esto:

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

Del Javadoc :

 6
Author: Enrique San Martín,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 15:48:48

En una línea:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

El libray json-io ( https://github.com/jdereg/json-io ) es una pequeña biblioteca (75K) sin otras dependencias que el JDK.

Además de JSON de impresión bonita, puede serializar objetos Java (gráficos de objetos Java completos con ciclos) en JSON, así como leerlos.

 5
Author: John DeRegnaucourt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-19 13:42:56

Ahora esto se puede lograr con la biblioteca JSONLib:

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

Si (y solo si) se utiliza el método toString(int indentationFactor) sobrecargado y no el método estándar toString().

He verificado esto en la siguiente versión de la API:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>
 4
Author: Sridhar-Sarnobat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-11 16:12:53

Siguiendo las especificaciones JSON-P 1.0 (JSR-353 ) una solución más actual para un determinado JsonStructure (JsonObject o JsonArray) podría verse así:

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

}
 3
Author: Jens Piegsa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-09 13:11:57

Puedes usar Gson como abajo

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

Del post JSON pretty print usando Gson

Alternativamente, puedes usar Jackson como abajo

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

Del post Pretty print JSON in Java (Jackson)

Espero que esta ayuda!

 3
Author: David Pham,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-06 15:28:45

La mayoría de las respuestas existentes dependen de alguna biblioteca externa, o requieren una versión especial de Java. Aquí hay un código simple para imprimir una cadena JSON, solo usando API Java generales (disponible en Java 7 para mayor; aunque no he probado la versión anterior).

La idea básica es tigger el formato basado en caracteres especiales en JSON. Por ejemplo, si se observa un ' {'o' [ ' , el código creará una nueva línea y aumentará el nivel de sangría.

Descargo de responsabilidad: Solo probado esto para algunos casos JSON simples (par clave-valor básico, lista, JSON anidado) por lo que puede necesitar algo de trabajo para texto JSON más general, como valor de cadena con comillas dentro, o caracteres especiales (\n, \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("  ");
  }
}
 2
Author: asksw0rder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-29 20:29:39

Esto funcionó para mí, usando Jackson:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
 0
Author: ObiWanKenobi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-09 01:31:51