it-roy-ru.com

Как получить Jackson ObjectMapper, используемый Spring 4.1?

Spring 4.1 создает экземпляр экземпляра ObjectMapper Джексона. У меня есть причина хотеть @Autowire этого экземпляра в один из моих контроллеров: контроллер выполняет небольшой анализ JSON самостоятельно, используя Jackson, но ObjectMapper, который он использует, должен быть тем же экземпляром, который использует сам Spring. Как мне добиться этого?

Обратите внимание, что я не спрашиваю, как настраивать ObjectMapper, используемый Spring; Я доволен настройками по умолчанию. Я просто хочу выловить экземпляр, используемый Spring, чтобы я мог повторно использовать существующий экземпляр в своем собственном коде.

37
Adam Maass

Если вы используете Spring Boot с Джексоном на вашем пути к классам и реализацию по умолчанию для анализа JSON в вашем контроллере REST, то это должно работать:

@Autowired
private ObjectMapper jacksonObjectMapper;
34
Tuno

Если вы посмотрите на MappingJackson2HttpMessageConverter, вы увидите, что он создает новый ObjectMapper, но не представляет его как bean-компонент. Есть геттер, но единственный способ, которым я выловил его в прошлом, - это когда я сам создал MappingJackson2HttpMessageConverter, например.

public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

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

        MappingJackson2HttpMessageConverter jacksonMessageConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = jacksonMessageConverter.getObjectMapper();

        objectMapper.registerModule(new JodaModule());
        objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);

        converters.add(jacksonMessageConverter);
    }
}

Если вы работаете с Spring Boot, в руководстве есть раздел , посвященный работе с ObjectMapper. Если вы создаете Jackson2ObjectMapperBuilder@Bean по умолчанию, вы сможете автоматически подключить тот же экземпляр ObjectMapper в свой контроллер. 

11
Emerson Farrugia

Как говорили другие, вы не можете @Autowired прямо в свой контроллер. 

Предложение @Emerson Farrugia создать новый экземпляр, используя 

Jackson2ObjectMapperBuilder.json().build()

также не работал для меня, потому что полученный экземпляр не соответствовал свойствам конфигурации spring.jackson.*, что мне и требовалось.


Решение, которое я нашел, состояло в том, чтобы получить ObjectMapper из MappingJackson2HttpMessageConverter Spring, который является инъекционным.

Так что я сделал это автоматически:

@Autowired
private MappingJackson2HttpMessageConverter springMvcJacksonConverter;

а затем получить ObjectMapper из него следующим образом:

ObjectMapper objectMapper = springMvcJacksonConverter.getObjectMapper();

Этот экземпляр ведет себя точно так же, как и собственное преобразование сообщений Spring MVC - в любом случае, он, вероятно, is тот же экземпляр.

10
netmikey

Двухступенчатый, если хотите;

  1. В своем классе @SpringBootApplication добавьте:

    @Bean
    public ObjectMapper mapper() {
      return new ObjectMapper();
    }
    
  2. Везде, где вы хотите использовать ObjectMapper:

    @Autowired
    ObjectMapper mapper;
    

Мир!

2
Sharan Arumugam

ObjectMapper создается Jackson2ObjectMapperBuilder, и вы можете внедрить компоновщик используя:

@Autowired
private Jackson2ObjectMapperBuilder mapperBuilder;

Затем используйте mapperBuilder.build() для создания экземпляра ObjectMapper, и этот экземпляр может использовать конфигурации в application.properties. Официальный документ здесь.

1
Lym Zoy

Когда вы пытаетесь @Autowire MappingJackson2HttpMessageConverter, он дает вам: No qualifying bean of type 'org.springframework.http.converter.json.MappingJackson2HttpMessageConverter' available: expected single matching bean but found 4: mappingJackson2HttpMessageConverter,jacksonHttpMessageConverter,halJacksonHttpMessageConverter,alpsJsonHttpMessageConverter.

Это не большая проблема, вы можете просто изменить имя переменной на одно из приведенных выше, чтобы получить этот экземпляр: @Autowired private MappingJackson2HttpMessageConverter halJacksonHttpMessageConverter;

0
AngelVel