webentwicklung-frage-antwort-db.com.de

Wie kann ich MappingJacksonHttpMessageConverter konfigurieren, während die auf Federn basierende Konfiguration verwendet wird?

Ich war unvernünftig genug, um Spring Beans über Annotationen und nicht über reine XML-Beans zu konfigurieren, und jetzt stehe ich vor den Konsequenzen.

Ich konfiguriere REST Kanäle mit

<mvc:annotation-driven />

Jetzt möchte ich einfach die MappingJacksonHttpMessageConverter so konfigurieren, dass nur diese Felder mit Nicht-Null-Werten an JSON ausgegeben werden. Ich habe folgendes versucht:

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

Die Beans werden erstellt, aber eine andere Instanz des Konverters wird erstellt und in Kanälen verwendet. Ich habe es übrigens mit @Configuration und @Bean aus dieser Stackoverflow-Frage ausprobiert, aber die json-Serialisierung verwendet immer noch ihre eigene Konfiguration.

Schließlich habe ich versucht, den Mapper über zu injizieren 

@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

aber ich habe mit NoSuchBeanDefinitionException geendet. Nun habe ich keine Optionen mehr und deshalb bitte ich hier nach Ideen. Wie kann ich den vom Framework verwendeten Mapper steuern und konfigurieren?

29
Danubian Sailor

Verwenden Sie die Methode WebMvcConfigurer.configureMessageConverters() :

Konfigurieren Sie die HttpMessageConverters für die Verwendung von [...]. Wenn der Liste keine Nachrichtenkonverter hinzugefügt werden, werden stattdessen Standardkonverter hinzugefügt.

Mit @Configuration haben Sie:

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

Ein Aufruf an addDefaultHttpMessageConverters() ist erforderlich, da die Standardwerte nicht angewendet werden, wenn benutzerdefinierte Konverter verwendet werden.

WICHTIGER HINWEIS Sie müssen @EnableWebMvc entfernen, damit Ihre Konverter konfiguriert werden, wenn Sie WebMvcConfigurationSupport erweitern.

57

Die Anpassung der Konfiguration des Spring MVC-Servlets nur in Java-Code kann auf verschiedene Arten erfolgen.

Die einfachste scheint die Erweiterung Ihrer @Configuration-Klasse mit WebMvcConfigurerAdapter zu sein:

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

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

Beachten Sie, dass dies dem Beispiel in der Antwort von Tomasz Nurkiewicz sehr ähnlich ist.

Die Verwendung von WebMvcConfigurationSupport anstelle von WebMvcConfigurerAdapter ist jedoch für erweiterte Anpassungen besser geeignet. Dies war der Fall, wenn Sie auch die Standardkonverter hinzufügen mussten.

Siehe die Spring-Dokumentation Anpassen der bereitgestellten Konfiguration

26
José Andias

Die folgende Lösung ist für Spring 4.3 (Nicht-Boot), bei der fetch=FetchType.LAZY durch Hinzufügen eines Moduls zu den Jackson-Konvertern adressiert werden musste. Eine ähnliche Technik kann verwendet werden, um Konverter auf beliebige Weise zu modifizieren, einschließlich Entfernen und Wiederherstellen.

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

In diesem Fall, 

  • die Variable WebMvcConfigurerAdapter enthält viele andere Konfigurationen und ich wollte eine andere Konfigurationsklasse vermeiden.
  • Durch die Verwendung von extendMessageConverters wurde der Zugriff auf die automatisch konfigurierten Jackson-Klassen aktiviert, ohne dass die Konfiguration aller anderen Nachrichtenkonverter verloren ging. Dies hätte configureMessageConverters getan. 
  • Mit registerModule können Sie einfach den benötigten Hibernate5Module zu den vorhandenen Konvertern hinzufügen. 
  • Das Modul wurde sowohl dem JSON- als auch dem XML-Prozessor hinzugefügt
0
sdw