Как получить компактную форму довольно печатного кода JSON?

Как сделать метод сборки() Jackson's pretty-print своим выходом JSON? Вот пример, который красиво печатает уродливую форму кода JSON. Мне нужно взять хорошую версию JSON-кода, а затем сориентировать ее на уродливую fom. Как это можно сделать? Мне нужно преобразовать это:

 {
   "one" : "AAA",
   "two" : [ "BBB", "CCC" ],
   "three" : {
     "four" : "DDD",
     "five" : [ "EEE", "FFF" ]
   }
 }

:

{"one":"AAA","two":["BBB","CCC"],"three":{"four":"DDD","five":["EEE","FFF"]}}

Я попытался удалить символы '\n', '\ t' и ''; но могут быть некоторые из этих символов в значениях, поэтому я не могу этого сделать. Что еще можно сделать?

Ответы

Ответ 1

Джексон позволяет вам читать строку JSON, поэтому прочитайте симпатичную печатную строку обратно в Jackson, а затем выведите ее снова с отключенной печатью.

См. преобразование строки в JSON

Простой пример

    String prettyJsonString = "{ \"Hello\" : \"world\"}";
    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode jsonNode = objectMapper.readValue(prettyJsonString, JsonNode.class);
    System.out.println(jsonNode.toString());

Требуется

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.5.3</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.5.3</version>
</dependency>

Ответ 2

С помощью потокового API вы можете использовать JsonGenerator.copyCurrentEvent(), чтобы легко повторно выводить поток токенов с помощью любой красивой печати, какой вы хотите, в том числе по умолчанию нет пробельные; это позволяет избежать буферизации всего документа в памяти и построения дерева для документа.

// source and out can be streams, readers/writers, etc.
String source = "   { \"hello\" : \" world \"  }  ";
StringWriter out = new StringWriter();

JsonFactory factory = new JsonFactory();
JsonParser parser = factory.createParser(source);
try (JsonGenerator gen = factory.createGenerator(out)) {
    while (parser.nextToken() != null) {
        gen.copyCurrentEvent(parser);
    }
}

System.out.println(out.getBuffer().toString()); // {"hello":" world "}

Вы можете использовать один и тот же подход для красивой печати документа JSON потоковым способом:

// reindent
gen.setPrettyPrinter(new DefaultPrettyPrinter());

Ответ 3

Безопасный способ состоит в том, чтобы прочитать данные, используя привязку данных "Raw" и просто записать его снова, не включив симпатичный принтер. Streaming API, вероятно, ваш друг здесь.

Использование регулярного выражения также работает, если вы используете этот шаблон: \s*\n\s*

Это не создает самую компактную форму (т.е. у вас все еще есть пробелы между элементами), но это дешевое решение, если у вас уже есть JSON как String. Причина, по которой этот шаблон безопасен, заключается в том, что новые строки недействительны в значениях String (они должны быть экранированы с помощью \n), чтобы вы могли безопасно удалять пробелы вокруг них.

Ответ 4

Jackosn-core - один из способов решения, но я предпочитаю использовать org.json, который является очень простым, но стандартным json lib для java, Открыть исходный код здесь → stleary/JSON-java.

Maven deps

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20160810</version>
</dependency>

Использование

        String payload = "{\n" +
            "  \"fact1\": \"Java is verbose.\", \n" +
            "  \"fact2\" : \"C has pointers\"\n" +
            "}";
        System.out.println(new JSONObject(payload));

Вы получите компактный json {"fact2":"C has pointers","fact1":"Java is verbose."} в одной строке.