Как настроить 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 описанный в этом вопросе Stackru, но сериализация json по-прежнему использует свою собственную конфигурацию.

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

@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

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

2 ответа

Решение

Использовать 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.

Настройка конфигурации сервлета 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() {
        // [...]
    }
}

Обратите внимание, что это очень похоже на пример, приведенный в ответе Томаша Нуркевича.

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

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

Следующее решение для 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
Другие вопросы по тегам