Гарненький друк JSON від ObjectMapper Jackson 2.2


141

Зараз у мене є примірник org.fasterxml.jackson.databind.ObjectMapperі я хотів би отримати Stringгарний JSON. Усі результати моїх пошуків Google придумали Jackson 1.x способи цього зробити, і я не можу знайти належний, непридатний спосіб зробити це з 2.2. Хоча я не вважаю, що код абсолютно необхідний для цього питання, ось що я зараз маю:

ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(Include.NON_NULL);
System.out.println("\n\n----------REQUEST-----------");
StringWriter sw = new StringWriter();
mapper.writeValue(sw, jsonObject);
// Want pretty version of sw.toString() here

Відповіді:


277

Ви можете включити досить-друк, встановивши SerializationFeature.INDENT_OUTPUTна ваш ObjectMapperвиглядати приблизно так:

mapper.enable(SerializationFeature.INDENT_OUTPUT);

1
Я також спробував це, але, схоже, SerializationConfigце вирішено, але SerializationConfig.Featureце не так. Це, здається, є ще одним методом гарного друку, який також застарілий, якщо я щось не пропускаю. Є Featureклас, який відокремлений самостійно, але не має INDENT_OUTPUTпостійної всередині. :(
Ентоні Аткінсон

Відмінно! Я хотів би знати, як ви це виявили;)
Ентоні Аткінсон

1
Я переглянув один із своїх проектів, але, здається, він також є тут: github.com/FasterXML/jackson-databind у розділі "Загальновживані функції"
gregwhitaker

Необхідний імпорт - імпорт com.fasterxml.jackson.databind. {SerializationFeature, ObjectMapper}
1313

2
в 2.2.1 це мені потрібно: імпорт org.codehaus.jackson.map.SerializationConfig.Feature; mapper.enable (Feature.INDENT_OUTPUT);
гарнітур

46

Згідно з мкьонгом , магічний заклик полягає defaultPrintingWriterу гарному друкуванні JSON :

Новіші версії:

System.out.println(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonInstance));

Старіші версії:

System.out.println(mapper.defaultPrettyPrintingWriter().writeValueAsString(jsonInstance));

Здається, я швидко стрибнув пістолет. Ви можете спробувати gson , конструктор якого підтримує гарне друкування :

Gson gson = new GsonBuilder().setPrettyPrinting().create();
String jsonOutput = gson.toJson(someObject);

Сподіваюся, це допомагає ...


1
Я знайшов цю статтю і розчарувався, коли виявив, що це один із тих застарілих способів гарного друку. defaultPrettyPrintingWriter()більше не доступний (навіть як застарілий метод) для ObjectMapperкласу.
Ентоні Аткінсон

Я насправді думав про це, але моя заявка вже сильно орієнтована на Джексона, і всі функціональні можливості фактично завершені. Сервер веб-додатків, на якому він буде розміщений, вже обкладається досить великим податком, і я не хотів би завантажувати додаткові бібліотеки просто для реєстрації запитів та відповідей. Я, безумовно, буду голосувати за вашу відповідь.
Ентоні Аткінсон

7
@AnthonyAtkinson у Джексона 2.3 є методObjectMapper.writerWithDefaultPrettyPrinter()
matt b

36

API Джексона змінився:

new ObjectMapper()
.writer()
.withDefaultPrettyPrinter()
.writeValueAsString(new HashMap<String, Object>());

3
Ще можна (з Джексоном 2.7.6) використовувати new ObjectMapper().configure(SerializationFeature.INDENT_OUTPUT, true).writer().writeValueAsString(new HashMap<String, Object>());. Вам просто потрібно переконатися, що ви використовуєте письменник, який ви отримали від налаштованого ObjectMapper.
Мартін

3

IDENT_OUTPUT нічого не зробив для мене, і щоб дати повну відповідь, яка працює з моїми банками Jackson 2.2.3:

public static void main(String[] args) throws IOException {

byte[] jsonBytes = Files.readAllBytes(Paths.get("C:\\data\\testfiles\\single-line.json"));

ObjectMapper objectMapper = new ObjectMapper();

Object json = objectMapper.readValue( jsonBytes, Object.class );

System.out.println( objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString( json ) );
}

0

Якщо ви хочете включити це за замовчуванням для ВСІХ примірників ObjectMapper в процесі, ось невеликий хак, який встановить значення за замовчуванням INDENT_OUTPUT на істинне:

val indentOutput = SerializationFeature.INDENT_OUTPUT
val defaultStateField = indentOutput.getClass.getDeclaredField("_defaultState")
defaultStateField.setAccessible(true)
defaultStateField.set(indentOutput, true)

0

якщо ви використовуєте комбінацію весна та Джексона, ви можете зробити це наступним чином. Я дотримуюся @gregwhitaker, як пропонується, але реалізую у весняному стилі.

<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper">
    <property name="dateFormat">
        <bean class="java.text.SimpleDateFormat">
            <constructor-arg value="yyyy-MM-dd" />
            <property name="lenient" value="false" />
        </bean>
    </property>
    <property name="serializationInclusion">
        <value type="com.fasterxml.jackson.annotation.JsonInclude.Include">
            NON_NULL
        </value>
    </property>
</bean>

<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref bean="objectMapper" />
    </property>
    <property name="targetMethod">
        <value>enable</value>
    </property>
    <property name="arguments">
        <value type="com.fasterxml.jackson.databind.SerializationFeature">
            INDENT_OUTPUT
        </value>
    </property>
</bean>

0

Якщо інші, хто переглядає це питання, мають лише рядок JSON (не в об'єкті), то ви можете помістити його в HashMapі все-таки приступити ObjectMapperдо роботи. resultМінлива ваша рядок JSON.

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.HashMap;
import java.util.Map;

// Pretty-print the JSON result
try {
    ObjectMapper objectMapper = new ObjectMapper();
    Map<String, Object> response = objectMapper.readValue(result, HashMap.class);
    System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(response));
} catch (JsonParseException e) {
    e.printStackTrace();
} catch (JsonMappingException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
} 

-8

Спробуйте це.

 objectMapper.enable(SerializationConfig.Feature.INDENT_OUTPUT);

13
Дублювання обраної відповіді через 7 місяців насправді не корисне.
Ігор Родрігес

1
може допомогти комусь, як я вже згадував в одному рядку, я відчуваю себе добре в обміні тим, що я знаю.
почувайтеся добре і програмуйте
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.