Pretty-Print JSON в Java

217

я использую и мне нужно красиво распечатать данные JSON (сделать их более читабельными).

Я не смог найти эту функцию в этой библиотеке. Как это обычно достигается?

mabuzer
источник

Ответы:

285

GSON может сделать это хорошим способом:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
JsonParser jp = new JsonParser();
JsonElement je = jp.parse(uglyJSONString);
String prettyJsonString = gson.toJson(je);
Рэй Хулха
источник
1
Ну, я включил код для разбора строки в JsonElement, обычно у вас уже есть это из предыдущей работы с данными JSON. Но я хотел бы включить его здесь, чтобы сделать использование более понятным.
Рэй Хулха
Так как этот ответ помог мне. Я добавил код ниже, чтобы сократить это утверждение до меньшего количества строк, если это то, что вы ищете. public String prettifyJson (String json) {JsonElement jsonElement = new JsonParser (). parse (json); вернуть новый GsonBuilder (). setPrettyPrinting (). create (). toJson (jsonElement); }
Ахмад
2
Можно ответить на вопрос ОП, не требуя дополнительных библиотек, так как вы можете просто получить доступ к анализатору JSON, встроенному в Rhino (JDK 1.7 и выше). Я не думаю, что желательно добавлять библиотеку в проект только для того, чтобы отформатировать какой-нибудь отладочный вывод. scriptEngine.eval("result = JSON.stringify(JSON.parse(jsonString), null, 2)");
Агнес
1
В отличие от альтернативы org.json, способ красивой печати GSON сохраняет порядок элементов без изменений после преобразования.
Айдын К.
1
Спасибо за указатель на GsonBuilder, так как я использовал, gson.toJson(object)я просто должен был изменить свой экземпляр с Gson gson = new Gson();на, Gson gson = new GsonBuilder().setPrettyPrinting().create(); и мой код продолжал работать, но довольно печатал объект вместо одной строки.
cptully
153

Я использовал встроенные методы org.json, чтобы красиво печатать данные.

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

Порядок полей в JSON является случайным для каждого определения. Конкретный порядок зависит от реализации синтаксического анализатора.

Рагху Киран
источник
7
Я также предпочитаю это решение, потому что вам не нужно импортировать дополнительные зависимости, как предлагают другие ответы.
Гдрт
3
Отсутствует важный импорт - import org.json.JSONObject;
MasterJoe2
есть ли в любом случае НЕ иметь поля в случайном порядке, я хочу, чтобы они были в том порядке, в котором я их добавил?
Томас Адриан
@ThomasAdrian это невозможно с org.json.JSONObject.
Рагху Киран
Underscore-java сохраняет порядок атрибутов при форматировании json.
Валентин Колесников
37

Кажется, GSON поддерживает это, хотя я не знаю, хотите ли вы переключиться с библиотеки, которую вы используете.

Из руководства пользователя:

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);
BuffaloBuffalo
источник
4
Проблема с GSON, она сложная, json-simple намного проще.
mabuzer
1
Я не рассматривал эту проблему более года, но если вы хотите немного изменить исходный код, code.google.com/p/json-simple/issues/detail?id=22 содержит некоторую информацию о улучшение json-simple с симпатичной печатью.
БуффалоБуффало
Получил только строку без какого-либо красивого форматирования печати :(
Cherry
это распечатать строку с \ r \ n
Каменный Джек
Спасибо. Переопределение toString () в одну строку: новый GsonBuilder (). setPrettyPrinting (). create (). toJson (this);
KeepAtIt
30

С Джексоном ( com.fasterxml.jackson.databind):

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

От: Как включить вывод в формате JSON для симпатичной печати (Джексон)

Я знаю, что это уже есть в ответах, но я хочу написать здесь отдельно, потому что есть вероятность, что у вас уже есть зависимость от Джексона, и все, что вам нужно, это дополнительная строка кода.

oktieh
источник
21

Если вы используете Java API для реализации JSON Processing (JSR-353), вы можете указать это JsonGenerator.PRETTY_PRINTINGсвойство при создании JsonGeneratorFactory.

Следующий пример был первоначально опубликован в моем блоге .

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
источник
18

Моя ситуация - мой проект использует устаревший (не JSR) парсер JSON, который не поддерживает красивую печать. Тем не менее, мне нужно было создать довольно напечатанные образцы JSON; это возможно без добавления дополнительных библиотек, если вы используете Java 7 и выше:

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
Это круто, используйте движок js, чтобы сделать это, намного проще
med116
предупреждение, если вы заботитесь: ScriptEngineManager не является API.
nclark
18

Красивая печать с GSON в одну строку:

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

Помимо встраивания, это эквивалентно принятому ответу .

Бенгт
источник
8

Теперь этого можно достичь с помощью библиотеки JSONLib:

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

Если (и только если) вы используете перегруженный toString(int indentationFactor)метод, а не стандартный toString()метод.

Я подтвердил это в следующей версии API:

<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>
Шридхар Сарнобат
источник
3
Хотя эта библиотека может помочь ответить на вопрос, было бы лучше включить пример того, как она применима к проблеме, с некоторыми пояснениями о том, как она работает.
Франческо Мензани
1
Хорошо, спасибо за отзыв. Хотя помните, такие люди, как я, являются волонтерами и им не платят за предоставление услуг, гарантирующих соответствие стандартам качества. У нас ограниченное время, потому что мы часто находимся в середине работы, или у нас есть семейные обязанности. Вот почему «правка» доступна для читателей, поэтому мы можем сделать посты друг друга более полезными.
Шридхар Сарнобат
8

Большинство существующих ответов либо зависят от какой-то внешней библиотеки, либо требуют специальной версии Java. Вот простой код для печати строки JSON, только с использованием общих API-интерфейсов Java (доступен в Java 7 для более поздних версий, хотя не пробовал более старую версию).

Основная идея состоит в том, чтобы изменить форматирование на основе специальных символов в JSON. Например, если наблюдается '{' или '[', код создаст новую строку и увеличит уровень отступа.

Отказ от ответственности: я проверял это только для некоторых простых случаев JSON (базовая пара ключ-значение, список, вложенный JSON), поэтому может потребоваться некоторая работа для более общего текста JSON, такого как строковое значение с кавычками внутри, или специальных символов (\ n, \ т и т. д.).

/**
 * 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
источник
В первом чтении я был очень недоволен этим предложением, но после прочтения всех ответов это лучшее решение. По крайней мере, если это просто для некоторого вывода отладочной информации, и вы не хотите перетаскивать зависимости, то вы, возможно, захотите удалить их позже. Большое спасибо!
user2081279
7

В одной строке:

String niceFormattedJson = JsonWriter.formatJson(jsonString)

Библиотека json-io ( https://github.com/jdereg/json-io) ) - это небольшая ( ) библиотека без каких-либо других зависимостей, кроме JDK.

В дополнение к симпатичной печати JSON, вы можете сериализовать объекты Java (целые графы объектов Java с циклами) в JSON, а также читать их.

Джон Дегноукорт
источник
6

Следуя спецификациям JSON-P 1.0 ( JSR-353 ), более актуальное решение для данного JsonStructure( JsonObjectили JsonArray) может выглядеть следующим образом:

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

}
Йенс Пигса
источник
6

В JSONLib вы можете использовать это:

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

Из Javadoc :

Энрике Сан Мартин
источник
5

Вы можете использовать Gson как ниже

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

Из поста JSON довольно печатать с помощью Gson

Кроме того, вы можете использовать Джексон, как показано ниже

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

Из поста Pretty print JSON на Java (Джексон)

Надеюсь, это поможет!

Дэвид Фам
источник
4

Используя org json. Ссылка ссылка

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

Используя Gson. Ссылка ссылка

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

Используя Джексона. Ссылка ссылка

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

Используя Генсона. Ссылочная ссылка .

Genson prettyGenson = new GensonBuilder().useIndentation(true).create();
String prettyJson = prettyGenson.serialize(obj);
Хари Кришна
источник
1

Это сработало для меня, используя Джексона:

mapper.writerWithDefaultPrettyPrinter().writeValueAsString(JSONString)
Оби-Ван Кеноби
источник
Откуда это mapper?
Sertage
0

Вы можете использовать небольшую библиотеку JSON

String jsonstring = ....;
JsonValue json = JsonParser.parse(jsonstring);
String jsonIndendedByTwoSpaces = json.toPrettyString("  ");
Антон Страка
источник
-2

У Underscore-Java есть статический метод U.formatJson(json). Поддерживаются пять типов форматов: 2, 3, 4, вкладки и компактный. Я поддерживаю проект. Живой пример

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

Вывод:

{
  "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"
    }
}    
Валентин Колесников
источник