[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   进击的davis  阅读(324)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示