简体   繁体   English

如何在使用基于spring注释的配置时配置MappingJacksonHttpMessageConverter?

[英]How to configure MappingJacksonHttpMessageConverter while using spring annotation-based configuration?

I was unreasonable enough to went into configuring spring beans via annotations and not pure xml beans and now I'm facing the consequences. 我不合理地通过注释而不是纯xml bean来配置spring bean,现在我正面临着后果。

I configure REST channels using 我使用配置REST通道

<mvc:annotation-driven />

Now I want simply configure the MappingJacksonHttpMessageConverter to output to JSON only this fields that have non-null values. 现在我只想配置MappingJacksonHttpMessageConverter ,只输出具有非空值的字段。 I've tried the following: 我尝试过以下方法:

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

The beans gets created, but another instance of converter is created and used in channels. Bean已创建,但转换器的另一个实例已创建并在通道中使用。 So I've tried the way with @Configuration and @Bean described in this Stackoverflow question , but still json serialization uses its own configuration. 所以我已经尝试了在这个Stackoverflow问题中描述的@Configuration@Bean ,但json序列化仍然使用自己的配置。

Finally I've tried to inject the mapper via 最后我试图通过注入mapper

@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

but I've ended with NoSuchBeanDefinitionException . 但我以NoSuchBeanDefinitionException结束了。 So now I'm out of options and therefore I'm asking for any ideas here. 所以现在我没有选择,所以我在这里要求任何想法。 How to controll and configure the mapper used by framework? 如何控制和配置框架使用的映射器?

Use the WebMvcConfigurer.configureMessageConverters() method: 使用WebMvcConfigurer.configureMessageConverters()方法:

Configure the HttpMessageConverters to use [...] If no message converters are added to the list, default converters are added instead. 配置HttpMessageConverters以使用[...]如果列表中未添加任何消息转换器,则会添加默认转换器。

With @Configuration you have: 使用@Configuration你有:

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

Call to addDefaultHttpMessageConverters() is required because the defaults are not applied when using custom converters. 需要调用addDefaultHttpMessageConverters() ,因为使用自定义转换器时不会应用默认值。

IMPORTANT NOTE You must remove @EnableWebMvc for your converters to be configured if you extend WebMvcConfigurationSupport. 重要提示您必须删除@EnableWebMvc你的转换器,如果你扩展WebMvcConfigurationSupport进行配置。

The customization of the spring mvc servlet configuration only in java code can be accomplished in multiple ways. 仅在java代码中定制spring mvc servlet配置可以通过多种方式完成。

The simplest one seems to be extending your @Configuration annotated class with WebMvcConfigurerAdapter : 最简单的似乎是使用WebMvcConfigurerAdapter扩展您的@Configuration注释类:

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

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

Notice that this is lot like the example provided by the answer of Tomasz Nurkiewicz . 请注意,这很像Tomasz Nurkiewicz的答案所提供的示例。

However using WebMvcConfigurationSupport instead of WebMvcConfigurerAdapter is more appropriate for Advanced Customizations. 但是,使用WebMvcConfigurationSupport而不是WebMvcConfigurerAdapter更适合高级自定义。 That was the case if you needed to also add the default converters. 如果您还需要添加默认转换器,则会出现这种情况。

See the Spring documentation Customizing the Provided Configuration 请参阅Spring文档自定义提供的配置

The following solution is for Spring 4.3, (non-boot) where it was necessary to address fetch=FetchType.LAZY by adding a module to the Jackson converters. 以下解决方案适用于Spring 4.3(非启动),其中需要通过向Jackson转换器添加模块来解决fetch=FetchType.LAZY A similar technique can be used to modify converters in any way, including removal and recreation. 可以使用类似的技术以任何方式修改转换器,包括移除和重新创建。

@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 this case, 在这种情况下,

  • the WebMvcConfigurerAdapter has a lot of other configuration in it and I wanted to avoid another configuration class. WebMvcConfigurerAdapter有很多其他配置,我想避免另一个配置类。
  • Using extendMessageConverters enabled access to the automatically-configured Jackson classes without losing the configuration of all other message converters, which is what configureMessageConverters would have done. 使用extendMessageConverters可以访问自动配置的Jackson类,而不会丢失所有其他消息转换器的配置,这就是configureMessageConverters所做的。
  • Using registerModule you can simply add the needed Hibernate5Module to the existing converters. 使用registerModule您只需将所需的Hibernate5Module添加到现有转换器即可。
  • The module was added to both the JSON and XML processors 该模块已添加到JSON和XML处理器中

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM