2015-03-02 2 views
2

У меня возникли проблемы с автозагрузкой по умолчанию Jackson XmlMapper в одном из моих проектов Spring Boot. Я создал простой пример проекта, который иллюстрирует это.Как использовать autwire по умолчанию XmlMapper в приложении Spring Boot

Что я делаю здесь примерно на этой основе:

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> 

<!-- ... --> 

Основной класс:

@SpringBootApplication 
public class DemoApplication { 

    public static void main(String[] args) { 
     SpringApplication.run(DemoApplication.class, args); 
    } 
} 

Демо 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; 
    } 
} 

Демо-контроллер:

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

Все отлично работает так, как она есть, в зависимости от Accept заголовков, либо JSON или XML будут возвращены.

Я могу легко автоустанавливать по умолчанию ObjectMapper, настроенный Spring 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 

Любую идею, почему это? Я бы предположил, что он работает так же, как и ObjectMapper. Просто уточнить, я не хочу Не хочу хочу настроить mappers, я просто хочу ссылку на созданные по умолчанию, созданные Spring Boot.

+0

Возможно Spring Загрузочный не содержит XmlMapper в IoC контейнер, попытаться придать боб первый. – kris14an

+0

Я знаю, что могу создать свой собственный XmlMapper, но я хочу, чтобы по умолчанию был тот, который фактически используется для сопоставления класса с Xml в теге ответа, который работает правильно прямо сейчас, поэтому должен быть XmlMapper где-то вправо ? @ kris14an –

ответ

6

Spring Загрузочный не выставляет XmlMapper как боб, как он будет конфликтовать с ObjectMapper боба, который используется для отображения JSON (Джексон XmlMapper является подклассом Джексона ObjectMapper).

+1

Это, конечно, отвечает на вопрос. Следующий вопрос был бы следующим: «могу ли я получить XmlMapper каким-то другим способом?», И я обнаружил, что вместо этого вы можете autowire «MappingJackson2XmlHttpMessageConverter» и получить «XmlMapper» через '.getObjectMapper()'. –

+1

Я пытаюсь сделать то же самое с самой последней Spring-Boot, но обнаруживаю, что не могу Autowire ObjectMapper или MappingJackson2XmlHttpMessageConverter. Оба результата приводят к ошибкам «Отсутствие квалификационного компонента типа». – robross0606

7

Основываясь на ответе от @Andy Wilkinson, я сделал еще несколько копаний и нашел способ получить то, что я хотел. Spring Boot не раскрывает XmlMapper в качестве компонента, но он использует отображаемый в нем конвертер сообщений, который равен 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; 
    } 
} 
+1

Я пытаюсь сделать то же самое с самой последней Spring-Boot, но обнаруживаю, что не могу Autowire ObjectMapper или MappingJackson2XmlHttpMessageConverter. Оба результата приводят к ошибкам «Отсутствие квалификационного компонента типа». – robross0606

+0

@ robross0606 Убедитесь, что у вас есть зависимости в pom.xml в вопросе. –

+0

Уже проверено, что. Я использую Gradle для управления зависимостями, но подтвердил, что у меня есть все те же зависимости, что указаны выше в вашем Maven POM. – robross0606