Spring Boot REST – Handling XML Request and Response

Spring boot, by default, configures Jackson for parsing Java objects to JSON and converting JSON to Java objects as part of REST API request-response handling. To accept XML requests and send XML responses, there are two common approaches:

  • Using Jackson XML Module
  • Using JAXB Module

1. Setup

To demo the configuration changes, we will use the following REST APIs. We are keeping the APIs simple to focus on the topic.

@RestController
@RequestMapping("/items")
public class ItemController {

  @GetMapping("/{id}")
  public Item getItemById(@PathVariable("id") Long id){
    return new Item(id, "temp-item");
  }

  @PostMapping
  public Item createItem(@RequestBody Item item){
    return item;
  }
}

The Item class is a standard POJO with two fields.

public class Item {

  private Long id;
  private String name;

  //Setters, Getters, Constructor
}

2. Jackson XML Module

2.1. Quick Start

Start with adding Jackson’s XML module by including the jackson-dataformat-xml dependency. Spring boot manages the library versions, so the following declaration is enough.

<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

Now we can access an API with the request header “Accept: application/xml” and the API will respond with XML response.

HTTP GET /items/1 
HTTP Header "Accept: application/xml"

<Item>
    <id>1</id>
    <name>temp-item</name>
</Item>

Similarly, we can send a POST request with an XML request body as follows, and API will return the XML response also.

Note that if we do not send the Accept header then API will respond with JSON response because default mediatype is always JSON.

HTTP POST /items/1 
HTTP Header "Content-type: application/xml"
HTTP Header "Accept: application/xml"

<Item>
    <id>1</id>
    <name>temp-item</name>
</Item>

2.2. Configure Default Content Negotiation

After adding the XML module, the default mediatype still remains JSON for all requests and responses. Though, APIs will support both media types.

To change the default mediatype to APPLICATION_XML, we can override the configureContentNegotiation() method from WebMvcConfigurer interface.

@SpringBootApplication
public class App implements WebMvcConfigurer {

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

  @Override
  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

    configurer.defaultContentType(MediaType.APPLICATION_XML);
  }
}

2.3. Custom Node Names in XML Response

By default, Jackson will produce the root element of the response as the name of the model class as seen in the previous section. We can give another name to XML nodes using the Jackson annotations such as:

  • @JacksonXmlRootElement
  • @JacksonXmlProperty
@JacksonXmlRootElement(localName = "item")
public class Item {

  private Long id;
  private String name;
}

The /items/1 API will return the XML response as follows. Notice the root node changed from “Item” to “item”.

HTTP GET /items/1 

<item>
    <id>1</id>
    <name>temp-item</name>
</item>

3. JAXB Module

JAXB provides excellent support for customizing the marshalling and unmarshalling of XML documents to/from Java objects. It also provides a rich set of annotations to customize the generated XML responses.

3.1. Quick Start

Like the Jackson XML module, enabling JAXB support is mostly about adding the jaxb-runtime dependency in the project and Spring boot will auto-detect and configure it in the startup.

<dependency>
  <groupId>org.glassfish.jaxb</groupId>
  <artifactId>jaxb-runtime</artifactId>
</dependency>

Note that JAXB requires the mandatory @XmlRootElement annotation for marshalling and unmarshalling. It was optional in the case of Jackson XML module.

@XmlRootElement(name = "item")
@XmlAccessorType(XmlAccessType.FIELD)
public class Item {

  private Long id;
  private String name;
}

Now we can access the API with the header “Accept: application/xml” and API will send the XML response.

HTTP GET /items/1 
HTTP Header "Accept: application/xml"

<item>
    <id>1</id>
    <name>temp-item</name>
</item>

3.2. Default Content Negotiation

Like Jackson module, the default content negotiation is set using the WebMvcConfigurer‘s configureContentNegotiation() method. No changes in this.

@SpringBootApplication
public class App implements WebMvcConfigurer {

  //...

  @Override
  public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {

    configurer.defaultContentType(MediaType.APPLICATION_XML);
  }
}

3.3. Customize the Response Body

We can use the JAXB annotations to customize the API response as per the requirements.

4. Conclusion

In this quick tutorial, we learned to add the support of XML requests and responses in a Spring boot application. Note that when we add the XML support, APIs support JSON mediatype also.

The default mediatype is always JSON, which can be changed by configuring the desired content negotiation strategy.

Happy Learning !!

Sourcecode on Github

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.