On this page
article
4.Go-net-http
Go net-http包介绍
net-http介绍
.
├─ ClientGet
│ └── main.go // 发送get请求
├─ ClientPost
│ └── main.go // 发送post请求
├─ Server
│ └── main.go // web服务
Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现。
1.Server/main.go
- 客户端 请求信息 封装在
http.Request
对象中 - 服务端返回的 响应报文 会被保存在
http.Response
结构体中 - 发送给客户端响应的并不是
http.Response
,而是通过http.ResponseWriter
接口来实现的
方法签名 | 描述 |
---|---|
Header() |
用户设置或获取响应头信息 |
Write() |
用于写入数据到响应体 |
WriteHeader() |
用于设置响应状态码,若不调用则默认状态码为200 OK。 |
package main
import (
"encoding/json"
"io"
"log"
"net/http"
)
// 定义入参结构体
type Data struct {
Speak string `json:"speak"`
}
// 处理get请求
func dealGetReqHandler(w http.ResponseWriter, r *http.Request) {
query := r.URL.Query()
//获取请求参数两种方法
if len(query["name"]) > 0 {
name := query["name"][0]
log.Printf("1.通过map中切片的下标获取:%s\n", name)
}
name2 := query.Get("name") //没有的话就会返回空值
log.Printf("2.通过Get方法获取:%s\n", name2)
data := &Data{
name2 + "是笨蛋",
}
//响应json数据:序列化了一下data对象,并写入响应体w中
json.NewEncoder(w).Encode(data)
//也可以w.Write([]byte(··json数据··))
}
// 处理post请求
func dealPostReqHandler(w http.ResponseWriter, r *http.Request) {
//获取请求体数据
bodyByte, err := io.ReadAll(r.Body)
if err != nil {
w.Write([]byte(err.Error()))
}
//转成结构体示范,为了可以更好的处理数据,而不是必须转结构体才能json返回
bodyStr := string(bodyByte)
data := &Data{}
json.Unmarshal([]byte(bodyStr), &data)
log.Printf("从post请求体中获取到的数据:%s\n", data.Speak)
//返回响应内容
data.Speak = data.Speak + "是笨蛋"
//返回响应体内容
json.NewEncoder(w).Encode(data)
}
// 启动http服务
func main() {
//注册全局路由
http.HandleFunc("/req/post", dealPostReqHandler)
http.HandleFunc("/req/get", dealGetReqHandler)
http.ListenAndServe(":8000", nil)
}
- 一个路由对应一个handler:
/api/xxx
对应的是一个处理方法 http.ResponseWriter
用来响应内容*http.Request
用来拿到请求头或者请求参数
测试
fei@feideMBP Server % go run main.go
2024/10/02 02:43:58 1.通过map中切片的下标获取:虞锋
2024/10/02 02:43:58 2.通过Get方法获取:虞锋
2024/10/02 02:44:04 从post请求体中获取到的数据:虞锋
fei@feideMBP ~ % curl http://127.0.0.1:8000/req/get?name=虞锋
{"speak":"虞锋是笨蛋"}
fei@feideMBP ~ % curl -X POST http://127.0.0.1:8000/req/post \
-H 'Content-Type: application/json' \
-d '{"speak":"虞锋"}'
{"speak":"虞锋是笨蛋"}
2.ClientGet/main.go
package main
import (
"io"
"log"
"net/http"
"net/url"
)
func main() {
apiUrl := "http://localhost:8000/req/get"
//定义url参数
data := url.Values{}
data.Set("name", "httpGet-root")
//组装url
u, err := url.ParseRequestURI(apiUrl)
if err != nil {
panic(err)
}
u.RawQuery = data.Encode()
log.Printf("请求路由为:%s\n", u.String())
//发起请求
resp, err := http.Get(u.String())
if err != nil {
panic(err)
}
defer resp.Body.Close()
//读取
byteBody, _ := io.ReadAll(resp.Body)
log.Printf("返回数据为:%s\n", string(byteBody))
}
测试
# 启动server
fei@feideMBP Server % go run main.go
2024/10/02 03:39:08 1.通过map中切片的下标获取:httpGet-root
2024/10/02 03:39:08 2.通过Get方法获取:httpGet-root
# 启动getclient
fei@feideMBP ClientGet % go run main.go
2024/10/02 03:39:08 请求路由为:http://localhost:8000/req/get?name=httpGet-root
2024/10/02 03:39:08 返回数据为:{"speak":"httpGet-root是笨蛋"}
3.ClientPost/main.go
package main
import (
"io"
"log"
"net/http"
"strings"
)
func main() {
apiUrl := "http://localhost:8000/req/post"
//定义请求体及header
contentType := "application/json"
data := `{"speak":"httpPost"}`
resp, err := http.Post(apiUrl, contentType, strings.NewReader(data))
if err != nil {
panic(err)
}
defer resp.Body.Close()
//读取
byteBody, _ := io.ReadAll(resp.Body)
log.Printf("返回数据为:%s\n", string(byteBody))
}
测试
# 启动server
fei@feideMBP Server % go run main.go
2024/10/02 03:51:39 从post请求体中获取到的数据:httpPost
# 启动postclient
fei@feideMBP ClientPost % go run main.go
2024/10/02 03:51:39 返回数据为:{"speak":"httpPost是笨蛋"}
Last updated 02 Oct 2024, 03:56 +0800 .