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
If you want to Gain In-depth Knowledge on Spring Boot, please go through this link Spring Boot Training
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 thisHttpHeaders 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.
Maven Project will be as follows-
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 SpringBootHelloWorldApplicatipackage 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