1. 程式人生 > >Restful Api寫法心得之二《引數接收篇》

Restful Api寫法心得之二《引數接收篇》

前言
溫馨提示:可以訂閱我的微信公眾號,在手機裡看技術文件也很不錯哦o( ̄︶ ̄)o

本篇文章主要說下介面的資料引數到底該如何接收,我們知道一個http請求最重要的意義就是將資料在伺服器上進行傳入與傳出,本章主要講的也就是傳入。一次請求傳遞引數的方式主要有 URL路徑中、請求頭中、請求體中還有通過cookie等,下面我們分別對幾種方式進行講解。

MediaType的選擇

MediaType即是Internet Media Type,網際網路媒體型別;也叫做MIME型別,在Http協議訊息頭中,使用Content-Type來表示具體請求中的媒體型別資訊。

  • 對於POST、PUT、PATCH這種HTTP方法,統一使用 application/json,將引數放在請求體中以JSON格式傳遞至伺服器
  • 對於GET、DELETE的HTTP方法,使用預設型別(application/x-www-form-urlencoded)

備註
特殊情況特殊考慮,例如進行檔案上傳時,使用 multipart/form-data型別等

路徑引數

對應spring mvc框架中@PathVariable註解

備註
這裡有個注意的點,當路徑引數值中有帶點”.”的情況時,spring mvc框架中有對點做特殊處理,這導致在程式中只能接收到點之前的內容,例如你的請求是:GET https://api.zhuma.com/users/hehe.haha,後端在接收userId=’hehe.haha’時,只會接收到hehe字串,後面的部分(.haha)被捨棄掉了。

解決方式是:

package com.zhuma.demo.analyst.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.PathMatchConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class
MvcConfig extends WebMvcConfigurerAdapter {
@Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setUseSuffixPatternMatch(false);//可以讓URL路徑中帶小數點 '.' 後面的值不被忽略 } }

請求頭引數

對應spring mvc框架中@RequestHeader註解

對於提供給APP(android、ios、pc) 的介面我們可能需要關注一些呼叫資訊,例如 使用者登入資訊、呼叫來源、app版本號、api的版本號、安全驗證資訊 等等,我們將這些資訊放入頭資訊(HTTP HEAD中),下面給出在引數命名的例子:

  • X-Token 使用者的登入token(用於兌換使用者登入資訊)
  • Api-Version api的版本號
  • App-Version app版本號
  • Call-Source 呼叫來源(IOS、ANDROID、PC、WECHAT、WEB)
  • Authorization 安全校驗引數(後面會有文章詳細介紹該如何做安全校驗)

這時你可能會思考一下幾個問題:

  1. 為什麼需要收集 api版本號、app版本號、呼叫來源這些資訊呢?
    這裡解釋下,主要有幾個原因:
    • ①. 方便線上環境定位問題,這也是一個重要的原因(我們後面會講通過切面全域性列印非GET請求的介面呼叫日誌)。
    • ②. 我們可以通過這些引數資訊處理我們的業務邏輯,而沒有必要在用到的時候我們才想起來讓呼叫者將資訊傳遞過來,導致同一功能性的引數,引數名和引數值不統一的情況發生。
  2. 是每個介面都要這些引數麼?
    是的,建議將所有的介面都傳遞上述引數資訊。
  3. 怎麼做這些引數的校驗呢?
    你可以寫個攔截器,統一校驗你的介面中全域性的header引數,如果還是不太會寫,可以參考這篇文章《統一引數校驗》

備註
- Header引數大小寫不敏感,所以引數X-Token和X-TOEKN是一個引數

請求體引數

引數傳遞分為了大體兩種 URL請求查詢引數、請求體引數,對於請求體引數我們選擇以JSON格式傳遞過來,URL請求查詢引數、請求體引數這兩種方式分別對應了spring mvc框架中的 @RequestParam、@RequestBody兩個註解進行修飾。
我們下面以新增一個使用者舉例,用POST MAN截圖如下:

舉例

開發例項

package com.zhuma.demo.user.web;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.zhuma.demo.comm.model.po.User;
import com.zhuma.demo.user.service.user.UserService;
import com.github.pagehelper.PageInfo;

/**
 * 使用者管理控制器
 */
@RestController
@RequestMapping("/users")
public class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping
    public PageInfo<User> getUserList(@RequestParam(name="pageNum", defaultValue="1") Integer pageNum, 
                                        @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
                                        @RequestParam(name="queryUser") User queryUser) {
        return userService.pageList(queryUser, pageNum, pageSize);
    }

    @GetMapping("/{userId}")
    User getUser(@PathVariable("userId") Long userId) {
        return userService.getUserById(userId);
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public User addUser(@Valid @RequestBody User user) {
        return userService.register(user);
    }

    @PutMapping
    public User updateUser(@RequestBody User user) {
        return userService.updateDbAndCache(user);
    }

    @DeleteMapping("/{userId}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    void deleteUser(@PathVariable("userId") Long userId) {
        userService.deleteUserById(userId);
    }

}

上面我們擷取一個管理使用者的功能控制器,可能其中有一些你不瞭解的註解,例如@Valid、@ResponseStatus我們後面會講解,所以你可以先不必關注這些,我們主要看@GetMapping、@PostMapping、
@PutMapping、@DeleteMapping 分別處理查、修改、刪除功能,@RequestParam、@RequestBody 分別表示
查詢引數、json body體引數。

備註

結束語

下一篇文章我們主要講解下 《介面返回值篇》 O(∩_∩)O

歡迎關注我們的公眾號或加群,等你哦!