简体   繁体   中英

What is the simplest way to configure a Spring Boot JMS app to use a JAXB marshalling as the default?

With a Spring Boot REST endpoint, it seems that if JAXB is available, simply passing the 'Accept' header of 'application/xml' is enough to receive the output from a very simple endpoint as XML as long as the @Xml... annotations are present on the entity.

@RequestMapping(value = "/thing/{id}")
ResponseEntity<Thing> getThing(
        @PathVariable(value = "id") String id) {
    Thing thing = thingService.get(id)

    return new ResponseEntity<Thing>(thing, HttpStatus.OK);
}

However, when calling jmsTemplate.convertAndSend(destination, thing) , I have to explicitly plug in a message converter to the JMS template that has the following code inside

        JAXBContext context = JAXBContext.newInstance(object.getClass());
        Marshaller marshaller = context.createMarshaller();
        StringWriter writer = new StringWriter();
        marshaller.marshal(object, writer);

        TextMessage textMessage = session.createTextMessage(writer.toString());

        return textMessage;

I'm using JavaConfig with annotations and these message dependencies currently:

compile("org.springframework:spring-jms")
compile('org.springframework.integration:spring-integration-jms')
compile("org.apache.activemq:activemq-broker")

Also include these from Spring Boot starter but not sure if they important here.

compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.boot:spring-boot-starter-data-jpa')
compile('org.springframework.boot:spring-boot-starter-hateoas')

I'm also using Groovy and Spock.

Seems like there is surely some way to have this marshalling done by default without code. Suggestions?

I ended up explicitly plugging in the Jaxb2Marshaller from the Spring OXM framework. I did it kinda clunky since I'm doing SpringBoot and annotation based configuration and the examples were all XML.

@Autowired
JmsTemplate jmsTemplate

...

@Bean
MessageConverter messageConverter() {
    MarshallingMessageConverter converter = new MarshallingMessageConverter()
    converter.marshaller = marshaller()
    converter.unmarshaller = marshaller()
    // set this converter on the implicit Spring JMS template
    jmsTemplate.messageConverter = converter
    converter
}

@Bean
Jaxb2Marshaller marshaller() {
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller()
    marshaller.classesToBeBound = [My.class, MyOther.class]
    marshaller
}

I'd love to make even simpler but I'm afraid this will have to do for now.

Actually, MessageConverter can be autowired (at least if you use JmsAutoConfiguration with Spring Boot 2 and Spring jms 5). Therefore, there is no need to set it manually, it is enough just to create bean:

@Bean
MessageConverter messageConverter(Jaxb2Marshaller marshaller) {
    MarshallingMessageConverter converter = new MarshallingMessageConverter();
    converter.setMarshaller(marshaller);
    converter.setUnmarshaller(marshaller);

    return converter;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM