RestController和Controller的區別和異同

WhoKnows1發表於2024-08-12

參考文章

【SpringBoot】帶你一文徹底搞懂RestController和Controller的關係與區別-CSDN部落格
https://blog.csdn.net/miles067/article/details/132567377

----------------------------------------------------------------------------------------------------------------------------------------------------

要點提取:@RestController 是一個組合註解,它結合了 @Controller@ResponseBody 註解的功能(就相當於把兩個註解組合在一起)。在使用 @RestController 註解標記的類中,每個方法的返回值都會以 JSON 或 XML 的形式直接寫入 HTTP 響應體中,相當於在每個方法上都新增了 @ResponseBody 註解。

----------------------------------------------------------------------------------------------------------------------------------------------------

什麼是@RestController,什麼是@Controller

@RestController@Controller 是 Spring Framework 中用於定義控制器的註解。

@RestController 是一個組合註解,它結合了 @Controller@ResponseBody 註解的功能(就相當於把兩個註解組合在一起)。在使用 @RestController 註解標記的類中,每個方法的返回值都會以 JSON 或 XML 的形式直接寫入 HTTP 響應體中,相當於在每個方法上都新增了 @ResponseBody 註解。

@Controller 註解標記的類則是傳統的控制器類。它用於處理客戶端發起的請求,並負責返回適當的檢視(View)作為響應。在使用 @Controller 註解的類中,通常需要在方法上使用 @ResponseBody 註解來指示該方法的返回值要作為響應的主體內容,而不是解析為檢視。

簡而言之,@RestController 適用於構建 RESTful 風格的 API,其中每個方法的返回值會直接序列化為 JSON 或 XML 資料併傳送給客戶端。而 @Controller 適用於傳統的 MVC 架構,它負責處理請求並返回相應的檢視。(@RestController下的方法預設返回的是資料格式,@Controller註解標註的類下面的方法預設返回的就是以檢視為格式)

使用@ResponseBody註解讓方法返回值作為響應內容是什麼意思

在使用 @Controller 註解標記的類中,預設情況下,方法的返回值會被解析為一個檢視名稱,並尋找與該名稱匹配的檢視進行渲染。這意味著返回的結果會被解析為一個 HTML 頁面或者模板引擎所需的資料。

但是有時候需要將方法的返回值直接作為響應的主體內容,而不是解析為檢視。為了實現這個目的,我們可以在方法上使用 @ResponseBody 註解。

@ResponseBody 註解表示方法的返回值應該直接寫入 HTTP 響應體中,而不是被解析為檢視。它告訴 Spring MVC 框架將方法的返回值序列化為特定格式(如 JSON、XML 等)並作為響應的主體內容返回給客戶端。

下面是一個使用 @Controller@ResponseBody 的示例:

@Controller
@RequestMapping("/hello")
public class HelloController {
    @GetMapping
    @ResponseBody
    public String sayHello() {
        return "Hello, World!";
    }
}

當客戶端發起 /hello 的 GET 請求時,sayHello() 方法會返回一個字串 "Hello, World!"。因為在方法上使用了 @ResponseBody 註解,返回值不會被解析為檢視,而是直接作為響應的主體內容返回給客戶端。

舉例說明

現在假設有一個簡單的訂單系統,其中有一個功能是獲取訂單資訊。我們來看如何使用 @RestController@Controller 分別實現同一個功能:

@RestController

@RestController
@RequestMapping("/orders")
public class OrderController {
    @GetMapping("/{id}")
    public Order getOrderById(@PathVariable int id) {
        // 從資料庫中獲取訂單資訊
        Order order = orderService.getOrderById(id);
        return order;
    }
}

使用 @RestController 註解標記類,並在方法上使用 @GetMapping 註解定義了一個 GET 請求的處理方法。方法的返回值是 Order 型別的物件,它將會直接序列化為 JSON 格式的資料,並作為 HTTP 響應的主體內容返回給客戶端。

@Controller

 

@Controller
@RequestMapping("/orders")
public class OrderController {
    @GetMapping("/{id}")
    @ResponseBody
    public ModelAndView getOrderById(@PathVariable int id) {
        // 從資料庫中獲取訂單資訊
        Order order = orderService.getOrderById(id);
        ModelAndView modelAndView = new ModelAndView("order-details");
        modelAndView.addObject("order", order);
        return modelAndView;
    }
}

使用 @Controller 註解標記類,並在方法上使用 @GetMapping 註解定義了一個 GET 請求的處理方法。方法的返回值是 ModelAndView 型別的物件,它將包含要渲染的檢視名稱和需要傳遞給檢視的資料。在方法上使用 @ResponseBody 註解,表示方法的返回值應該作為響應的主體內容,而不是解析為檢視。

通俗一點說就是——有時候並不需要返回檢視,只需要一組資料,這樣在方法加上一個@ResponseBody,就可以讓返回的格式轉換為資料格式

什麼時候需要返回的是檢視,什麼時候需要返回資料?

當設計 RESTful API 時,一般的原則是:

  • 如果客戶端希望獲取資料(例如 JSON、XML),則返回資料。
  • 如果客戶端希望展示資料(例如 HTML 頁面),則返回檢視。

下面是一些示例情況:

  • 當你在開發一個單頁應用的後端介面時,前端通常會透過 Ajax 請求獲取資料(例如 JSON),然後使用 JavaScript 動態更新頁面。在這種情況下,你應該返回資料(例如使用 @ResponseBody 註解)。
  • 當你需要為前端渲染 HTML 頁面時,需要返回檢視。檢視可以包含動態生成的資料,但最終會經過伺服器端模板引擎的處理,形成最終的 HTML 頁面。

再以例項說明,更通俗易懂的理解:

  1. 需要返回檢視的例項: 假設你正在開發一個部落格應用的後端介面。有一個頁面需要顯示所有文章的列表,並且希望以 HTML 形式展示。在這種情況下,你可以設計一個 GET 請求的介面 /api/articles,返回一個包含所有文章資料的檢視,讓前端直接展示這個頁面。這裡需要返回檢視而不是僅返回資料,因為需要服務端渲染整個 HTML 頁面。

  2. 只需要返回資料的例項: 假設正在開發一個電子商務網站,前端使用 React 或 Vue.js 等框架構建。在購物車頁面上,需要獲取當前使用者的購物車資料以便展示。在這種情況下,你可以設計一個 GET 請求的介面 /api/cart,返回一個 JSON 物件,包含當前使用者的購物車資料。這裡只需要返回資料而不是整個 HTML 頁面,因為前端透過 JavaScript 來處理和展示資料。

總結

  • @RestController@Controller@ResponseBody 的組合註解,用於建立 RESTful 風格的 API。
  • @RestController 返回的資料會直接作為響應的主體內容(JSON 或 XML),不進行頁面跳轉或檢視解析。
  • @Controller 用於傳統的 MVC 架構,負責處理請求並返回檢視作為響應。
  • @Controller 方法通常需要配合 @ResponseBody 註解,才能將返回值作為響應的主體內容。
  • 傳統的springMVC一般就需要直接返回檢視,而現在新興的前端技術vue在專案中為前後端分離的架構,前端框架負責處理資料和渲染頁面,而後端 API 則負責提供資料即可,所以對返回檢視的要求也就比較少了

相關文章