Spring Boot Tutorial- Return both JSON and XML Response using Spring ContentNegotiationManager | JavaInUse



Implement Content Negotiation using Spring Boot

In this post we implement a simple Spring Boot example to implement Content Negotiation for returning XML or JSON depending upon the URL suffixes.
Previously we had implemented Content Negotiation for Spring MVC using XML Configuration
Usual scenarios we specify if a method should return a response either as xml,json,html or some other type. But it may happen that we need the same method to return a response of different type depending on the incoming request.
For example we have a Server application which return the list of employees. We are having 2 UI applications using the same server method to get the list of employees. But one requires xml and the other json.
This is where content negotiation comes into picture. As name suggests it negotiates the response type based on the request. This content negotiation can be achieved in following ways-
  • Using Path Extension - In the request we specify the required response type using the extension like .json,.xml or .txt. This has the highest preference
  • Using url parameter - In the request we specify the required response type using the url parameter like format=xml or format=json. This has the second highest preference
  • Using Accept Headers - When making a request using HTTP we specify required response by setting the Accept header property. Its something like this
    HttpHeaders headers = new HttpHeaders();
    headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
    
In this example we will be looking at Content Negotiation using Path Extension and using url parameter.

Video

This tutorial is explained in the below Youtube Video.

Lets Begin-

Maven Project will be as follows-

Spring Boot Content Negotiation Setup

In the Maven we need the spring boot test dependency.Maven will be as follows-
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.javainuse</groupId>
	<artifactId>boot-contentnegotiationmanager</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>SpringBootHelloWorld</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.1.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>


</project>
Create the SpringBootHelloWorldApplication.java as below-
package com.javainuse;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringBootHelloWorldApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringBootHelloWorldApplication.class, args);
	}
}
Create the Employee model class as follows-
package com.javainuse.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Employee {
	private String empId;
	private String name;
	private String designation;
	private double salary;

	public Employee() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getDesignation() {
		return designation;
	}

	public void setDesignation(String designation) {
		this.designation = designation;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	public String getEmpId() {
		return empId;
	}

	public void setEmpId(String empId) {
		this.empId = empId;
	}

}
@RequestMapping maps /employee request to return an employee object. method. Define the produces to include both XML and JSON.
package com.javainuse.controllers;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.javainuse.model.Employee;

@RestController
public class TestController {

	@RequestMapping(value = "/employee", method = RequestMethod.GET,
			produces = { "application/json", "application/xml" })
	public Employee firstPage() {

		Employee emp = new Employee();
		emp.setName("emp1");
		emp.setDesignation("manager");
		emp.setEmpId("1");
		emp.setSalary(3000);

		return emp;
	}

}

Next we overwrite configureContentNegotiation method in our configuration class. We set the In defaultContentType(MediaType.APPLICATION_JSON). default content type is set. It means that if we don't pass path expression then Spring will generate JSON as response. The configuration will be as follows depending on the content negotiation type
  • Using Path Extension

    package com.javainuse.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.MediaType;
    import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    @Configuration
    @EnableWebMvc
    public class WebConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    
        //set path extension to true
        configurer.favorPathExtension(true).
        //set favor parameter to false
        favorParameter(false).
        //ignore the accept headers
        ignoreAcceptHeader(true).
        //dont use Java Activation Framework since we are manually specifying the mediatypes required below
        useJaf(false).
        defaultContentType(MediaType.APPLICATION_JSON).
        mediaType("xml", MediaType.APPLICATION_XML).
        mediaType("json", MediaType.APPLICATION_JSON);
      }
    }
    
    Compile and the run the SpringBootHelloWorldApplication.java as a Java application.
    Go to localhost:8080/employee.json
    Spring Boot Content Negotiation Tutorial

    Go to localhost:8080/employee.xml
    Spring Boot Content Negotiation Example
  • Using Path Parameters

    package com.javainuse.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.MediaType;
    import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
    import org.springframework.web.servlet.config.annotation.EnableWebMvc;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    @Configuration
    @EnableWebMvc
    public class WebConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    
    	//set path extension to false
    	configurer.favorPathExtension(false).
        //request parameter ("format" by default) should be used to determine the requested media type
        favorParameter(true).
        //the favour parameter is set to "mediaType" instead of default "format"
        parameterName("mediaType").
        //ignore the accept headers
        ignoreAcceptHeader(true).
        //dont use Java Activation Framework since we are manually specifying the mediatypes required below
        useJaf(false).
        defaultContentType(MediaType.APPLICATION_JSON).
        mediaType("xml", MediaType.APPLICATION_XML).
        mediaType("json", MediaType.APPLICATION_JSON);
      }
    }
    
    Compile and the run the SpringBootHelloWorldApplication.java as a Java application.
    Go to localhost:8080/employee?mediaType=json
    Spring Boot Content Negotiaition

    Go to localhost:8080/employee?mediaType=xml
    Spring Boot Content Negotiation Output
  • Download Source Code

    Download it -
    Spring Boot Content Negotiation Manager