如何在Spring Boot应用程序中自动装配默认的XmlMapper

ci_*_*ci_ 3 xmlmapper spring-boot

我有一些问题XmlMapper在我的一个Spring Boot项目中自动装配默认的Jackson .我已经创建了一个简单的示例项目来说明这一点.

我在这里做的大致基于这个:

http://docs.spring.io/spring-boot/docs/1.2.2.RELEASE/reference/htmlsingle/#howto-write-an-xml-rest-service

http://docs.spring.io/spring-boot/docs/1.2.2.RELEASE/reference/htmlsingle/#howto-customize-the-jackson-objectmapper

来自pom.xml

<!-- ... -->

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.2.2.RELEASE</version>
</parent>

<!-- ... -->

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.dataformat</groupId>
        <artifactId>jackson-dataformat-xml</artifactId>
    </dependency>
</dependencies>

<!-- ... -->
Run Code Online (Sandbox Code Playgroud)

主要课程:

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

演示POJO,没有指定@XmlRootElement,所以它不会使用JAXB:

@JsonInclude(Include.NON_NULL)
public class Demo {
    private String stringProperty;
    private int intProperty;
    public String getStringProperty() {
        return stringProperty;
    }
    public void setStringProperty(String stringProperty) {
        this.stringProperty = stringProperty;
    }
    public int getIntProperty() {
        return intProperty;
    }
    public void setIntProperty(int intProperty) {
        this.intProperty = intProperty;
    }
}
Run Code Online (Sandbox Code Playgroud)

演示控制器:

@RestController
public class DemoController {
    @Autowired 
    private ObjectMapper objectMapper;
    // @Autowired 
    // private XmlMapper xmlMapper;

    @RequestMapping(value = "/demo", method = RequestMethod.GET)
    public Demo getDemo() {
        Demo demo = new Demo();
        demo.setStringProperty("Hello world!");
        demo.setIntProperty(42);
        return demo;
    }
}
Run Code Online (Sandbox Code Playgroud)

一切都按照它的方式工作,取决于Accept标题,将返回JSON或XML.

我可以轻松自动装配ObjectMapperSpring Boot配置的默认值.到现在为止还挺好.

如果我评论XmlMapper我得到的自动装配:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.fasterxml.jackson.dataformat.xml.XmlMapper] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1301)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1047)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:533)
... 18 more
Run Code Online (Sandbox Code Playgroud)

知道为什么会这样吗?我会假设它的工作方式与ObjectMapper.相同.只是为了澄清,我并不想自定义映射器,我只是想通过春季启动创建的默认的一个参考.

ci_*_*ci_ 16

根据@Andy Wilkinson的回答,我做了一些挖掘工作,找到了一种方法来获得我想要的东西.Spring Boot不公开XmlMapper作为Bean,但它确实公开了它所使用的消息转换器,即MappingJackson2XmlHttpMessageConverter.所以我可以自动连接那个bean并从中获取ObjectMapper(现在是XmlMapper).

我的问题的演示控制器现在看起来像这样:

@RestController
public class DemoController {
    @Autowired 
    private ObjectMapper objectMapper;
    @Autowired
    private MappingJackson2XmlHttpMessageConverter xmlConverter;

    @RequestMapping(value = "/demo", method = RequestMethod.GET)
    public Demo getDemo() {
        Demo demo = new Demo();
        demo.setStringProperty("Hello world!");
        demo.setIntProperty(42);
        ObjectMapper xmlMapper = xmlConverter.getObjectMapper();
        return demo;
    }
}
Run Code Online (Sandbox Code Playgroud)


And*_*son 10

Spring Boot不公开XmlMapperbean作为bean,因为它会与ObjectMapper用于JSON映射的bean 冲突(Jackson的XmlMapper是Jackson的子类ObjectMapper).

  • 这回答了当然的问题.隐含的下一个问题是,"我可以通过其他方式获取XmlMapper吗?",我发现你可以自动装配`MappingJackson2XmlHttpMessageConverter`并通过`.getObjectMapper()`获取`XmlMapper`. (6认同)
  • 我试图用最新的 Spring-Boot 做同样的事情,但发现我无法自动装配 ObjectMapper 或 MappingJackson2XmlHttpMessageConverter。两者都会导致“没有合格的 bean 类型”错误。 (2认同)