web-dev-qa-db-fra.com

Comment puis-je obtenir le ObjectMapper Jackson utilisé par Spring 4.1?

Spring 4.1 instancie une instance de Jackson ObjectMapper. J'ai des raisons de vouloir @Autowire cette instance dans l'un de mes contrôleurs: le contrôleur effectue lui-même une analyse JSON mineure à l'aide de Jackson, mais la variable ObjectMapper qu'il utilise doit être celle qui est utilisée par Spring. Comment puis-je accomplir cela?

Notez que je ne vous demande pas comment personnaliser la ObjectMapper utilisée par Spring; Je suis content des défauts. Je veux juste récupérer l'instance utilisée par Spring afin de pouvoir réutiliser l'instance existante dans mon propre code.

37
Adam Maass

Si vous utilisez Spring Boot avec Jackson sur votre chemin d'accès aux classes et sur l'implémentation par défaut pour l'analyse JSON dans votre contrôleur REST, cela devrait alors fonctionner:

@Autowired
private ObjectMapper jacksonObjectMapper;
34
Tuno

Si vous jetez un coup d'œil à MappingJackson2HttpMessageConverter, vous verrez qu'il crée une nouvelle ObjectMapper, mais ne l'expose pas sous forme de bean. Il y a un getter, mais la seule façon de l'exploiter par le passé est de créer moi-même le MappingJackson2HttpMessageConverter, par exemple.

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);
    }
}

Si vous travaillez avec Spring Boot, il y a une section dans le manuel dédiée à l'utilisation de ObjectMapper Si vous créez un Jackson2ObjectMapperBuilder@Bean par défaut, vous devriez pouvoir autoriser automatiquement la même instance ObjectMapper dans votre contrôleur. 

11

Comme d'autres l'ont dit, vous ne pouvez pas @Autowired le directement dans votre contrôleur. 

La suggestion de @Emerson Farrugia de créer une nouvelle instance à l'aide de 

Jackson2ObjectMapperBuilder.json().build()

cela ne fonctionnait pas non plus pour moi car l'instance obtenue ne suivait pas les propriétés de configuration spring.jackson.*, ce dont j'avais besoin.


La solution que j'ai trouvée consistait à obtenir l'ObjectMapper à partir du MappingJackson2HttpMessageConverter de Spring, qui est injectable.

Alors je l'ai auto-câblé:

@Autowired
private MappingJackson2HttpMessageConverter springMvcJacksonConverter;

puis récupérez le ObjectMapper comme ceci:

ObjectMapper objectMapper = springMvcJacksonConverter.getObjectMapper();

Cette instance se comporte exactement comme la conversion de message propre à Spring MVC - elle est probablement est de toute façon la même instance.

10
netmikey

Un deux pas si vous voulez;

  1. Dans votre classe @SpringBootApplication, ajoutez:

    @Bean
    public ObjectMapper mapper() {
      return new ObjectMapper();
    }
    
  2. Où que vous souhaitiez utiliser ObjectMapper:

    @Autowired
    ObjectMapper mapper;
    

Paix!

2
Sharan Arumugam

La ObjectMapper est créée par Jackson2ObjectMapperBuilder et vous pouvez injecter le générateur en utilisant:

@Autowired
private Jackson2ObjectMapperBuilder mapperBuilder;

Utilisez ensuite mapperBuilder.build() pour créer une instance ObjectMapper. Cette instance peut utiliser des configurations dans application.properties. Doc officiel ici.

1
Lym Zoy

Lorsque vous essayez de @Autowire MappingJackson2HttpMessageConverter, il vous donne: No qualifying bean of type 'org.springframework.http.converter.json.MappingJackson2HttpMessageConverter' available: expected single matching bean but found 4: mappingJackson2HttpMessageConverter,jacksonHttpMessageConverter,halJacksonHttpMessageConverter,alpsJsonHttpMessageConverter.

Ce n'est pas un gros problème, vous pouvez simplement changer le nom de votre variable en l'un des éléments ci-dessus pour obtenir cette instance: @Autowired private MappingJackson2HttpMessageConverter halJacksonHttpMessageConverter;

0
AngelVel