A key difference between a traditional web application (monolithic) and the RESTful web service is the way that the HTTP response body is created.
Instead of using a view technology (JSP / Thymeleaf) to perform server-side rendering of the data to HTML, typically a RESTful web service controller simply populates and returns a Java object (data). The object data will be written directly to the HTTP response as JSON/XML/Text.
To do this, the @ResponseBody
annotation on the return type of the request handling method tells Spring MVC that it does not need to render the Java object through a server-side view layer.
Instead, it tells that the Java object returned is the response body, and should be written out directly.
The Java object must be converted to JSON. Thanks to Spring’s HTTP message converter support, you don’t need to do this conversion manually. Because the Jackson Jar is on the classpath, Spring can automatically convert the Java object to JSON & vice versa (using 2 annotations @ResponseBody
& @RequestBody
).
o.s.http.converter.HttpMessageConverter<T>
T
: Type of request/response body.o.s.http.converter.xml.Jaxb2RootElementHttpMessageConverter
HttpMessageConverter
that can read and write XML using JAXB2 (Java Architecture for XML Binding).o.s.http.converter.json.MappingJackson2HttpMessageConverter
HttpMessageConverter
that can read and write JSON using Jackson 2.x’s ObjectMapper class API.@ResponseBody
@RequestMapping
or @GetMapping
/ @PostMapping
/ @PutMapping
/ @DeleteMapping
, etc.Example:
@Controller
@RequestMapping("/employees")
public class EmpController {
@GetMapping(...)
public @ResponseBody Emp fetchEmpDetails(int empId) {
// get emp details from DB through layers
return e;
}
}
@RestController
@RestController
= @Controller
(at the class level) + @ResponseBody
implicitly added on return types of ALL request handling methods (annotated with @RequestMapping
| @GetMapping
| @PostMapping
| @PutMapping
, etc.).Example:
@RestController
@RequestMapping("/employees")
public class EmpController {
@GetMapping(...)
public Emp fetchEmpDetails(int empId) {
// get emp details from DB through layers
return e;
}
}
@PathVariable
Example:
URL: http://host:port/products/1234
, method=GET
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{pid}")
public Product getDetails(@PathVariable Long pid) {
// fetch product details by its id
}
}
OR for sub-resources:
URL: http://host:port/products/categories/cat_id/10/product_id/1234
, method=GET
@RestController
@RequestMapping("/products/categories/cat_id/{catId}")
public class ProductController {
@GetMapping("/productId/{pid}")
public Product getDetails(@PathVariable int catId, @PathVariable(name="pid") int pid1234) {
// ...
}
}
In the above URL, the path variable {pid}
is mapped to an int
. Therefore, all URIs such as /products/1
or /products/10
will map to the same method in the controller.