web-dev-qa-db-fra.com

Comment configurer MappingJacksonHttpMessageConverter en utilisant une configuration à annotation par ressort?

J'étais assez déraisonnable pour entrer dans la configuration des haricots de printemps via des annotations et non des haricots xml purs et maintenant je suis confronté aux conséquences.

Je configure les canaux REST à l’aide de

<mvc:annotation-driven />

Maintenant, je veux simplement configurer la MappingJacksonHttpMessageConverter pour ne générer en JSON que les champs qui ont des valeurs non nulles. J'ai essayé ce qui suit:

<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>

Les beans sont créés, mais une autre instance de convertisseur est créée et utilisée dans les canaux. J'ai donc essayé le chemin avec @Configuration et @Bean décrit dans cette question de Stackoverflow , mais la sérialisation json utilise toujours sa propre configuration.

Enfin, j'ai essayé d'injecter le mappeur via 

@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

mais j'ai terminé avec NoSuchBeanDefinitionException. Alors maintenant, je n’ai plus d’options et je demande donc des idées ici. Comment contrôler et configurer le mappeur utilisé par le framework?

29
Danubian Sailor

Utilisez la méthode WebMvcConfigurer.configureMessageConverters() :

Configurez les convertisseurs HttpMessage pour qu'ils utilisent [...] Si aucun convertisseur de message n'est ajouté à la liste, les convertisseurs par défaut sont également ajoutés.

Avec @Configuration vous avez:

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

L'appel à addDefaultHttpMessageConverters() est requis car les valeurs par défaut ne sont pas appliquées lors de l'utilisation de convertisseurs personnalisés.

NOTE IMPORTANTE Vous devez supprimer @EnableWebMvc pour que vos convertisseurs soient configurés si vous étendez WebMvcConfigurationSupport.

57

La personnalisation de la configuration du servlet spring mvc uniquement en code Java peut être réalisée de plusieurs manières.

La plus simple semble étendre votre classe annotée @Configuration avec WebMvcConfigurerAdapter:

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

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

Notez que cela ressemble beaucoup à l'exemple fourni par la réponse de Tomasz Nurkiewicz.

Cependant, utiliser WebMvcConfigurationSupport au lieu de WebMvcConfigurerAdapter est plus approprié pour les personnalisations avancées. C'était le cas si vous deviez également ajouter les convertisseurs par défaut.

Voir la documentation de Spring Personnalisation de la configuration fournie

26
José Andias

La solution suivante concerne Spring 4.3 (non-boot) où il était nécessaire d'adresser fetch=FetchType.LAZY en ajoutant un module aux convertisseurs de Jackson. Une technique similaire peut être utilisée pour modifier les convertisseurs de quelque manière que ce soit, y compris le retrait et la récréation.

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

Dans ce cas, 

  • la WebMvcConfigurerAdapter contient beaucoup d'autres configurations et je voulais éviter une autre classe de configuration.
  • L’utilisation de extendMessageConverters pour permettre l’accès aux classes de Jackson automatiquement configurées sans perdre la configuration de tous les autres convertisseurs de message, comme l’avait fait configureMessageConverters 
  • En utilisant registerModulevous pouvez simplement ajouter le Hibernate5Module nécessaire aux convertisseurs existants. 
  • Le module a été ajouté aux processeurs JSON et XML.
0
sdw