http包中request和response的接口结构
response
type ResponseWriter interface {
Header() Header //返回header
Write([]byte) (int, error) //传回数据
WriteHeader(statusCode int) //发送带有状态码的header
}
request
type Request struct {
Method string //请求方式(GET, POST, PUT, etc.)
URL *url.URL //url或者uri
Proto string // 协议,如:"HTTP/1.0"
ProtoMajor int // 1
ProtoMinor int // 0
Header Header //请求头
Body io.ReadCloser //请求体
GetBody func() (io.ReadCloser, error) //获取请求体的方法
ContentLength int64 //内容长度
TransferEncoding []string //传输编码集合
Close bool //之后是否关闭
Host string //主机名
Form url.Values //表单包含解析后的表单数据,包括URL
PostForm url.Values //包含从PATCH, POST解析的表单数据
MultipartForm *multipart.Form //多部分表单,包括文件上传
Trailer Header //指定在请求之后发送的附加头
RemoteAddr string //通常用于日志记录,HTTP服务器在调用处理程序之前将RemoteAddr设置“IP:port”地址
RequestURI string //uri
TLS *tls.ConnectionState //TLS
Cancel <-chan struct{} //一个通道,他的关闭表示请求取消
Response *Response //重新向响应
ctx context.Context //上下文
}
一个十分简单的小案例
向 http://localhost:8080/test 发送请求后,得到响应”给你响应“
func main() {
http.HandleFunc("/test",handler)
http.ListenAndServe(":8080",nil)
}
func handler (res http.ResponseWriter, req *http.Request){
res.Write([]byte("给你响应"))
}
使用postman测试结果如下:
修改其handle方法,使其对get和post请求分别处理
func handler (res http.ResponseWriter, req *http.Request){
switch req.Method {
case "GET":
res.Write([]byte("这是给GET请求的响应"))
break
case "POST":
res.Write([]byte("这是给POSt请求的响应\n"))
all, _ := io.ReadAll(req.Body)
res.Write(all)
break
}
}
效果如下:
- GET
- POST(带有请求体)
创建客户端
向 http://localhost:8080/test 发送请求
func main() {
client:= new(http.Client)
request, err := http.NewRequest("GET", "http://localhost:8080/test", nil)
if err != nil {
return
}
response, _ := client.Do(request)
body := response.Body
all, _ := io.ReadAll(body)
fmt.Println(string(all))
}
使用post请求带有body
body为{"name":"客户端"}的json串
func main() {
client:= new(http.Client)
request, err := http.NewRequest("POST", "http://localhost:8080/test",
bytes.NewBuffer([]byte("{"name":"客户端"}")))
if err != nil {
return
}
response, _ := client.Do(request)
body := response.Body
all, _ := io.ReadAll(body)
fmt.Println(string(all))
}
效果如下
在request中写入添加请求头
客户端
func main() {
client:= new(http.Client)
request, err := http.NewRequest("POST", "http://localhost:8080/test",
bytes.NewBuffer([]byte("{"name":"客户端"}")))
if err != nil {
return
}
header := request.Header
header["test"] = []string{"test","test1"}
response, _ := client.Do(request)
body := response.Body
all, _ := io.ReadAll(body)
fmt.Println(string(all))
}
服务端
func handler (res http.ResponseWriter, req *http.Request){
switch req.Method {
case "GET":
res.Write([]byte("这是给GET请求的响应"))
break
case "POST":
res.Write([]byte("这是给POSt请求的响应\n"))
header := req.Header
strings := header["Test"] //注意此处应为"Test"而不是"test"
fmt.Println(strings)
all, _ := io.ReadAll(req.Body)
res.Write(all)
break
}
}
tips:注意此处有一个坑,在请求头中写入head的key为test,然而传输时自动转变为Test将首字母进行了大写
本文正在参加技术专题18期-聊聊Go语言框架