文档
1、实现一个简易的服务端
package main
import (
"fmt"
"net/http"
)
// 请求处理函数
func helloHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world!"))
}
func main() {
// 路由
http.HandleFunc("/", helloHandler)
// 启动服务
fmt.Printf("http server starting at http://127.0.0.1:9090\n")
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Printf("http server failed, err:%v\n", err)
return
}
}
请求示例
$ curl http://127.0.0.1:9090/
hello world!
示例
2、实现一个类似 https://httpbin.org/
的服务,返回请求的信息
package main
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
)
type Result struct {
Args map[string]string `json:"args"`
Headers map[string]string `json:"headers"`
Form map[string]string `json:"form"`
Json map[string]interface{} `json:"json"`
Method string `json:"method"`
Data string `json:"data"`
Url string `json:"url"`
Origin string `json:"origin"`
}
func echoHandler(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
ret := &Result{}
ret.Method = r.Method
ret.Origin = r.RemoteAddr
// 完整url
scheme := "http://"
if r.TLS != nil {
scheme = "https://"
}
ret.Url = strings.Join([]string{scheme, r.Host, r.RequestURI}, "")
// raw data
data, _ := io.ReadAll(r.Body)
ret.Data = string(data)
// form
// r.ParseForm()
// ret.Form = make(map[string]string)
// for key, _ := range r.PostForm {
// ret.Form[key] = r.PostForm.Get(key)
// }
// 通过raw data解析
ret.Form = make(map[string]string)
form, err := url.ParseQuery(string(data))
if err != nil {
for key, _ := range form {
ret.Form[key] = form.Get(key)
}
}
// json
ret.Json = make(map[string]interface{})
json.Unmarshal(data, &ret.Json)
// args
ret.Args = make(map[string]string)
for key, _ := range r.URL.Query() {
ret.Args[key] = r.URL.Query().Get(key)
}
// header
ret.Headers = make(map[string]string)
for key, _ := range r.Header {
ret.Headers[key] = r.Header.Get(key)
}
body, _ := json.Marshal(ret)
w.Write(body)
}
func main() {
// 路由
http.HandleFunc("/", echoHandler)
// 启动服务
fmt.Printf("http server starting at http://127.0.0.1:9090\n")
err := http.ListenAndServe(":9090", nil)
if err != nil {
fmt.Printf("http server failed, err:%v\n", err)
return
}
}
注意:由于请求体只能读取一次,所以form和rawData只能取到一个
通过客户端发起请求
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
targetUrl := "http://127.0.0.1:9090"
// url args
u, _ := url.ParseRequestURI(targetUrl)
params := url.Values{}
params.Set("name", "Tom")
params.Set("age", "18")
u.RawQuery = params.Encode() // URL encode
// json
data := make(map[string]interface{})
data["name"] = "Tom"
data["age"] = 12
resqdata, _ := json.Marshal(data)
client := &http.Client{}
req, _ := http.NewRequest("POST", u.String(), bytes.NewReader(resqdata))
// header
req.Header.Add("X-Token", "token")
req.Header.Add("Content-Type", "application/json")
resp, _ := client.Do(req)
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))
}
返回结果
{
"args": {
"age": "18",
"name": "Tom"
},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "23",
"Content-Type": "application/json",
"User-Agent": "Go-http-client/1.1",
"X-Token": "token"
},
"form": {},
"json": {
"age": 12,
"name": "Tom"
},
"method": "POST",
"data": "{\"age\":12,\"name\":\"Tom\"}",
"url": "http://127.0.0.1:9090/?age=18&name=Tom",
"origin": "127.0.0.1:62103"
}
可以看到,我们的服务端可以正确获取到请求的参数信息和json请求体,以及请求头部信息
【参考 】
- 深入探索Go语言net/http包:构建高性能的Web服务
- Golang:发起http请求-GET带参数、POST发送Form和JSON数据