golang http标准库介绍及简单使用

http标准库客户端功能 发出GET请求 package main import ( "fmt" "io/ioutil" "log" "net/http" "net/url" "time" ) func testGet() { // https

http标准库客户端功能

发出GET请求

package main
import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "time"
)
func testGet() {
    // https://www.juhe.cn/box/index/id/73
    url := "http://apis.juhe.cn/simpleWeather/query?key=087d7d10f700d20e27bb753cd806e40b&city=北京"
    r, err := http.Get(url)
    if err != nil {
        log.Fatal(err)
    }
    defer r.Body.Close()
    b, _ := ioutil.ReadAll(r.Body)
    fmt.Printf("b: %v\n", string(b))
}

运行结果

{
    "reason":"查询成功!",
    "result":{
        "city":"北京",
        "realtime":{
            "temperature":"3",
            "humidity":"94",
            "info":"阴",
            "wid":"02",
            "direct":"东北风",
            "power":"2级",
            "aqi":"117"
        },
        "future":[
            {
                "date":"2021-12-09",
                "temperature":"-1\/7℃",
                "weather":"多云转晴",
                "wid":{
                    "day":"01",
                    "night":"00"
                },
                "direct":"北风"
            },
            {
                "date":"2021-12-10",
                "temperature":"-1\/8℃",
                "weather":"多云",
                "wid":{
                    "day":"01",
                    "night":"01"
                },
                "direct":"北风转西南风"
            },
            {
                "date":"2021-12-11",
                "temperature":"-2\/10℃",
                "weather":"多云转晴",
                "wid":{
                    "day":"01",
                    "night":"00"
                },
                "direct":"北风"
            },
            {
                "date":"2021-12-12",
                "temperature":"-5\/4℃",
                "weather":"晴",
                "wid":{
                    "day":"00",
                    "night":"00"
                },
                "direct":"西北风转西南风"
            },
            {
                "date":"2021-12-13",
                "temperature":"-6\/5℃",
                "weather":"晴",
                "wid":{
                    "day":"00",
                    "night":"00"
                },
                "direct":"西南风"
            }
        ]
    },
    "error_code":0
}

本实例我们使用到了:https://www.juhe.cn/box/index/id/73 天气查询api

GET请求,把一些参数做成变量而不是直接放到url


func testGet2() {
    params := url.Values{}
    Url, err := url.Parse("http://apis.juhe.cn/simpleWeather/query")
    if err != nil {
        return
    }
    params.Set("key", "087d7d10f700d20e27bb753cd806e40b")
    params.Set("city", "北京")
    //如果参数中有中文参数,这个方法会进行URLEncode
    Url.RawQuery = params.Encode()
    urlPath := Url.String()
    fmt.Println(urlPath)
    resp, err := http.Get(urlPath)
    if err != nil {
        log.Fatal(err)
    }
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

解析JSON类型的返回结果


package main
import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "time"
)
func testParseJson() {
    type result struct {
        Args    string            `json:"args"`
        Headers map[string]string `json:"headers"`
        Origin  string            `json:"origin"`
        Url     string            `json:"url"`
    }
    resp, err := http.Get("http://httpbin.org/get")
    if err != nil {
        return
    }
    defer resp.Body.Close()
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
    var res result
    _ = json.Unmarshal(body, &res)
    fmt.Printf("%#v", res)
}

运行结果

{
  "args": {},
  "headers": {
    "Accept-Encoding": "gzip",
    "Host": "httpbin.org",
    "User-Agent": "Go-http-client/1.1",
    "X-Amzn-Trace-Id": "Root=1-61b16029-731c99ba4591c9bd3db53edd"
  },
  "origin": "115.171.25.28",
  "url": "http://httpbin.org/get"
}
main.result{Args:"", Headers:map[string]string{"Accept-Encoding":"gzip", "Host":"httpbin.org", "User-Agent":"Go-http-client/1.1", "X-Amzn-Trace-Id":"Root=1-61b16029-731c99ba4591c9bd3db53edd"}, Origin:"115.171.25.28", Url:"http://httpbin.org/get"}

GET请求添加请求头


package main
import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "time"
)
func testAddHeader() {
    client := &http.Client{}
    req, _ := http.NewRequest("GET", "http://httpbin.org/get", nil)
    req.Header.Add("name", "Lemon")
    req.Header.Add("age", "80")
    resp, _ := client.Do(req)
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Printf(string(body))
}

运行结果


{
  "args": {},
  "headers": {
    "Accept-Encoding": "gzip",
    "Age": "3",
    "Host": "httpbin.org",
    "Name": "zhaofan",
    "User-Agent": "Go-http-client/1.1",
    "X-Amzn-Trace-Id": "Root=1-61b16107-5814e133649862c20ab1c26f"
  },
  "origin": "115.171.25.28",
  "url": "http://httpbin.org/get"
}

发出POST请求


func testPost() {
    path := "http://apis.juhe.cn/simpleWeather/query"
    urlValues := url.Values{}
    urlValues.Add("key", "087d7d10f700d20e27bb753cd806e40b")
    urlValues.Add("city", "哈尔滨")
    r, err := http.PostForm(path, urlValues)
    if err != nil {
        log.Fatal(err)
    }
    defer r.Body.Close()
    b, _ := ioutil.ReadAll(r.Body)
    fmt.Printf("b: %v\n", string(b))
}

另外一种方式

func testPost2() {
    urlValues := url.Values{
        "name": {"Lemon"},
        "age":  {"80"},
    }
    reqBody := urlValues.Encode()
    resp, _ := http.Post("http://httpbin.org/post", "text/html", strings.NewReader(reqBody))
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

发送JSON数据的post请求

func testPostJson() {
    data := make(map[string]interface{})
    data["site"] = "ning0818.cn"
    data["name"] = "Lemon"
    bytesData, _ := json.Marshal(data)
    resp, _ := http.Post("http://httpbin.org/post", "application/json", bytes.NewReader(bytesData))
    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}

使用Client自定义请求


func testClient() {
    client := http.Client{
        Timeout: time.Second * 5,
    }
    url := "http://apis.juhe.cn/simpleWeather/query?key=087d7d10f700d20e27bb753cd806e40b&city=北京"
    req, err := http.NewRequest(http.MethodGet, url, nil)
    if err != nil {
        log.Fatal(err)
    }
    req.Header.Add("referer", "http://apis.juhe.cn/")
    res, err2 := client.Do(req)
    if err2 != nil {
        log.Fatal(err2)
    }
    defer res.Body.Close()
    b, _ := ioutil.ReadAll(res.Body)
    fmt.Printf("b: %v\n", string(b))
}

HTTP Server

使用golang实现一个http server非常简单,代码如下:

func testHttpServer() {
    // 请求处理函数
    f := func(resp http.ResponseWriter, req *http.Request) {
        io.WriteString(resp, "hello world")
    }
    // 响应路径,注意前面要有斜杠 /
    http.HandleFunc("/hello", f)
    // 设置监听端口,并监听,注意前面要有冒号:
    err := http.ListenAndServe(":9999", nil)
    if err != nil {
        log.Fatal(err)
    }
}

在浏览器输入:

http://localhost:9999/hello

运行结果:

hello world

使用Handler实现并发处理


type countHandler struct {
    mu sync.Mutex // guards n
    n  int
}
func (h *countHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    h.mu.Lock()
    defer h.mu.Unlock()
    h.n++
    fmt.Fprintf(w, "count is %d\n", h.n)
}
func testHttpServer2() {
    http.Handle("/count", new(countHandler))
    log.Fatal(http.ListenAndServe(":8080", nil))
}

在浏览器输入:http://localhost:8080/count,刷新查看结果

count is 8

Comment