HTTP和RESTful API

TCP/IP五層網(wǎng)絡(luò)架構(gòu)

  • 應(yīng)用層(HTTP,RPC等)——直接和應(yīng)用程序接口并提供常見的網(wǎng)絡(luò)應(yīng)用服務(wù)
  • 傳輸層(TCP)——同一個網(wǎng)絡(luò)中鏈接的兩個節(jié)點,如何完成端對端的連接
  • 網(wǎng)絡(luò)層(IP)——同一個網(wǎng)絡(luò)的機器如何去協(xié)作和傳遞數(shù)據(jù),建立一條路徑,保證傳輸數(shù)據(jù)的一致
  • 數(shù)據(jù)鏈路層——網(wǎng)線兩端的設(shè)備如何傳遞數(shù)據(jù)
  • 物理層——一條網(wǎng)線如何去傳輸數(shù)據(jù)

數(shù)據(jù)鏈路層和物理層是設(shè)備工程師考慮的問題,而應(yīng)用層、傳輸層、網(wǎng)絡(luò)層是Web工程師該考慮的問題

HTTP協(xié)議

  • HTTP協(xié)議是互聯(lián)網(wǎng)的基礎(chǔ)協(xié)議
  • 本質(zhì)上是Web前端程序和Web后端程序的通信的協(xié)議
  • 定義了前端給后端發(fā)送請求的格式
  • 同時也定義了后端解析前端發(fā)來的請求(HTTP請求)的方式
  • 使用程序語言來描述,HTTP協(xié)議給后端程序定義了一個接口
  • 每個請求都是獨立的,每個請求都需要顯示的附帶狀態(tài)信息(無狀態(tài))
  • 互聯(lián)網(wǎng)上的所有內(nèi)容都是資源,每個資源有唯一的URL
  • 交互就是對互聯(lián)網(wǎng)資源的操作(GET,PUT,POST,DELETE)
  • 資源的操作結(jié)果都有狀態(tài)返回碼

HTTP請求格式

  • 請求路徑——URL,例如:https://pandorawanz.github.io
  • 請求操作命令(動詞):GET,POST,PUT,DELETE,TRACE,OPTIONS,CONNECT,PATCH
  • 客戶端標記User-Agent,值的離子:Mozilla.5.0(火狐的內(nèi)核) (Macintosh; Intel Mac OS X 10_10_5)
  • 接收類型Content-Type,值的例子:text/plain,text/html,image/jepg
  • Cookie:用于傳送和狀態(tài)相關(guān)的信息的鍵值對

HTTP回應(yīng)格式

  • HTTP協(xié)議版本:HTTP/1.1
  • HTTPStatus:200,201,404
  • 時間,例如:Sat,29 Sep 2018 07:24:53 GMT
  • Content-Type:text/plain,text/html,image/jpeg
    以上是HTTP協(xié)議在程序語義層面的定義,同時也抽象了整個互聯(lián)網(wǎng)內(nèi)容的組織和交互方式

常見的Content-Type字段值

  • text/plain
  • text/html
  • text/css
  • image/jpeg
  • image/png
  • image/svg+xml
  • audio/mp4
  • video/mp4
  • application/javascript
  • application/pdf
  • application/zip
  • application/atpm+xml

HTTPStatus

  • 1xx消息——請求已被服務(wù)器接收,繼續(xù)處理
  • 2xx成功——請求已成功被服務(wù)器接收、理解、并接受
  • 3xx重定向——需要后續(xù)操作才能完成這一請求
  • 4xx請求錯誤——請求含有詞法錯誤或者無法被執(zhí)行(客戶端責任)
  • 5xx服務(wù)器錯誤——服務(wù)器在處理某個正確請求時發(fā)生錯誤(服務(wù)端責任)

總結(jié)

一個HTTP請求在語義上表達對一個互聯(lián)網(wǎng)資源(URL)的操作(GET,POST,PUT,Delete),然后Web后端返回資源操作的結(jié)果和相關(guān)信息

RESTful API

RESTful API就是基于HTTP協(xié)議對互聯(lián)網(wǎng)的內(nèi)容定義的方式提出的一套互聯(lián)網(wǎng)應(yīng)用的架構(gòu)體系,其中信息以JSON的形式進行存儲,對對象的資源、操作、狀態(tài)
進行定義,RESTful是一種設(shè)計模式規(guī)范的指南,不是強制性的要求,所以要靠開發(fā)者自己遵守

URL基本要求

1.協(xié)議:HTTP或HTTPS
2.域名和地址一般格式:http://<域名>/api/<version>
3.域名和地址之后接資源名字統(tǒng)一用復(fù)數(shù)

寫RESTful API步驟

1.想清楚我們的應(yīng)用里可以抽象出什么樣的資源,和他們的層次結(jié)構(gòu)
2.想清楚對對象的基本操作:GET,POST,PUT,DELETE的含義是什么
3.組織接口代碼。Spring如何去定義這些路由(URL):URL->Java類方法
4.開始實現(xiàn)

HTTP相關(guān)Web編程

采用了Spring框架,在Maven中配置好pom.xml即可,pom.xml相關(guān)配置在https://pandorawanz.github.io/2018/10/14/SpringBootStarted/

操作相關(guān)注解

  • @RequestMapping
  • @PostMapping
  • @GetMapping
  • @PutMapping
  • @Deletemapping

參數(shù)相關(guān)注解

  • @RequestBody
  • @PathVariable

User

public class User {
    private String name;
    private String content;

    public User() {
        // default constructor for spring mapping
        // Spring中不可以省略空構(gòu)造方法
    }

    public User(String name, String content) {
        this.name = name;
        this.content = content;
    }

    public String getName() {
        return name;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public void setName(String name) {
        this.name = name;
    }
}

UserController

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

// 告訴Spring這是個Controller
// 資源的控制,資源的接口合集
@RestController
public class UserController {

    // user -> User對象
    private final HashMap<String, User> users = new HashMap<>();

    // Spring 通過HTTP請求中的操作(GET, POST, PUT, DELETE) + URL確定調(diào)用方法來處理請求

    /**
     * 響應(yīng) GET /users 這樣的請求
     * 查詢用戶列表
     * @return 所有用戶列表
     */
    @GetMapping("/users")
    List<User> listUsers() {
        return new ArrayList<>(users.values());
    }

    /**
     * 響應(yīng) GET /users/{name}
     * 通過User的name查詢具體User對象
     * @param name
     * @return name確定User對象
     */
    @GetMapping("/users/{name}")
    // 從path中提取出name
    ResponseEntity<User> getUser(@PathVariable String name) {
        if (users.containsKey(name)) {
            return new ResponseEntity<>(users.get(name),HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }

    /**
     * 響應(yīng) POST /users 這樣的請求
     * 添加一個用戶到我們用戶列表里
     * @param user
     * @return 返回創(chuàng)建成功的User對象
     */

    /*
    @PostMapping("/users")
    User newUser(@RequestBody User user) {
        users.put(user.getName(),user);
        return users.get(user.getName());
    }
    */

    /**
     * 響應(yīng) POST /users 這樣的請求
     * 添加一個用戶到我們用戶列表里
     * @param user
     * @return 返回創(chuàng)建成功的User對象
     */
    @PostMapping("/users")
    ResponseEntity<User> newUser(@RequestBody User user) {
        users.put(user.getName(),user);
        // 創(chuàng)建成功后返回User對象,以及自定義的狀態(tài)值201
        return new ResponseEntity<>(users.get(user.getName()), HttpStatus.CREATED);
    }

    /**
     * 響應(yīng) PUT /users/{name} 這樣的請求
     * @param name
     * @param updatedUser
     * @return 修改之后的User對象
     */
    @PutMapping("/users/{name}")
    ResponseEntity<User> updateUser(@PathVariable String name,@RequestBody User updatedUser) {
        if (users.containsKey(name)) {
            User user = users.get(name);
            user.setContent(updatedUser.getContent());
            return new ResponseEntity<>(user,HttpStatus.OK);
        } else return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    /**
     * 響應(yīng) DELETE /users/{name} 這樣的請求
     * 刪除 name 確定的User對象
     * @param name
     */
    @DeleteMapping("/users/{name}")
    ResponseEntity<Void> deleteUser(@PathVariable String name) {
        if (users.containsKey(name)) {
            users.remove(name);
            return new ResponseEntity<>(HttpStatus.OK);
        } else return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }
}

Application

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

// 告訴Spring從這里啟動
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容