SpringBoot 開發實踐(4):使用 @Controller 實現 RESTful Web 接口

前言

在之前的章節,我們已經用到了 Controller 的部分功能——外界通過 HTTP 請求,訪問 SpringBoot 中的方法。這就是我們熟知的 Web 接口,是客戶端與後端應用交互的重要方式之一。

那麼在本章,我們就來整理下如何使用 @Controller 實現 RESTful Web 接口。

@Controller 的使用

基本介紹

@Controller 註解用於標識一個類,被標識的類就是個 SpringMVC Controller 對象,即一個控制器。SpringBoot 在啓動時,會自動掃描被 @Controller 標記的類,並掃描該類中的方法。使用 @RequestMapping 標記的方法即爲一個處理器,不同的請求會由分發器分發到對應的方法上。

創建 Controller 類

新建一個 controller 包,在包內創建一個 MyController1.java

@Controller
public class MyController1 {
    @ResponseBody
    @RequestMapping(value = "/test")
    private String test() {
        return "Hello world!";
    }
}
  • @Controller: 標記爲一個控制器類。
  • @ResponseBody: 標誌返回值是實體內容,而不是返回一個界面。因爲我們要做的是 RESTful 接口,所以這裏需要的是直接返回參數內容。如果不標記 @ResponseBody 的話,將返回名爲"Hello world!"的界面文件。
  • @RequestMapping: 標記方法爲控制器。後面會詳細介紹該註解的用法。

啓動項目,在瀏覽器中或 Web 調試工具(例如 PostMan)訪問 http://127.0.0.1:8080/test,將得到"Hello world!"字符串。

在這裏插入圖片描述

用 @RestController 代替 @Controller 與 @ResponseBody

@RestController 的功能 = @Controller + @ResponseBody
在類上標註 @RestController,就不需要在該類的每個方法上標註 @ResponseBody 了。

@RequestMapping 的使用

基本介紹

@RequestMapping 可以標識在類或者方法上,用於指明 Spring 用哪個類或者哪個方法來處理對應的請求。

@RequestMapping 標記在類上時,表示該類下的所有方法都被映射到其 value 屬性所指示的路徑下。

創建 MyController2.java

@RestController
@RequestMapping(value = "/controller2")
public class MyController2 {
    @RequestMapping(value = "/test1")
    private String test1() {
        return "This is test1.";
    }

    @RequestMapping(value = "/test2")
    private String test2() {
        return "This is test2.";
    }
}

這上面這兩個方法的 URL 分別爲:

@RequestMapping 相關屬性

@RequestMapping 中,可以配置如下的屬性:

  • value: 用於將請求映射到指定的方法上。
  • method: 規定請求的類型。支持的請求類型包括:GETPOSTPUTDELETEOPTIONSPATCHHEADTRACE。如果不填,則默認支持所有請求類型。
  • consumes: 規定請求的入參類型,即 Content-Type。例如:text/xmlapplication/jsonmultipart/form-data 等。
  • produces: 規定請求的出參類型,如果請求的 header 中設置了 Accept 類型,則需要在 produces 中配置同樣的類型才能返回出參。
  • params: 規定請求中必須包含指定參數值時,方法纔會處理該請求。
  • headers: 規定請求頭必須包含指定 header 值時,方法纔會處理該請求。
  • names: 給映射地址起個別名。

例如:

@RestController
@RequestMapping(value = "/controller3")
public class MyController3 {
    @RequestMapping(value = "/test1", method = {RequestMethod.POST})
    private String test1() {
        return "This is test1.";
    }

    @RequestMapping(value = "/test2", consumes = "application/json")
    private String test2() {
        return "This is test2.";
    }

    @RequestMapping(value = "/test3", params = "id=1")
    private String test3() {
        return "This is test3.";
    }
}

如何獲取入參

通常,我們需要在訪問接口的同時向後臺傳入數據。關於入參的獲取,有以下四種常見方式。

通過 HttpServletRequest 獲取參數

HttpServletRequest 對象,包含了客戶端一次 HTTP 請求中的請求消息頭、請求消息體和請求消息行的所有內容。通過 API 可以獲取請求中的信息。對於入參,我們可以使用 getParameter(String key) 方法獲得參數值。

MyController4.java 中添加如下方法:

@RequestMapping(value = "/test1")
private String test1(HttpServletRequest httpServletRequest) {
    int id = Integer.parseInt(httpServletRequest.getParameter("id"));
    String name = httpServletRequest.getParameter("name");
    return String.format("id:%d, name:%s", id, name);
}

訪問 http://127.0.0.1:8080/controller4/test1?id=1&name=InterHorse,返回“id:1, name:InterHorse”。

通過 @RequestParam 獲取參數

@RequestMapping(value = "/test2")
private String test2(@RequestParam("id") int id,
                     @RequestParam("name") String name) {
    return String.format("id:%d, name:%s", id, name);
}

訪問 http://127.0.0.1:8080/controller4/test2?id=1&name=InterHorse,返回“id:1, name:InterHorse”。

其中,@RequestParam 也有屬性可以進行配置:

  • name: 指定屬性綁定的名稱。
  • value: name 的別名。所以 name 和 value 是等價的。
  • required: 參數是否必須傳。默認爲 true。
  • defaultValue: 如果某個屬性的 required 設置爲 false,則可以通過該屬性配置某個參數的默認值。

例如

@RequestMapping(value = "/test5")
private String test5(@RequestParam(value = "id", required = false, defaultValue = "10") int id,
                     @RequestParam(value = "name", required = false, defaultValue = "Bill") String name) {
    return String.format("id:%d, name:%s", id, name);
}

如果入參爲空,則默認返回“id:10, name:Bill”。

通過 @PathVariable 獲得入參

使用 @PathVariable ,可以直接將 URL 中的參數動態綁定到入參中。

@RequestMapping(value = "/test3/{id}/{name}")
private String test3(@PathVariable("id") int id,
                     @PathVariable("name") String name) {
    return String.format("id:%d, name:%s", id, name);
}

請求 http://127.0.0.1:8080/controller4/test3/1/InterHorse,返回值爲“id:1, name:InterHorse”。

通過實體獲得入參

創建一個實體 InputAO.java,包含 id 和 name 兩個屬性。SpringBoot 會自動根據入參的屬性名稱與實體中同名屬性進行映射,將參數 set 到實體中。

public class InputAO {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
@RequestMapping(value = "/test4")
private String test4(InputAO inputAO) {
    int id = inputAO.getId();
    String name = inputAO.getName();
    return String.format("id:%d, name:%s", id, name);
}

請求 http://127.0.0.1:8080/controller4/test4?id=1&name=InterHorse,返回值爲“id:1, name:InterHorse”。

如何返回參數

返回一個對象

在之前所有的演示中,我們已經在返回 String 類型的數據了,其他幾種基本類型例如 intlongboolean 也是一樣,只需要修改方法的返回類型就可以返回不同類型的數據了。那麼如何返回對象類型呢?非常簡單,只需要將返回類型修改爲需要返回的對象類型,那麼 SpringBoot 就自動將實體序列化成 JSON 格式進行返回了。

創建實體 ResponseBO.java

public class ResponseBO {
    private String code;
    private String message;
    private Object data;

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

MyController5.java 中添加如下方法

@RequestMapping(value = "/test1")
private ResponseBO test1(@RequestParam("id") int id,
                         @RequestParam("name") String name) {
    ResponseBO res = new ResponseBO();
    res.setCode("200");
    res.setMessage("調用成功");
    Map<String, Object> map = new HashMap<>(2);
    map.put("id", id);
    map.put("name", name);
    res.setData(map);
    return res;
}

訪問 http://127.0.0.1:8080/controller5/test1?id=1&name=InterHorse ,返回

{
    "code": "200",
    "message": "調用成功",
    "data": {
        "name": "InterHorse",
        "id": 1
    }
}

設置 HTTP 參數

有時候,我們除了要返回數據內容之外,可能還要根據需要,設置 HTTP 的相關屬性。例如,默認的 HTTP code 爲 200,如果想修改成別的數值,需要怎麼做呢?同樣也非常簡單。與 HttpServletRequest 類似,HttpServletResponse 對象爲一次請求的響應對象,在方法的入參中添加 HttpServletResponse httpServletResponse,通過其 API 即可對響應內容進行設置。

@RequestMapping(value = "/test2")
private ResponseBO test2(@RequestParam("id") int id,
                         @RequestParam("name") String name,
                         HttpServletResponse httpServletResponse) {
    ResponseBO res = new ResponseBO();
    res.setCode("200");
    res.setMessage("調用成功");
    Map<String, Object> map = new HashMap<>(2);
    map.put("id", id);
    map.put("name", name);
    res.setData(map);
    // 設置 HTTP code
    httpServletResponse.setStatus(600);
    return res;
}

訪問 http://127.0.0.1:8080/controller5/test2?id=1&name=InterHorse,請求的 HTTP code 已設置爲 600。
在這裏插入圖片描述

以上就是有關 SpringBoot 中 RESTful Web API 的常用實現方法。方法之多,適用爲重。要根據實際的生產需要,選擇適合自己的方法。

本章代碼地址:GitHub


我是因特馬,一個愛分享的斜槓程序員~

歡迎關注我的公衆號:一隻因特馬

原文作者: 一隻因特馬
原文鏈接: https://www.matalking.com/a/463891276/
版權聲明: 本博客所有文章除特別聲明外,均採用 BY-NC-ND 許可協議。轉載請註明出處!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章