如何将JAXB注释与Spring Resttemplate一起使用



我正在尝试使用Spring的RestTemplate自动估算XML格式化响应。我正在使用Jackson的jackson-dataformat-xml模块,该模块将Spring Boot设置为自动配置。我想在我想挑选的课堂中使用JAXB注释,但似乎行不通。这是我希望课的样子的样本:

@XmlRootElement(name="Book")
public class Book {
    @XmlElement(name="Title")
    private String title;
    @XmlElement(name="Author")
    private String author;
}

这是基于以下XML样本:

<Book>
    <Title>My Book</Title>
    <Author>Me</Author>
</Book>

但是,随着上述类似的类注释,这些字段始终设置为null。我做了一些实验,发现如果我使用杰克逊的@JsonProperty来注释孩子元素,则可以进行挑战:

@XmlRootElement(name="Book")
public class Book {
    @JsonProperty("Title")
    private String title;
    @JsonProperty("Author")
    private String author;
}

它有效,但我觉得这有点尴尬。是否有一种方法可以像我的第一个示例一样使JAXB注释起作用?

Jackson提供了用于XML数据限制的jackson-module-jaxb-annotations模块,以使用JAXB注释。但是,我不确定如何设置RestTemplate使用此模块的ObjectMapper

要解决此问题,我需要将JaxbAnnotationModule的实例注册到添加到Spring的RestTemplate中使用的每个ObjectMapper。该课程包括在Jackson的jackson-module-jaxb-annotations模块中,我通过Gradle添加到构建中。

随着我项目添加的依赖关系,我接下来做的是配置应用程序使用的RestTemplateObjectMapper实例由MappingJackson2XmlHttpMessageConverter s在春季自动配置。我必须将JaxbAnnotationModule实例注册到每个转换器中使用的每个ObjectMapper,因此第一个任务是使用:

找到所有MappingJackson2XmlHttpMessageConverter s
//create module
JaxbAnnotationModule jaxbAnnotationModule = new JaxbAnnotationModule();
restTemplate.getMessageConverters().stream().filter(converter -> {
    return converter instanceof MappingJackson2XmlHttpMessageConverter;
})

我拥有所有相关转换器后,我将模块注册到其ObjectMappers中的每个:

forEach(converter -> {
    ((MappingJackson2XmlHttpMessageConverter) converter)
            .getObjectMapper()
            .register(jaxbAnnotationModule);
});

如果某人仍然必须处理这种问题,Springboot提供了一个优雅的解决方案:

com.fasterxml.jackson.databind.module的任何bean bean均自动在自动配置的jackson2objectmapperbuilder上自动注册,并将其应用于其创建的任何对象mapper实例。这为您在应用程序添加新功能时提供了一个全球机制,可以贡献自定义模块。

因此,将其添加到您的一个配置类中应该足够:

@Bean
public Module jaxbModule() {
    return new JaxbAnnotationModule();
}

来源:https://docs.spring.io/spring-boot/docs/current/referent/referent/html/howto.html#howto-howto-howto-customize-customize-the-jackson-objectmapper

如果@psycho punch的解决方案仍然不适用于您,这是另一种选择:

  • 添加com.fasterxml.jackson.dataformat:jackson-dataformat-xml依赖项。
  • 将XMLMAPPER代替对象模具使用MappingJackson2XmlHttpMessageConverter。例如:

    XmlMapper xmlMapper = new XmlMapper();
    xmlMapper.registerModule(new JaxbAnnotationModule());
    forEach(converter -> {
        ((MappingJackson2XmlHttpMessageConverter) converter).setObjectMapper(xmlMapper)
    });
    

hth

我怀疑在第二种情况下,春季只是忽略了根级jaxb注释,因为默认情况下,杰克逊将正确解析类的名称。

要使用JAXB注释,您必须使用库jackson-xc

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-xc</artifactId>
</dependency>

这些艺术品也可能有用:

1)http://wiki.fasterxml.com/jacksonjaxbannotations

2)http://springinpractice.com/2011/12/06/jackson-json-json-jaxb2-xml-spring

3)使用RESTTEMPLATE时如何配置内部杰克逊映射器?

最新更新