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:

// 定义字段保存路由与视图函数之间的映射关系
var routerMapFunc = make(map[string]func(http.ResponseWriter, *http.Request)) type CustomerHandler struct {}
func (*CustomerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if viewFunc, ok := routerMapFunc[r.URL.String()]; ok {
viewFunc(w, r)
} else {
w.WriteHeader(http.StatusNotFound)
w.Write([]byte("404 not found"))
}
} func main() {
s := &http.Server{
Addr: ":8000",
Handler: &CustomerHandler{},
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
MaxHeaderBytes: 2 << 20, // 1048576个字节,也就是1M
} // 注册路由
routerMapFunc["/index"] = IndexView if err := s.ListenAndServe(); err != nil {
fmt.Println(err.Error())
return
}
}
func IndexView(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, `{"status": "OK", "msg": "哈哈哈"}`)
}

golang中的标准库http的更多相关文章

  1. golang中的标准库数据格式

    数据格式介绍 是系统中数据交互不可缺少的内容 这里主要介绍JSON.XML.MSGPack JSON json是完全独立于语言的文本格式,是k-v的形式 name:zs 应用场景:前后端交互,系统间数 ...

  2. golang中的标准库context

    在 Go http包的Server中,每一个请求在都有一个对应的 goroutine 去处理.请求处理函数通常会启动额外的 goroutine 用来访问后端服务,比如数据库和RPC服务.用来处理一个请 ...

  3. golang中的标准库log

    Go语言内置的log包实现了简单的日志服务.本文介绍了标准库log的基本使用. 使用Logger log包定义了Logger类型,该类型提供了一些格式化输出的方法.本包也提供了一个预定义的" ...

  4. golang中的标准库context解读

    简介 golang 中的创建一个新的 goroutine , 并不会返回像c语言类似的pid,所有我们不能从外部杀死某个goroutine,所有我就得让它自己结束,之前我们用 channel + se ...

  5. golang中的标准库template

    html/template包实现了数据驱动的模板,用于生成可对抗代码注入的安全HTML输出.它提供了和text/template包相同的接口,Go语言中输出HTML的场景都应使用text/templa ...

  6. golang中的标准库IO操作

    参考链接 输入输出的底层原理 终端其实是一个文件,相关实例如下: os.Stdin:标准输入的文件实例,类型为*File os.Stdout:标准输出的文件实例,类型为*File os.Stderr: ...

  7. golang中的标准库time

    时间类型 time.Time类型表示时间.我们可以通过time.Now()函数获取当前的时间对象,然后获取时间对象的年月日时分秒等信息.示例代码如下: func main() { current := ...

  8. golang中的标准库反射

    反射 反射是指程序在运行期对程序本身访问和修改的能力 变量的内在机制 变量包含类型信息和值信息 var arr [10]int arr[0] = 10 类型信息:是静态的元信息,是预先定义好的 值信息 ...

  9. golang中的标准库strconv

    strconv 包 strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数: Atoi().Itia().parse系列.format系列.append系列. string与int ...

随机推荐

  1. IDEA版本2020.1全局MAVEN配置

    我们用IDEA打开项目有时候要每次配置maven地址,这样就很麻烦 我们可以直接设置全局的 这样所有新打开的项目都能使用

  2. 移动端点击a标签拨打电话、发送短信

    拨打电话 <a href="tel:88888888">888888</a> 发送短信 <a href="sms:电话号码"> ...

  3. 【LeetCode】1579. 保证图可完全遍历 Remove Max Number of Edges to Keep Graph Fully Traversable

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题思路 并查集 代码 欢迎加入组织 日期 题目地址:https ...

  4. 【LeetCode】212. Word Search II 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 前缀树 日期 题目地址:https://leetco ...

  5. hdu-1421搬寝室(dp)

    http://acm.hdu.edu.cn/showproblem.php?pid=1421; 思路:先将所给的椅子的价值按升序排列,举个例子,四张椅子的价值分别为a,b,c,d(a<b< ...

  6. APP打开(四)—Deeplink推广,打开率很低怎么排查

    在开始正文之前,先解释一下,这里提到的打开率指的是点击了Deeplink之后正常打开了APP和点击量的比值. 开始正文: 但凡做TOC业务的多多少少都会用到Deeplink,这是一个重要的运营手段.但 ...

  7. 第二十九个知识点:什么是UF-CMA数字签名的定义?

    第二十九个知识点:什么是UF-CMA数字签名的定义? 第16篇博客给出了DSA,Schnoor和RSA-FDH签名方案的细节,但是签名方案是什么?它应该保证什么样的安全性? 一个签名方案\(S\)是一 ...

  8. 「算法笔记」Polya 定理

    一.前置概念 接下来的这些定义摘自 置换群 - OI Wiki. 1. 群 若集合 \(s\neq \varnothing\) 和 \(S\) 上的运算 \(\cdot\) 构成的代数结构 \((S, ...

  9. vue是如何通过diff算法做渲染更新

    渲染页面 图中框起来的部分,vue会根据响应式变化的通知生成一颗新的 Virtual Dom Tree,然后将新的Virtual Dom Tree 和之前的 Virtual Dom Tree 做 di ...

  10. .NET6: 三分钟搭建WPF三维应用

    要运行本文中的示例,请先安装Vistual Studio 2022,社区版就可以了. 1 创建项目 选择创建WPF应用 给程序起一个酷酷的名字,选一个酷酷的位置: 选一下.NET6 2 配置项目 从n ...