Когда я отправил этот вопрос, у меня был ответ, но я все равно решил опубликовать его на случай, если найдутся лучшие альтернативные решения. Вот мой опыт:
Первым делом первым. MappingJacksonHttpMessageConverter
ожидает, что вы добавите экземпляр Jackson ObjectMapper
и выполните настройку Jackson для этого экземпляра (а не через класс Spring).
Я думал, это будет так же просто, как сделать это:
Создайте реализацию ObjectMapperFactoryBean
, которая позволит мне настроить экземпляр ObjectMapper
, который может быть внедрен в MappingJacksonHttpMessageConverter
. Например:
<bean id="jacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="objectMapper">
<bean class="com.foo.my.ObjectMapperFactoryBean">
<property name="prettyPrint" value="${json.prettyPrint}"/>
</bean>
</property>
</bean>
И затем, в моей реализации ObjectMapperFactoryBean
, я мог сделать это (как было задокументировано как решение в другом месте на SO):
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, isPrettyPrint());
return mapper;
Но это не сработало. И пытается выяснить, почему кошмар . Это серьезная проверка на терпение, чтобы понять Джексона. Взгляд на его исходный код только смущает вас, поскольку он использует устаревшие и тупые формы конфигурации (целочисленные битовые маски для включения / выключения функций? Вы шутите?)
Мне, по сути, пришлось переписать Spring 10 * с нуля, и переопределить его writeInternal
реализацию следующим образом:
@Override
protected void writeInternal(Object o, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
JsonEncoding encoding = getEncoding(outputMessage.getHeaders().getContentType());
JsonGenerator jsonGenerator =
getObjectMapper().getJsonFactory().createJsonGenerator(outputMessage.getBody(), encoding);
try {
if (this.prefixJson) {
jsonGenerator.writeRaw("{} && ");
}
if (isPrettyPrint()) {
jsonGenerator.useDefaultPrettyPrinter();
}
getObjectMapper().writeValue(jsonGenerator, o);
}
catch (JsonGenerationException ex) {
throw new HttpMessageNotWritableException("Could not write JSON: " + ex.getMessage(), ex);
}
}
Единственное, что я добавил в существующую реализацию, это следующий блок:
if (isPrettyPrint()) {
jsonGenerator.useDefaultPrettyPrinter();
}
isPrettyPrint()
- это просто геттер, совместимый с JavaBeans, с сеттером соответствия, который я добавил в свой подкласс MappingJacksonHttpMessageConverter
.
Только после перехода через эти обручи я смог включить или отключить красивую печать на основе моего значения ${json.prettyPrint}
(которое устанавливается как свойство в зависимости от того, как приложение развернуто).
Надеюсь, это поможет кому-то в будущем!