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

Posted

技术标签:

【中文标题】使用基于spring注解的配置时如何配置MappingJacksonHttpMessageConverter?【英文标题】:How to configure MappingJacksonHttpMessageConverter while using spring annotation-based configuration? 【发布时间】:2012-05-25 21:13:27 【问题描述】:

我不合理地通过注释而不是纯 xml bean 来配置 spring bean,现在我正面临后果。

我使用配置 REST 通道

<mvc:annotation-driven />

现在我只想将MappingJacksonHttpMessageConverter 配置为仅将具有非空值的字段输出到 JSON。我尝试了以下方法:

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

bean 被创建,但另一个转换器实例被创建并在通道中使用。所以我尝试了this *** question中描述的@Configuration@Bean的方式,但json序列化仍然使用自己的配置。

最后我尝试通过

注入映射器
@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

但我以NoSuchBeanDefinitionException 结束。所以现在我别无选择,因此我在这里寻求任何想法。如何控制和配置framework使用的mapper?

【问题讨论】:

尝试将连线字段的名称更改为jsonHttpMessageConverter,如@Autowired private MappingJacksonHttpMessageConverter jsonHttpMessageConverter; 【参考方案1】:

使用WebMvcConfigurer.configureMessageConverters() 方法:

将 HttpMessageConverters 配置为使用 [...] 如果未将消息转换器添加到列表中,则会添加默认转换器。

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

需要调用addDefaultHttpMessageConverters(),因为使用自定义转换器时不会应用默认值。

重要提示如果您扩展 WebMvcConfigurationSupport,则必须删除 @EnableWebMvc 才能配置转换器。

【讨论】:

仍然,在我的情况下,只创建了另一个 MappingJacksonHttpMessageConverter 实例,它不是之后使用的实例 这似乎取决于添加转换器与默认转换器的顺序。当我像上面描述的那样首先添加自己的转换器时,它对我有用。 另外,不要忘记 版本 必须兼容。我正在使用 Spring 4.* 并且我尝试了几个小时来使用 Jackson 1.* 进行设置 - 没有用。然后,我发现,他们在 Jasckson 2.* 中将工件更改为 com.fasterxml.jackson.core:jackson-databind。我更改了依赖项-> 像魅力一样工作(没有 configureMessageConverters);) “重要提示”救了我!谢谢! 不知什么原因,这对我不起作用。可能是因为我有扩展WebMvcConfigurationSupport 的类和扩展WebMvcConfigurerAdapter 的其他类?在这两种情况下,应用程序启动时的调试都显示,代码由 Spring 执行。但是在调用控制器时仍然不是我的配置的对象映射器。【参考方案2】:

仅在java代码中自定义spring mvc servlet配置可以通过多种方式完成。

最简单的方法似乎是用WebMvcConfigurerAdapter 扩展您的@Configuration 注释类:

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

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

请注意,这很像 Tomasz Nurkiewicz 的答案提供的示例。

但是,使用 WebMvcConfigurationSupport 而不是 WebMvcConfigurerAdapter 更适合高级自定义。如果您还需要添加默认转换器,就是这种情况。

请参阅 Spring 文档Customizing the Provided Configuration

【讨论】:

为什么方法converter()必须用@Bean标记? JavaDoc:将转换器添加到列表中,关闭默认转换器注册。要在不影响默认注册的情况下简单地添加转换器,请考虑改用方法 extendMessageConverters(java.util.List)。 @MikhailBatcer - 放置了@Bean 注释,因此您可以在容器(弹簧)上下文中使用此方法返回的对象。另请参阅问题以了解答案上下文。【参考方案3】:

以下解决方案适用于 Spring 4.3(非引导),需要通过向 Jackson 转换器添加模块来解决 fetch=FetchType.LAZY。可以使用类似的技术以任何方式修改转换器,包括删除和重新创建。

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

在这种情况下,

WebMvcConfigurerAdapter 中有很多其他配置,我想避免使用其他配置类。 使用extendMessageConverters 可以访问自动配置的Jackson 类,而不会丢失所有其他消息转换器的配置,这正是configureMessageConverters 所做的。 使用registerModule,您可以简单地将所需的Hibernate5Module 添加到现有转换器中。 该模块已添加到 JSON 和 XML 处理器中

【讨论】:

以上是关于使用基于spring注解的配置时如何配置MappingJacksonHttpMessageConverter?的主要内容,如果未能解决你的问题,请参考以下文章

Spring之基于Java配置

如何纯注解整合Spring SpringMVC Mybatis

Spring基于注解@Required配置

Spring使用@Scheduled注解配置定时任务

spring学习5:基于注解实现spring的aop

基于注解的 AOP 配置