Pretty-Print JSON w Javie

217

używam i muszę dość wydrukować dane JSON (aby były bardziej czytelne dla człowieka).

Nie udało mi się znaleźć tej funkcji w tej bibliotece. Jak to się zwykle osiąga?

mabuzer
źródło

Odpowiedzi:

285

GSON może to zrobić w przyjemny sposób:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);
Ray Hulha
źródło
1
Cóż, dołączyłem kod do parsowania łańcucha w JsonElement, zwykle masz go już z poprzedniej pracy, którą wykonujesz z danymi JSON. Chciałem jednak dołączyć to tutaj, aby użytkowanie było bardziej przejrzyste.
Ray Hulha
Ponieważ ta odpowiedź mi pomogła. Poniżej dodałem kod, aby zmniejszyć tę instrukcję do mniejszej liczby wierszy, jeśli tego właśnie szukasz. public String prettifyJson (String json) {JsonElement jsonElement = new JsonParser (). parse (json); zwraca nową GsonBuilder (). setPrettyPrinting (). create (). toJson (jsonElement); }
ahmad
2
Możliwe jest udzielenie odpowiedzi na pytanie OP bez potrzeby korzystania z dodatkowych bibliotek, ponieważ można po prostu uzyskać dostęp do analizatora składni JSON osadzonego w Rhino (JDK 1.7 i nowsze wersje). Nie sądzę, aby pożądane było dodawanie biblioteki do projektu w celu sformatowania niektórych danych wyjściowych do debugowania. scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
Agnes,
1
W przeciwieństwie do alternatywy org.json, ładny sposób drukowania GSON utrzymuje porządek elementów w stanie nienaruszonym po transformacji.
Aydin K.,
1
Dzięki za wskaźnik do GsonBuilder, ponieważ używałem gson.toJson(object), po prostu musiałem zmienić instancję z Gson gson = new Gson();na Gson gson = new GsonBuilder().setPrettyPrinting().create(); i mój kod nadal działał, ale całkiem wydrukowałem obiekt zamiast jednej linii.
cptully
153

Kiedyś org.json wbudowanej metody pretty wydrukować dane.

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

Kolejność pól w JSON jest losowa według definicji. Konkretne zamówienie podlega implementacji parsera.

Raghu Kiran
źródło
7
Ja też wolę to rozwiązanie, ponieważ nie trzeba importować dodatkowych zależności, jak sugerują inne odpowiedzi.
gdrt
3
Brak kluczowego importu - import org.json.JSONObject;
MasterJoe2,
czy w ogóle NIE ma pól w kolejności losowej, chcę je w kolejności, w której je dodałem?
Thomas Adrian,
@ThomasAdrian nie jest możliwe w przypadku org.json.JSONObject.
Raghu Kiran,
Underscore-java utrzymuje porządek atrybutów podczas formatowania json.
Valentyn Kolesnikov
37

Wygląda na to, że GSON obsługuje to, chociaż nie wiem, czy chcesz przełączyć się z używanej biblioteki.

Z instrukcji obsługi:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
BuffaloBuffalo
źródło
4
Problem z GSON jest skomplikowany, json-simple jest znacznie łatwiejszy.
mabuzer
1
Nie patrzyłem na ten problem od ponad roku, ale jeśli chcesz nieco zmodyfikować kod źródłowy, code.google.com/p/json-simple/issues/detail?id=22 ma trochę informacji na temat ulepszenie json-simple dzięki ładnemu drukowaniu.
BuffaloBuffalo,
Dostałem tylko ciąg bez ładnego formatowania wydruku :(
Cherry
wypisuje napis z \ r \ n
Stone Jack
Dzięki. przesłonięcie toString () w jednym wierszu: new GsonBuilder (). setPrettyPrinting (). create (). toJson (this);
KeepAtIt
30

Z Jacksonem ( com.fasterxml.jackson.databind):

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

Od: Jak włączyć ładny wydruk JSON (Jackson)

Wiem, że jest to już w odpowiedziach, ale chcę napisać to tutaj osobno, ponieważ są szanse, że masz już Jackson jako zależność, więc wszystko, czego potrzebujesz, to dodatkowy wiersz kodu

okej
źródło
21

Jeśli używasz interfejsu API języka Java do implementacji przetwarzania JSON (JSR-353), możesz określić JsonGenerator.PRETTY_PRINTINGwłaściwość podczas tworzenia JsonGeneratorFactory.

Poniższy przykład został pierwotnie opublikowany na moim blogu .

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
źródło
18

Moja sytuacja jest taka, że ​​mój projekt korzysta ze starszego parsera JSON (nie JSR), który nie obsługuje ładnego drukowania. Musiałem jednak wyprodukować ładnie wydrukowane próbki JSON; jest to możliwe bez konieczności dodawania dodatkowych bibliotek, o ile używasz Java 7 i nowszych wersji:

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");
Agnieszka
źródło
3
To jest niesamowite, użyj do tego silnika js, o wiele prostsze
med116
ostrzeżenie, jeśli cię to obchodzi: ScriptEngineManager nie jest API.
nclark,
18

Ładne drukowanie z GSON w jednej linii:

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

Oprócz wstawiania jest to równoważne z przyjętą odpowiedzią .

Bengt
źródło
8

Większość istniejących odpowiedzi albo zależy od biblioteki zewnętrznej, albo wymaga specjalnej wersji Java. Oto prosty kod do wydrukowania łańcucha JSON, tylko przy użyciu ogólnych interfejsów API Java (dostępny w Javie 7 dla wyższych wersji; chociaż nie wypróbowałem starszej wersji).

Podstawową ideą jest przełączanie formatowania na podstawie znaków specjalnych w JSON. Na przykład, jeśli zostanie zaobserwowane „{” lub „[”, kod utworzy nowy wiersz i zwiększy poziom wcięcia.

Oświadczenie: Testowałem to tylko dla niektórych prostych przypadków JSON (podstawowa para klucz-wartość, lista, zagnieżdżony JSON), więc może potrzebować trochę pracy dla bardziej ogólnego tekstu JSON, takiego jak wartość ciągu z cudzysłowami lub znaki specjalne (\ n, \ t itp.).

/**
 * 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("  ");
  }
}
asksw0rder
źródło
Podczas pierwszego czytania byłem bardzo niezadowolony z tej sugestii, ale po przeczytaniu wszystkich odpowiedzi jest to najlepsze rozwiązanie. Przynajmniej jeśli jest to tylko dla niektórych wyników debugowania i nie chcesz przeciągać zależności, które możesz chcieć usunąć później. Dziękuję Ci bardzo!
user2081279,
7

W jednej linii:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

Biblioteka json-io ( https://github.com/jdereg/json-io ) to mała biblioteka (75 KB ) bez żadnych innych zależności niż JDK.

Oprócz ładnego drukowania JSON, możesz serializować obiekty Java (całe wykresy obiektów Java z cyklami) do JSON, a także wczytywać je.

John DeRegnaucourt
źródło
7

Teraz można to osiągnąć dzięki bibliotece JSONLib:

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

Jeśli (i tylko jeśli) używasz toString(int indentationFactor)metody przeciążonej , a nie standardowej toString().

Zweryfikowałem to w następującej wersji interfejsu API:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>
Sridhar Sarnobat
źródło
3
Chociaż ta biblioteka może pomóc w udzieleniu odpowiedzi na pytanie, lepiej byłoby podać przykład, w jaki sposób można go zastosować do problemu, wraz z wyjaśnieniem, jak to działa.
Francesco Menzani,
1
Ok dzięki za opinie. Chociaż pamiętajcie, ludzie tacy jak ja są wolontariuszami i nie zarabiają na świadczeniu usług, które gwarantują spełnienie standardów jakości. Mamy ograniczony czas, ponieważ często jesteśmy w środku pracy lub mamy obowiązki rodzinne. Właśnie dlatego „edycja” jest dostępna dla czytelników, dzięki czemu możemy wzajemnie się poprawiać.
Sridhar Sarnobat
6

Zgodnie ze specyfikacjami JSON-P 1.0 ( JSR-353 ) bardziej aktualne rozwiązanie dla danego JsonStructure( JsonObjectlub JsonArray) mogłoby wyglądać następująco:

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
źródło
6

W JSONLib możesz użyć tego:

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

Z Javadoc :

Enrique San Martín
źródło
5

Możesz użyć Gson jak poniżej

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

Z postu ładny wydruk JSON za pomocą Gsona

Alternatywnie możesz użyć Jacksona jak poniżej

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

Z postu Ładny druk JSON w Javie (Jackson)

Mam nadzieję, że to pomoże!

David Pham
źródło
4

Za pomocą org json. Link referencyjny

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

Korzystanie z Gson. Link referencyjny

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

Korzystanie z Jacksona. Link referencyjny

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

Korzystanie z Genson. Link referencyjny .

Genson prettyGenson = new GensonBuilder().useIndentation(true).create();
String prettyJson = prettyGenson.serialize(obj);
Hari Krishna
źródło
1

To zadziałało dla mnie przy użyciu Jacksona:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
Obi-Wan Kenobi
źródło
Skąd to się mapperwzięło?
Sertage
0

Możesz użyć małej biblioteki json

String jsonstring = ....;
JsonValue json = JsonParser.parse(jsonstring);
String jsonIndendedByTwoSpaces = json.toPrettyString("  ");
Anton Straka
źródło
-2

Underscore-java ma metodę statyczną U.formatJson(json). Obsługiwanych jest pięć typów formatów: 2, 3, 4, tabulatory i compact. Jestem opiekunem projektu. Przykład na żywo

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

Wynik:

{
  "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
źródło