ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

golang中的标准库http

2021-12-01 18:32:46  阅读:174  来源: 互联网

标签:http nil err fmt golang 标准 Println resp


Go语言内置的net/http包十分的优秀,提供了HTTP客户端和服务端的实现。

http客户端

基本的HTTP/HTTPS请求 Get、Head、Post和PostForm函数发出HTTP/HTTPS请求。

resp, err := http.Get("http://5lmh.com/")
...
resp, err := http.Post("http://5lmh.com/upload", "image/jpeg", &buf)
...
resp, err := http.PostForm("http://5lmh.com/form",
    url.Values{"key": {"Value"}, "id": {"123"}})

程序在使用完response后必须关闭回复的主体。

resp, err := http.Get("http://5lmh.com/")
if err != nil {
    // handle error
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
// ...

GET请求示例

使用net/http包编写一个简单的发送HTTP请求的Client端,代码如下:

func main() {
	resp, err := http.Get("https://www.liwenzhou.com")
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	// 使用完response之后必须关闭使用的主体
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(string(body))
}

将上面的代码保存之后编译成可执行文件,执行之后就能在终端打印liwenzhou.com网站首页的内容了,我们的浏览器其实就是一个发送和接收HTTP协议数据的客户端,我们平时通过浏览器访问网页其实就是从网站的服务器接收HTTP数据,然后浏览器会按照HTML、CSS等规则将网页渲染展示出来。

带参数的GET请求示例

关于GET请求的参数需要使用Go语言内置的net/url这个标准库来处理。

  1. server.go
func main() {
	http.HandleFunc("/", SayHello)
	if err := http.ListenAndServe(":8000", nil); err != nil {
		fmt.Println(err.Error())
		return
	}
}

func SayHello(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	data := r.URL.Query()
	name := data.Get("name")
	age := data.Get("age")
	fmt.Println(name, age)
	answer := `{"status": "ok"}`
	w.Write([]byte(answer))
}
  1. client.go
func main() {
	//resp, err := http.Get("http://127.0.0.1:8000")
	apiUrl := "http://127.0.0.1:8000"
	data := url.Values{}  // 类型:type Values map[string][]string
	data.Set("name", "张三")
	data.Set("age", "18")
	u, err := url.ParseRequestURI(apiUrl)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	u.RawQuery = data.Encode()
	fmt.Println(u.String())
	resp, err := http.Get(u.String())
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer resp.Body.Close()
	/*
	reader := bufio.NewReader(resp.Body)
	buf := make([]byte, 1000)
	n, _ := reader.Read(buf)
	fmt.Println(buf[:n])
	 */
	// ioutil.ReadAll() 代替了上面这段
	buf, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(string(buf))
}

POST请求示例

上面演示了使用net/http包发送GET请求的示例,发送POST请求的示例代码如下:

POST表单请求数据

  1. server.go
func main() {
	http.HandleFunc("/", SayHello)
	if err := http.ListenAndServe(":8000", nil); err != nil {
		fmt.Println(err.Error())
		return
	}
}

func SayHello(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	// 1. 请求类型是application/x-www-form-urlencoded时解析form数据
	r.ParseForm()
	fmt.Println(r.PostForm)
	fmt.Println(r.PostForm.Get("name"), r.PostForm.Get("age"))
	answer := `{"status": "ok"}`
	w.Write([]byte(answer))
}

  1. client.go
func main() {
	apiUrl := "http://127.0.0.1:8000"
	data := url.Values{}  // 类型:type Values map[string][]string
	data.Set("name", "张三")
	data.Set("age", "18")
	resp, err := http.PostForm(apiUrl, data)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer resp.Body.Close()

	buf, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(string(buf))
}

POST json提交数据

  1. server.go
func main() {
	http.HandleFunc("/", SayHello)
	if err := http.ListenAndServe(":8000", nil); err != nil {
		fmt.Println(err.Error())
		return
	}
}

func SayHello(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	// 1. 请求类型是application/json时从r.Body读取数据
	buf, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(buf))
	answer := `{"status": "ok"}`
	w.Write([]byte(answer))
}
  1. client.go
func main() {
	apiUrl := "http://127.0.0.1:8000"
	contentType := "application/json"
	data := `{"name": "haha", "age": 123}`
	resp, err := http.Post(apiUrl, contentType, strings.NewReader(data))
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer resp.Body.Close()

	buf, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	fmt.Println(string(buf))
}

默认的server示例

使用Go语言中的net/http包来编写一个简单的接收HTTP请求的Server端示例,net/http包是对net包的进一步封装,专门用来处理HTTP协议的数据。具体的代码如下:

func main() {
	http.HandleFunc("/", SayHello)
	if err := http.ListenAndServe(":8000", nil); err != nil {
		fmt.Println(err.Error())
		return
	}
}

func SayHello(w http.ResponseWriter, r *http.Request) {
	defer r.Body.Close()
	// 1. 请求类型是application/json时从r.Body读取数据
	buf, err := ioutil.ReadAll(r.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(string(buf))
	fmt.Fprintln(w, `{"status": "ok"}`)
}

自定义server

要管理服务端的行为,可以创建一个自定义的Server:

type CustomHandler struct{}
var mux = make(map[string]func(http.ResponseWriter, *http.Request))
func (*CustomHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if handler, ok := mux[r.URL.String()]; ok {
		handler(w, r)
	}
}
func main() {
	s := &http.Server{
		Addr:           ":8080",
		Handler:        &CustomHandler{},
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	mux["/"] = SayHello
	s.ListenAndServe()
	log.Fatal(s.ListenAndServe())
}
func SayHello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintln(w, `{"status": "OK呀"}`)
}

标签:http,nil,err,fmt,golang,标准,Println,resp
来源: https://www.cnblogs.com/mayanan/p/15630195.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有