it-roy-ru.com

Как настроить MappingJacksonHttpMessageConverter при использовании конфигурации на основе весенних аннотаций?

Я был достаточно неразумен, чтобы заняться настройкой весенних компонентов с помощью аннотаций, а не чисто XML-компонентов, и теперь я сталкиваюсь с последствиями.

Я настраиваю REST каналы, используя

<mvc:annotation-driven />

Теперь я хочу просто настроить MappingJacksonHttpMessageConverter для вывода в JSON только тех полей, которые имеют ненулевые значения. Я пробовал следующее:

<bean id="jsonHttpMessageConverter"
    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
    <property name="prefixJson" value="false" />
    <property name="supportedMediaTypes" value="application/json" />
    <property name="objectMapper">
        <bean class="org.codehaus.jackson.map.ObjectMapper">
            <property name="serializationInclusion" value="NON_NULL"/>
        </bean>
    </property>
</bean>

Бины создаются, но в каналах создается и используется другой экземпляр конвертера. Итак, я попробовал способ с @Configuration и @Bean, описанными в этот вопрос Stackoverflow , но сериализация json все же использует свою собственную конфигурацию.

Наконец я попытался ввести маппер через 

@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

но я закончил с NoSuchBeanDefinitionException. Так что теперь у меня нет вариантов, и поэтому я прошу любые идеи здесь. Как контролировать и настраивать маппер, используемый фреймворком?

29
Danubian Sailor

Используйте WebMvcConfigurer.configureMessageConverters() метод:

Сконфигурируйте HttpMessageConverters для использования [...] Если конвертеры сообщений не добавляются в список, вместо них добавляются конвертеры по умолчанию.

С @Configuration у вас есть:

@Configuration
class MvcConf extends WebMvcConfigurationSupport {
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(converter());
        addDefaultHttpMessageConverters(converters);
    }

    @Bean
    MappingJacksonHttpMessageConverter converter() {
        MappingJacksonHttpMessageConverter converter = new MappingJacksonHttpMessageConverter()
        //do your customizations here...
        return converter;
    }
}

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

ВАЖНОЕ ПРИМЕЧАНИЕ Вы должны удалить @EnableWebMvc для настройки ваших конвертеров, если вы расширяете WebMvcConfigurationSupport.

57
Tomasz Nurkiewicz

Настройка конфигурации сервлета spring mvc только в коде Java может быть выполнена несколькими способами.

Кажется, самый простой способ - расширить аннотированный класс @Configuration с помощью WebMvcConfigurerAdapter:

@Configuration
@EnableWebMvc
public class ApplicationSpringConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters( List<HttpMessageConverter<?>> converters ) {
        converters.add(converter());
    }

    @Bean
    MappingJackson2HttpMessageConverter converter() {
        // [...]
    }
}

Обратите внимание, что это очень похоже на пример, приведенный в ответе Tomasz Nurkiewicz.

Однако использование WebMvcConfigurationSupport вместо WebMvcConfigurerAdapter более подходит для расширенных настроек. Это было в том случае, если вам нужно было также добавить конвертеры по умолчанию.

См. Документацию Spring Настройка предоставленной конфигурации

26
José Andias

Следующее решение предназначено для Spring 4.3 (без загрузки), где необходимо было обратиться к fetch=FetchType.LAZY, добавив модуль в преобразователи Джексона. Подобную технику можно использовать для модификации преобразователей любым способом, включая удаление и восстановление.

@Configuration
@EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {

@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {

    for (HttpMessageConverter<?> mc : converters){
         if (mc instanceof MappingJackson2HttpMessageConverter || mc instanceof MappingJackson2XmlHttpMessageConverter) {
            ((AbstractJackson2HttpMessageConverter) mc).getObjectMapper().registerModule(new Hibernate5Module());
        }
    }
    return;
 }

В этом случае, 

  • WebMvcConfigurerAdapter содержит много других настроек, и я хотел бы избежать другого класса конфигурации.
  • Использование extendMessageConverters разрешило доступ к автоматически конфигурируемым классам Джексона, не теряя конфигурацию всех других конвертеров сообщений, что и было бы configureMessageConverters
  • Используя registerModule, вы можете просто добавить необходимый Hibernate5Module к существующим конвертерам. 
  • Модуль был добавлен к процессорам JSON и XML
0
sdw