使用基于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?的主要内容,如果未能解决你的问题,请参考以下文章