当前位置: 移动技术网 > IT编程>开发语言>Java > Go 语言编程 — net/http

Go 语言编程 — net/http

2020年07月21日  | 移动技术网IT编程  | 我要评论

目录

net/http

HTTP 是典型的 C/S 架构,客户端和服务端面对的都是双向的 HTTP 请求与响应,客户端构建请求并等待响应,服务端处理请求并返回响应。

Golang 的 net/http 标准库同时封装了 HTTP 客户端和服务端的实现。

官方文档:

  • 英文:https://golang.org/pkg/net/http/
  • 中文:https://cloud.tencent.com/developer/section/1143633

为了支持更好的扩展性,还引入了 http.RoundTripper 和 http.Handler 两个接口。

  • http.Handler(请求处理程序):主要用于作为 HTTP 服务器响应客户端的 request。实现了处理 HTTP 请求的逻辑,处理的过程中会调用 http.ResponseWriter 接口的方法来构造一个相应的 HTTP 响应。
type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}
  • http.ResponseWriter(响应编写器):提供了三个接口 Header、Write 和 WriteHeader 分别用于获取 HTTP 响应、将数据写入负载(Payload)和响应头(Header)。
type ResponseWriter interface {
	Header() Header
	Write([]byte) (int, error)
	WriteHeader(statusCode int)
}
  • http.RoundTripper:用来表示执行 HTTP 请求的接口,调用者将 request 对象作为参数传入,就可以获取对应的 response 或 error。是一种特殊的调用方式,谓之 “往返者”。
type RoundTripper interface {
    RoundTrip(*Request) (*Response, error)
}

在这里插入图片描述

HTTP 客户端

net/http 为客户端提供了 Get、Head、Post 和 PostForm 函数来发起 HTTP/HTTPS 请求。

示例

  • 发出一个简单的 http.Get 请求:
package main

import (
    "bytes"
    "fmt"
    "log"
    "net/http"
    "reflect"
)

func main() {

    resp, err := http.Get("http://www.baidu.com")
    if err != nil {
        // handle error
        log.Println(err)
        return
    }

    defer resp.Body.Close()

    headers := resp.Header

    for k, v := range headers {
        fmt.Printf("k=%v, v=%v\n", k, v)
    }

    fmt.Printf("resp status %s,statusCode %d\n", resp.Status, resp.StatusCode)
    fmt.Printf("resp Proto %s\n", resp.Proto)
    fmt.Printf("resp content length %d\n", resp.ContentLength)
    fmt.Printf("resp transfer encoding %v\n", resp.TransferEncoding)
    fmt.Printf("resp Uncompressed %t\n", resp.Uncompressed)
    fmt.Println(reflect.TypeOf(resp.Body)) // *http.gzipReader

    buf := bytes.NewBuffer(make([]byte, 0, 512))

    length, _ := buf.ReadFrom(resp.Body)

    fmt.Println(len(buf.Bytes()))
    fmt.Println(length)
    fmt.Println(string(buf.Bytes()))
}
  • 使用 http.Post 或 http.PostForm 发出 POST 请求:
package main

import (
    "bytes"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    body_json_str := "{\"action\":20}"
    res, err := http.Post("http://xxx.com", "application/json;charset=utf-8",
    	bytes.NewBuffer([]byte(body_json_str)))
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }
    defer res.Body.Close()

    content, err := ioutil.ReadAll(res.Body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }
    fmt.Println(string(content))
}
  • http.PostForm:
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
)

func main() {

    postParam := url.Values{
        "mobile":      {"xxxxxx"},
        "isRemberPwd": {"1"},
    }

    resp, err := http.PostForm("http://www.maimaiche.com/loginRegister/login.do", postParam)
    if err != nil {
        fmt.Println(err)
        return
    }

    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println(err)
        return
    }

    fmt.Println(string(body))
}
  • 使用 http.NewRequest 来创建 request 对象,再通过 http.Client 执行这个 request 对象:
package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "strings"
)

func main() {
    v := url.Values{}
    v.Set("username", "xxxx")
    v.Set("password", "xxxx")
    body := ioutil.NopCloser(strings.NewReader(v.Encode()))
    req, err := http.NewRequest("POST", "http://xxx.com/logindo", body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }
    req.Header.Set("Content-Type", "application/x-www-form-urlencoded;param=value")

    client := &http.Client{}
    resp, err := client.Do(req)
    defer resp.Body.Close()

    content, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Fatal error ", err.Error())
    }

    fmt.Println(string(content))
}
  • 客户端忽略 TLS 证书认证:
package main

import (
    "crypto/tls"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {

    tr := &http.Transport{
        TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    }

    client := &http.Client{Transport: tr}

    seedUrl := "https://www.douban.com/"
    resp, err := client.Get(seedUrl)
    if err != nil {
        fmt.Errorf("get https://www.douban.com/ error")
        panic(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        fmt.Errorf("get https://www.douban.com/ error")
        panic(err)
    }

    fmt.Printf("%s\n", body)
}

实现原理

HTTP 服务端

package main

import (
    "fmt"
    "net/http"
)

func indexHandler(w http.ResponseWriter, request *http.Request) {
    fmt.Fprintln(w, "Hello World.")
}

func main() {
    http.HandleFunc("/", indexHandler)
    err := http.ListenAndServe("127.0.0.1:80", nil)
    if err != nil {
        fmt.Println("ListenAndServe: ", err)
    }
}

示例

实现原理

在这里插入图片描述

在这里插入图片描述

注册请求路由

监听请求

处理请求

支持 https

HTTP 客户端

HTTP 服务端

本文地址:https://blog.csdn.net/Jmilk/article/details/107475006

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网