3

I wrote a spring boot application to accept a Http get Request and send a XML response as the output.I need to get following XML as output over HTTP

<response xmlns="">
    <userId>235</userId>
    <amount>345.0</amount>
</response>

And my DTO class is follows,

@XmlRootElement(name = "response")
public class CgPayment {
    @XmlElement
    private String userId;
    @XmlElement
    private double amount;

    @XmlElement
    public String getUserId() {
        return userId;
    }

    @XmlElement
    public void setUserId(String userId) {
        this.userId = userId;
    }

    @XmlElement
    public void setAmount(double amount) {
        this.amount = amount;
    }

    @XmlElement
    public double getAmount() {

        return amount;
    }
}

But i'm getting following response as the Output.

<CgPayment xmlns="">
    <userId>235</userId>
    <amount>345.0</amount>
</CgPayment>

How can I change the root element.The response type is APPLICATION_XML_VALUE

Lakmal Vithanage
  • 2,767
  • 7
  • 42
  • 58
  • 1
    Try `@JacksonXmlRootElement` [see this](https://stackoverflow.com/questions/23632419/how-to-deserialize-xml-with-annotations-using-fasterxml?rq=1). Or `XmlElement` annotation with the `name` attribute set to `Response` could do the trick. See this : http://www.duanqu.tech/questions/359704/jackson-annotation-how-to-rename-element-names – Thoomas Jul 21 '17 at 06:54

3 Answers3

11

You are using JAXB specific annotations, but Jackson to marshall your response. To make JAXB annotations work with Jackson, you have to include the jackson-module-jaxb-annotations inside your pom.xml

<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-jaxb-annotations</artifactId>
</dependency>

Additionally, you have to register the JaxbAnnotationModule for your configuration. I think the easiest way to achieve that with Spring Boot is to register a Bean of type org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer like this:

@Component
public class JacksonCustomizer implements Jackson2ObjectMapperBuilderCustomizer {
    @Override
    public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
        jacksonObjectMapperBuilder.modulesToInstall(new JaxbAnnotationModule());
}

or

@Bean
Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {
    return (mapperBuilder) -> mapperBuilder.modulesToInstall(new JaxbAnnotationModule());
}
Patrick
  • 915
  • 1
  • 8
  • 17
  • 3
    This should be the accepted answer. spring uses jackson by default, so installing the `JaxbAnnotationModule` to use JAXB annotations is required. As of `2.9.0` the extra dependency is also no longer necessary. – membersound Sep 15 '17 at 08:51
  • This works for me, I have added Bean dependency in the SpringBootApplication – Mayur Nov 08 '20 at 09:03
5

You can use @JacksonXmlRootElement(localName = "response") at the level of the class.

Javadoc : http://static.javadoc.io/com.fasterxml.jackson.dataformat/jackson-dataformat-xml/2.2.0/com/fasterxml/jackson/dataformat/xml/annotation/JacksonXmlRootElement.html

Thoomas
  • 2,150
  • 2
  • 19
  • 33
0

Have you tried to change class name to Response ?? I think that your marshaller is getting name from name of class.

i found this (maybe it will be helpful)

If type() is JAXBElement.class , then namespace() and name() point to a factory method with XmlElementDecl. The XML element name is the element name from the factory method's XmlElementDecl annotation or if an element from its substitution group (of which it is a head element) has been substituted in the XML document, then the element name is from the XmlElementDecl on the substituted element.If type() is not JAXBElement.class, then the XML element name is the XML element name statically associated with the type using the annotation XmlRootElement on the type. If the type is not annotated with an XmlElementDecl, then it is an error. If type() is not JAXBElement.class, then this value must be "".

rbednarska
  • 129
  • 1
  • 2
  • 13