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

31

我太过不理智,使用注解而不是纯xml来配置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 被创建了,但是另一个转换器实例被创建并在通道中使用。因此,我尝试了 这个 Stackoverflow 问题 中描述的使用 @Configuration@Bean 的方法,但是 JSON 序列化仍然使用自己的配置。

最后,我尝试通过注入 mapper 来解决问题。

@Autowired
private MappingJacksonHttpMessageConverter jacksonConverter;

但现在我遇到了NoSuchBeanDefinitionException的问题。所以我已经没有其他选择,现在想在这里询问一些想法。如何控制和配置框架使用的映射器?


尝试将有线字段的名称更改为 jsonHttpMessageConverter,如 @Autowired private MappingJacksonHttpMessageConverter jsonHttpMessageConverter; - Ahamed Mustafa M
3个回答

63

使用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 才能配置转换器。


2
在我的情况下,仍然只创建了另一个MappingJacksonHttpMessageConverter实例,并且它不是随后使用的那个。 - Danubian Sailor
1
似乎取决于添加转换器的顺序,是先添加自己的转换器还是默认的转换器。当我按照上述描述先添加自己的转换器时,对我来说可以正常工作。 - user405935
另外,不要忘记版本必须兼容。我正在使用Spring 4.*,并尝试了几个小时来与Jackson 1.*进行设置 - 没有成功。然后,我发现他们在Jasckson 2.*中将artifact更改为com.fasterxml.jackson.core:jackson-databind。我更改了依赖项->像魔法一样工作(无需configureMessageConverters);) - pkopac
4
“重要提示”救了我!谢谢! - Beto Neto
2
由于某些未知原因,这对我不起作用。可能是因为我有类扩展了WebMvcConfigurationSupport和其他类扩展了WebMvcConfigurerAdapter?当应用程序启动时进行调试,在两种情况下,代码都由Spring执行。但是在调用控制器时,仍然没有使用我的配置对象映射器。 - Wrench
显示剩余8条评论

27

使用纯Java代码自定义Spring MVC Servlet配置可以有多种方法。

其中最简单的一种似乎是通过将您的@Configuration注释类扩展为WebMvcConfigurerAdapter

@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文档自定义提供的配置


2
为什么方法converter()必须标记为@Bean - Mikhail Batcer
1
JavaDoc:将转换器添加到列表中会关闭默认的转换器注册。如果只想简单地添加转换器而不影响默认注册,请考虑使用方法extendMessageConverters(java.util.List)。 - xedo
2
@MikhailBatcer - @Bean注解的作用是将该方法返回的对象放置在容器(Spring)上下文中,以便您可以从容器中使用它。另请参见问题以获取答案的背景信息。 - José Andias

-1
以下解决方案适用于Spring 4.3(非boot),其中需要通过添加模块到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处理器中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接