In this quick article, we’ll discuss the difference between @Controller and @RestController annotations in Spring MVC.
The first annotation is used for traditional Spring controllers and has been part of the framework for a very long time. The @RestController annotation was introduced in Spring 4.0 to simplify the creation of RESTful web services. It’s a convenience annotation that combines @Controller and @ResponseBody – which eliminates the need to annotate every request handling method of the controller class with the @ResponseBody annotation.
The key difference between a traditional Spring MVC controller and the RESTful web service controller is the way the HTTP response body is created. While the traditional MVC controller relies on the View technology, the RESTful web service controller simply returns the object, and the object data is written directly to the HTTP response as JSON/XML.
The first annotation is used for traditional Spring controllers and has been part of the framework for a very long time. The @RestController annotation was introduced in Spring 4.0 to simplify the creation of RESTful web services. It’s a convenience annotation that combines @Controller and @ResponseBody – which eliminates the need to annotate every request handling method of the controller class with the @ResponseBody annotation.
The key difference between a traditional Spring MVC controller and the RESTful web service controller is the way the HTTP response body is created. While the traditional MVC controller relies on the View technology, the RESTful web service controller simply returns the object, and the object data is written directly to the HTTP response as JSON/XML.
YouTube Video - @Controller Annotation
@Controller Annotation
Classic controllers can be annotated with the @Controller annotation. This is simply a specialization of the @Component class and allows implementation classes to be autodetected through classpath scanning.
In order to develop REST web services using Spring MVC @Controller, we need to add a @ResponseBody annotation to each of the @RequestMapping methods in the return value as shown in the below diagram.
In order to develop REST web services using Spring MVC @Controller, we need to add a @ResponseBody annotation to each of the @RequestMapping methods in the return value as shown in the below diagram.
@Controller Annotation Example
@Controller is typically used in combination with a @RequestMapping annotation used on request handling methods.
Notice that in the below example, we added @ResponseBody annotation to each of the @RequestMapping methods in the return value.
@Controller @RequestMapping("/api/v1") public class EmployeeController { @Autowired private EmployeeRepository employeeRepository; @GetMapping("/employees") public @ResponseBody List<Employee> getAllEmployees() { return employeeRepository.findAll(); } @GetMapping("/employees/{id}") public @ResponseBody ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); return ResponseEntity.ok().body(employee); } @PostMapping("/employees") public @ResponseBody Employee createEmployee(@Valid @RequestBody Employee employee) { return employeeRepository.save(employee); } @PutMapping("/employees/{id}") public @ResponseBody ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId, @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); employee.setEmailId(employeeDetails.getEmailId()); employee.setLastName(employeeDetails.getLastName()); employee.setFirstName(employeeDetails.getFirstName()); final Employee updatedEmployee = employeeRepository.save(employee); return ResponseEntity.ok(updatedEmployee); } @DeleteMapping("/employees/{id}") public @ResponseBody Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); employeeRepository.delete(employee); Map<String, Boolean> response = new HashMap<>(); response.put("deleted", Boolean.TRUE); return response; } }
YouTube Video - @RestController Annotation
@RestController Annotation
Spring 4.0 introduced @RestController, a specialized version of the controller which is a convenience annotation that does nothing more than add the @Controller and @ResponseBody annotations.
By annotating the controller class with @RestController annotation, you no longer need to add @ResponseBody to all the request mapping methods. The @ResponseBody annotation is active by default.
@RestController Annotation Example
To use @RestController in our example, all we need to do is modify the @Controller to @RestController and remove the @ResponseBody from each method. The resultant class should look like the following:
@RestController @RequestMapping("/api/v1") public class EmployeeController { @Autowired private EmployeeRepository employeeRepository; @GetMapping("/employees") public List<Employee> getAllEmployees() { return employeeRepository.findAll(); } @GetMapping("/employees/{id}") public ResponseEntity<Employee> getEmployeeById(@PathVariable(value = "id") Long employeeId) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); return ResponseEntity.ok().body(employee); } @PostMapping("/employees") public Employee createEmployee(@Valid @RequestBody Employee employee) { return employeeRepository.save(employee); } @PutMapping("/employees/{id}") public ResponseEntity<Employee> updateEmployee(@PathVariable(value = "id") Long employeeId, @Valid @RequestBody Employee employeeDetails) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); employee.setEmailId(employeeDetails.getEmailId()); employee.setLastName(employeeDetails.getLastName()); employee.setFirstName(employeeDetails.getFirstName()); final Employee updatedEmployee = employeeRepository.save(employee); return ResponseEntity.ok(updatedEmployee); } @DeleteMapping("/employees/{id}") public Map<String, Boolean> deleteEmployee(@PathVariable(value = "id") Long employeeId) throws ResourceNotFoundException { Employee employee = employeeRepository.findById(employeeId) .orElseThrow(() -> new ResourceNotFoundException("Employee not found for this id :: " + employeeId)); employeeRepository.delete(employee); Map<String, Boolean> response = new HashMap<>(); response.put("deleted", Boolean.TRUE); return response; } }
You can find a complete example using Spring MVC @RestController annotation at Spring Boot 2 JPA MySQL CRUD Example
The controller is annotated with the @RestController annotation, therefore the @ResponseBody isn’t required.
Every request handling method of the controller class automatically serializes return objects into HttpResponse.
Related Spring and Spring Boot Annotations
- Spring Boot @Bean Annotation Example
- Spring @Qualifier Annotation Example
- Spring @Autowired Annotation with Example
- Spring @Bean Annotation with Example
- Spring @Configuration Annotation with Example
- Spring @PropertySource Annotation with Example
- Spring @Import Annotation with Example
- Spring @ImportResource Annotation Example
- Spring - @Lazy Annotation Example
- Spring - @Primary Annotation Example
- Spring @PostConstruct and @PreDestroy Example
- Spring @Repository Annotation
- Spring @Service Annotation
- The Spring @Controller and @RestController Annotations
- Spring Boot @Component, @Controller, @Repository and @Service
- Spring @Scope annotation with Prototype Scope Example
- Spring @Scope annotation with Singleton Scope Example
- Spring Boot @PathVariable
- Spring Boot @ResponseBody
- Spring @RequestBody - Binding Method Parameters to Request Body
- Spring Boot @ResponseStatus Annotation
- Spring Boot - Creating Asynchronous Methods using @Async Annotation
- @SpringBootTest Spring Boot Example
- @SpringBootTest vs @WebMvcTest
- @DataJpaTest Spring Boot Example
- Spring @PostConstruct and @PreDestroy Example
- Spring @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping
- Spring Boot @EnableAutoConfiguration Annotation with Example
- Spring Boot @SpringBootApplication Annotation with Example
Comments
Post a Comment
Leave Comment