Giới thiệu

Trong Spring Boot, lớp điều khiển chịu trách nhiệm xử lý các yêu cầu API REST đến, chuẩn bị một mô hình và trả về chế độ xem sẽ được hiển thị dưới dạng phản hồi.

Các lớp bộ điều khiển trong Spring được chú thích bởi @Controller hoặc là @RestController chú thích. Các lớp bộ điều khiển đánh dấu này như một trình xử lý yêu cầu để cho phép Spring nhận ra nó như một dịch vụ RESTful trong thời gian chạy.

Trong hướng dẫn này, chúng tôi sẽ đề cập đến định nghĩa của @Controller@RestController chú thích, trường hợp sử dụng của chúng và sự khác biệt giữa hai chú thích.

Nếu bạn chưa quen với Spring Boot, bạn cũng có thể muốn xem hướng dẫn đầy đủ của chúng tôi về Cách tạo API REST Spring Boot.

Quy trình làm việc của Spring Boot REST API

Trước khi xác định hai chú thích, chúng ta sẽ nhanh chóng xem qua quy trình làm việc về cách Spring Boot xử lý các yêu cầu và quy trình REST API và trả về phản hồi:

Đầu tiên, yêu cầu được nhận bởi DispatcherServlet, chịu trách nhiệm xử lý bất kỳ yêu cầu URI nào đến và ánh xạ chúng tới các trình xử lý tương ứng của chúng dưới dạng phương thức bộ điều khiển. Sau khi phương thức controller đã được thực thi, tài nguyên sau đó được xử lý dưới dạng phản hồi có thể là JSON hoặc XML.

Trong sơ đồ trên, hai quy trình được gói gọn trong hình chữ nhật là các quy trình được thực hiện bởi một nhà phát triển. Phần còn lại được thực thi bởi các dịch vụ Spring đang chạy ở chế độ nền, bao gồm DispatcherServlet.

Các @Controller Chú thích

Các @Controller chú thích là một chuyên môn hóa của khuôn mẫu chung @Component chú thích, cho phép một lớp được công nhận là một thành phần do Spring quản lý.

Các @Controller chú thích mở rộng trường hợp sử dụng của @Component và đánh dấu lớp được chú thích là lớp nghiệp vụ hoặc lớp trình bày. Khi một yêu cầu được thực hiện, điều này sẽ thông báo cho DispatcherServlet để bao gồm lớp bộ điều khiển trong quá trình quét các phương thức được ánh xạ bởi @RequestMapping chú thích.

Bây giờ, chúng ta sẽ khai báo bộ điều khiển thực tế để xác định logic nghiệp vụ và xử lý tất cả các yêu cầu liên quan đến mô hình Tree.

Đầu tiên, đánh dấu lớp học bằng @Controller chú thích cùng với @RequestMapping và chỉ định đường dẫn đến /api/tree:

@Controller
@ResponseBody
@RequestMapping("/api/tree")
public class TreeController {

    @Autowired
    private TreeRepository repository;
 
    @GetMapping("/{id}")
    public Tree getTreeById(@PathVariable int id) {
        return repository.findById(id);
    }
  
    @GetMapping
    public Tree getTreeById(@RequestParam String name, 
                            @RequestParam int age) {
        return repository.findFirstByCommonNameIgnoreCaseAndAge(name, age);
    }
}

Các @Autowired chú thích được sử dụng để tự động đưa các phụ thuộc của kiểu được chỉ định vào bean hiện tại. Trong trường hợp này, TreeRepository bean được tiêm như một phụ thuộc của TreeController.

@GetMapping là một lối tắt cho @RequestMapping(method = RequestMethod.GET)và được sử dụng để ánh xạ HTTP GET yêu cầu đối với các phương thức bộ điều khiển được ánh xạ.

Chúng tôi đã áp dụng một @ResponseBody chú thích cho cấp độ lớp của bộ điều khiển này. Khi trình xử lý yêu cầu trả lại dữ liệu, chẳng hạn như return repository.findById()phản hồi sẽ được tuần tự hóa thành JSON trước khi được trả lại cho máy khách.

Ngoài ra, bạn có thể chú thích từng loại phản hồi với @ResponseBody chú thích thay thế:

 @GetMapping("/{id}")
    public @ResponseBody Tree getTreeById(@PathVariable int id) {
        return repository.findById(id);
    }

Nếu chúng tôi chạy ứng dụng này, giả sử chúng tôi đã có một Tree cá thể được lưu vào cơ sở dữ liệu, với ID là 1 và nhấn localhost:8080/1 endpoint, chúng tôi sẽ được chào đón với:

{"species":"Salix babylonica","commonName":"Weeping willow", "age":"150"}

Bởi vì @ResponseBody chú thích, các trường từ đối tượng đã tìm nạp được tuần tự hóa thành JSON và được trả lại cho ứng dụng khách đã yêu cầu nó.

Các @RestController Chú thích

Các @RestController chú thích trong Spring về cơ bản chỉ là sự kết hợp của @Controller@ResponseBody. Chú thích này đã được thêm vào trong Spring 4.0 để loại bỏ sự dư thừa của việc khai báo @ResponseBody chú thích trong bộ điều khiển của bạn.

Đó là một khai báo ít chú thích hơn! Nếu bạn cũng nhìn vào định nghĩa giao diện của hai chú thích để thấy sự khác biệt giữa hai chú thích:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
  //..
}

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
  //..
}

Các RestController được chú thích bởi @Controller@ResponseBody chú thích trực tiếp nó với @Component.

Nếu chúng tôi thay thế chú thích của bộ điều khiển của chúng tôi bằng @RestControllerchúng tôi sẽ không cần thay đổi miền và lớp bền vững vì chúng vẫn sẽ tương thích với chú thích này.

Sử dụng bộ điều khiển mẫu TreeController ở trên, hãy so sánh những thay đổi khi chúng tôi sử dụng chú thích này:

@RestController
@RequestMapping("/api/tree")
public class TreeController {

    @Autowired
    private TreeRepository repository;
 
    @GetMapping("/{id}")
    public Tree getTreeById(@PathVariable int id) {
        return repository.findById(id);
    }
  
    @GetMapping
    public Tree getTreeById(@RequestParam String name, 
                            @RequestParam int age) {
        return repository.findFirstByCommonNameIgnoreCaseAndAge(name, age);
    }
}

Bây giờ, tất cả các phương pháp đều có @ResponseBody chú thích được áp dụng cho chúng, như @RestControllernằm ở cấp độ lớp học.

Nếu chúng tôi chạy ứng dụng này, giả sử chúng tôi đã có Tree cá thể được lưu vào cơ sở dữ liệu, với ID là 1 và nhấn localhost:8080/1 endpoint, chúng tôi sẽ được chào đón với:

{"species":"Salix babylonica","commonName":"Weeping willow", "age":"150"}

Sự kết luận

Bản chất, @RestController mở rộng khả năng của cả hai @Controller@ResponseBody chú thích.

Khác với thực tế là @RestController tồn tại để cho phép bộ điều khiển Spring ngắn hơn một dòng, không có bất kỳ sự khác biệt lớn nào giữa hai chú thích.

Chức năng chính của cả hai chú thích là cho phép một lớp được công nhận là thành phần do Spring quản lý và cho phép xử lý các yêu cầu HTTP bằng REST API.