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.
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;
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.
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.
Dans votre classe @SpringBootApplication
, ajoutez:
@Bean
public ObjectMapper mapper() {
return new ObjectMapper();
}
Où que vous souhaitiez utiliser ObjectMapper
:
@Autowired
ObjectMapper mapper;
Paix!
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.
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;