[go-每日一库] go借助net/http包实现客户端get、post请求

本文主要通过net/http实现简单server,另外根据net/http,区分简单请求和带参数的复杂请求实现客户端。

1.server端

package main

import (
	"encoding/json"
	"log"
	"net/http"
)

func main()  {
	http.HandleFunc("/index", index)
	http.HandleFunc("/login", login)

	log.Println("http server is starting now...")
	http.ListenAndServe(":8080", nil)
}

type Auth struct {
	User string `json:"user"`
	Pass string `json:"pass"`
}

type LoginResp struct {
	Msg  string `json:"msg"`
	Code int    `json:"code"`
}

func index(w http.ResponseWriter, r *http.Request)  {
	log.Printf("calling %s from %s", r.URL,r.RemoteAddr)
	clientIP := r.Host
	respData, _ := json.Marshal(map[string]string{"msg": "hello index", "user": clientIP})
	// method-1
	w.Write(respData)
	// method-2
	//fmt.Fprintf(w, "hello index, user: %s", clientIP)
}

func login(w http.ResponseWriter, r *http.Request)  {
	log.Printf("calling %s from %s", r.URL,r.RemoteAddr)
	var auth Auth
	if err := json.NewDecoder(r.Body).Decode(&auth); err != nil {
		defer r.Body.Close()
		log.Println(err)
	}

	var resp LoginResp
	resp.Msg = "login success."
	resp.Code = 0
	if err := json.NewEncoder(w).Encode(resp); err != nil {
		log.Println(err)
	}
}

2.client端

2.1 简单请求

package main

import (
	"io/ioutil"
	"log"
	"net/http"
)

func main()  {
	// get-index
	GetIndex()
}

const (
	url string = "http://localhost:8080"
)

func GetIndex()  {
	indexUrl := url + "/index"
	resp, _ := http.Get(indexUrl)
	defer resp.Body.Close()
	// parse-1 resp by ioutil
	data, _ := ioutil.ReadAll(resp.Body)

	// parse-2 resp by json if data is json type
	//var data interface{}
	//_ = json.NewDecoder(resp.Body).Decode(&data)

	log.Printf("recv from server: %s, data type: %T", data, data)
}

2.2 带参数的请求

package main

import (
	"bytes"
	"encoding/json"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
	"time"
)

func main()  {
	GetIndex()
	PostLogin()
	PostLoginVersion2()
}

const (
	url = "http://127.0.0.1:8080"
)

func GetIndex() string {
	indexUrl := url + "/index"
	client := &http.Client{Timeout: 10*time.Second}
	resp, err := client.Get(indexUrl)
	if err != nil {
		log.Println(err)
	}
	defer resp.Body.Close()

	// 循环读取返回数据,统一处理,也可以通过ioutil.Readall()处理数据
	var buf [1024]byte
	res := bytes.NewBuffer(nil)
	for {
		n, err := resp.Body.Read(buf[0:])
		res.Write(buf[0:n])
		if err != nil && err == io.EOF {
			break
		} else if err != nil {
			log.Println(err)
		}
	}

	log.Println(res.String())
	return res.String()
}

type Auth struct {
	User string `json:"user"`
	Pass string `json:"pass"`
}

func PostLogin() string {
	// 1.构造请求
	loginUrl := url + "/login"
	client := &http.Client{Timeout: 10 * time.Second}
	data := Auth{"name", "passwd"}
	jsonStr, _ := json.Marshal(data)
	resp, err := client.Post(loginUrl, "application/json", bytes.NewBuffer(jsonStr))
	defer resp.Body.Close()
	if err != nil {
		log.Println(err)
	}
	// 解析、读取返回数据
	res, _ := ioutil.ReadAll(resp.Body)
	log.Println(string(res))
	return string(res)
}

func PostLoginVersion2()  {
	// 1.构造请求
	loginUrl := url + "/login"
	data := Auth{"name", "passwd"}
	bytes, _ := json.Marshal(data)
	body := strings.NewReader(string(bytes))
	client := &http.Client{}
	req, err := http.NewRequest("POST", loginUrl, body)
	// 设置请求头
	req.Header.Set("Content-Type", "application/json")
	// 发出请求
	resp, err := client.Do(req)
	defer resp.Body.Close()
	// 读取返回结果,respData为字节切片,根据需求可转为map或者string或者struct数据做进一步处理
	respData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Println(err)
	}

	log.Println("PostLoginVersion2's response data:", string(respData))
}

3.响应数据的解析

// 1.ioutil -> 返回字节数组
data, _ := ioutil.ReadAll(resp.Body) 

// 2.json -> 返回
var data interface{}
_ = json.NewDecoder(resp.Body).Decode(&data)

// 3.buffer循环读取
...
	var buf [1024]byte
	res := bytes.NewBuffer(nil)
	for {
		n, err := resp.Body.Read(buf[0:])
		res.Write(buf[0:n])
		if err != nil && err == io.EOF {
			break
		} else if err != nil {
			log.Println(err)
		}
	}
...

4.通过NewClient || client 构建req

构建带请求参数的请求时,即带上了body,只要实现了io.Reader接口的都可以, 这里介绍几种方法侯建body:

1.通过bytes包实现
data := Auth{"name", "passwd"}
jsonStr, _ := json.Marshal(data)
body := bytes.NewBuffer(jsonStr)

2.通过strings包实现
data := Auth{"name", "passwd"}
bytes, _ := json.Marshal(data)
body := strings.NewReader(string(bytes))

posted on 2022-06-27 15:11  进击的davis  阅读(257)  评论(0编辑  收藏  举报

导航