运维八一 运维八一
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)

运维八一

运维,运维!
首页
运维杂记
编程浅尝
周积跬步
专栏
生活
关于
收藏
  • 分类
  • 标签
  • 归档
Source (opens new window)
  • Go

    • 前言

    • Go基础知识

    • Go基本语法

    • 实战项目:简单web服务

    • 基本数据类型

    • 内置运算符

    • 分支和循环

    • 函数 function

    • 结构体 struct

    • 方法 method

    • 实战项目:跟踪函数调用链

    • 接口 interface

    • 并发 concurrency

    • 指针

    • 实战项目:实现轻量级线程池

    • 实战项目:实现TCP服务器

    • go常用包

      • fmt包
      • time包
      • os包
      • flag包
      • net-http包
        • 5.net-http包
          • 5.1 介绍
          • 5.2 web服务
          • 5.3 请求数据
          • 5.4 示例
    • Gin框架

    • go随记

  • Python

  • Shell

  • Java

  • Vue

  • 前端

  • 编程浅尝
  • Go
  • go常用包
lyndon
2022-06-23
目录

net-http包

# 5.net-http包

# 5.1 介绍

├── ClientGet
│  └── main.go  // 发送get请求
├── ClientPost
│  └── main.go  // 发送post请求
├── Server
│  └── main.go  // web服务
1
2
3
4
5
6

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

# 5.2 web服务

Server/main.go

  • 客户端 请求信息 封装在 http.Request 对象中
  • 服务端返回的响应报文会被保存在http.Response结构体中
  • 发送给客户端响应的并不是http.Response,而是通过http.ResponseWriter接口来实现的
方法签名 描述
Header() 用户设置或获取响应头信息
Write() 用于写入数据到响应体
WriteHeader() 用于设置响应状态码,若不调用则默认状态码为200 OK
package main
import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)
type Data struct {
	Name string `json:"name"`
}
// 处理GET请求: http://127.0.0.1:8005/req/get?name=root
func dealGetRequestHandler(w http.ResponseWriter, r *http.Request) {
	// 获取请求的参数
	query := r.URL.Query()
	if len(query["name"]) > 0 {
		// 方式1:通过字典下标取值
		name := query["name"][0]
		fmt.Println("通过字典下标获取:", name)
	}
	// 方式2:使用Get方法,,如果没有值会返回空字符串
	name2 := query.Get("name")
	fmt.Println("通过get方式获取:", name2)
	type data struct {
		Name2 string
	}
	d := data{
		Name2: name2,
	}
	//w.Write([]byte(string(d))) // 返回string
	json.NewEncoder(w).Encode(d) // 返回json数据
}
// 处理POST请求: http://127.0.0.1:8005/req/post {"name": "root"}
func dealPostRequestHandler(w http.ResponseWriter, r *http.Request) {
	// 请求体数据
	bodyContent, _ := ioutil.ReadAll(r.Body)
	strData := string(bodyContent)
	var d Data
	json.Unmarshal([]byte(strData), &d) // gin.ShouldBind
	fmt.Printf("body content:[%s]\n", string(bodyContent))
	//返回响应内容
	json.NewEncoder(w).Encode(fmt.Sprintf("收到名字:%s", d.Name))
}
func main() {
	http.HandleFunc("/req/post", dealPostRequestHandler)
	http.HandleFunc("/req/get", dealGetRequestHandler)
	http.ListenAndServe(":8005", nil)
	// 在golang中,你要构建一个web服务,必然要用到http.ListenAndServe
	// 第二个参数必须要有一个handler
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

postman测试

测试发送get请求:http://127.0.0.1:8005/req/get?name=root

image-20220622233205773

测试发送post请求:http://127.0.0.1:8005/req/post

image-20220622233300404

# 5.3 请求数据

ClientGet/main.go

package main
import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)
func main() {
	requestGet()
}
func requestGet() {
	apiUrl := "http://127.0.0.1:8005/req/get"
	data := url.Values{}
	data.Set("name", "root")
	u, _ := url.ParseRequestURI(apiUrl)
	u.RawQuery = data.Encode() // URL encode
	fmt.Println("请求路由为:", u.String())
	resp, _ := http.Get(u.String())
	b, _ := ioutil.ReadAll(resp.Body)
	fmt.Println("返回数据为:", string(b))
}
/*
请求路由为: http://127.0.0.1:8005/req/get?name=root
返回数据为: ["root"]
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

ClientPost/main.go

package main
import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)
func main() {
	requestPost()
}
func requestPost() {
	url := "http://127.0.0.1:8005/req/post"
	// 表单数据 contentType := "application/x-www-form-urlencoded"
	contentType := "application/json"
	data := `{"name":"rootPort"}`
	resp, _ := http.Post(url, contentType, strings.NewReader(data))
	b, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(b))
}
/*
"收到名字:rootPort"
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 5.4 示例

Server/main.go

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
)

/*
使用net/http模块,开发一个简单的web server
	1、提供get请求
	2、提供post请求
http: 协议(和web服务器进行交互的规范,规则)
	Get: 从数据库读取数据,比如 查询订单
		- get请求参数是从url上直接读取(一般数据都比较少)
	Post: 创建新的数据,163购买票(在数据库会添加一条数据,购票记录)
		- 从http的body中获取的数据
	Put:  修改数据,更新支付宝上的用户信息(修改我的手机号)
	Delete: 删除数据库中数据
*/

/*
开发一个web服务器主要的步骤
第一步:路由
第二步:处理函数
	- 解析请求的数据(获取某一个商品,你需要把商品Id信息携带给后端)
		- 根据请求数据参数查询数据库
	- 响应数据(把从数据库读取的数据,给返回给浏览器或者请求方)
*/
func main() {
	//第一步:路由
	// http://127.0.0.1:8005 /req/get ?name=zhangsan
	http.HandleFunc("/req/get", dealGetHandler)
	/*
		"/req/get": 路由URL除去域名的哪一块(http://www.example.com /book/1/)
		dealGetHandler: 处理函数(处理服务请求)
	*/
	http.HandleFunc("/req/post", dealPostHandler) // POST

	fmt.Println("http://127.0.0.1:8005/req/get")
	// 第三步:启动服务
	http.ListenAndServe(":8005", nil)
	/*
		addr: 当前server监听的端口号和ip
		handler:处理函数
	*/
}

// 处理函数的名字用驼峰命名: xxxHandler函数名
// 第二步:处理函数(处理get请求)
/*
- 1)解析请求的数据(获取某一个商品,你需要把商品Id信息携带给后端)
	http.Request:解析url中的数据或者post请求中body的数据
- 2)响应数据(把从数据库读取的数据,给返回给浏览器或者请求方)
	http.ResponseWriter: 本质是一个interface接口,定义三个方法,进行返回数据
*/
func dealGetHandler(w http.ResponseWriter, r *http.Request) {
	//1)解析请求的数据
	query := r.URL.Query() // 返回  map[string][]string
	// 1.1 通过字典下标取get路由参数
	if len(query["name"]) > 0 {
		names := query["name"][0]
		fmt.Println("字典下标取值", names)
	}
	// 1.2 通过Get方法取值
	name2 := query.Get("name")
	fmt.Println("通过get方法取值", name2)
	fmt.Println(query)

	//2)响应数据
	//// 2.1 返回一个简单字符串
	//w.Write([]byte("hello world!"))
	// 2.2 返回一个json数据
	// 加上我们拿到了 name=zhangsan,我们到数据库取出了zhangsan用户的信息
	type Info struct {
		Name     string
		Password string
		Age      int
	}
	// 假设这是从数据库中取出
	u := Info{
		Name:     name2,
		Password: "123456",
		Age:      24,
	}
	json.NewEncoder(w).Encode(u)
}

type Info struct {
	Name     string `json:"name"`
	Password string `json:"password"`
}

// 和get请求是一模一样的写法,这是一个post请求
func dealPostHandler(w http.ResponseWriter, r *http.Request) {
	// r  *http.Request是结构的对象
	// r.URL.query()从url取请求参数
	// post请求从http的body中获取数据
	// r.Body是结构体 Request 中的字段 r.body 其实是*http.Request.body
	bodyContent, _ := ioutil.ReadAll(r.Body) // 返回的是一个byte
	//fmt.Printf("%T %v", bodyContent, bodyContent)
	// 获取string
	//strData := string(bodyContent)
	// 如何才能解析这个string字符串(str转结构体)
	var d Info
	//json.Unmarshal([]byte(strData), &d)
	json.Unmarshal(bodyContent, &d)
	fmt.Println("获取的数据name:", d.Name)
	fmt.Println(d)
	w.Write([]byte("hello world Post"))
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

ClientGet/main.go

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

/*
使用net/http模块,作为web的客户端发送get请求
应用场景:
	1) 爬虫,获取页面数据
	2) 调用其他服务中的接口
*/
func main() {
	//// 1、直接通过url拼接处url字符串
	//apiUrl := "http://127.0.0.1:8005/req/get?name=zhangsan"
	apiUrl := "http://127.0.0.1:8005/req/get"

	// 2、通过url进行解析
	// http://127.0.0.1:8005/req/get?name=zhangsan
	data := url.Values{}
	data.Set("name", "zhangsan")
	u, _ := url.ParseRequestURI(apiUrl)
	u.RawQuery = data.Encode()
	fmt.Println(u.String())

	resp, err := http.Get(u.String())
	if err != nil {
		fmt.Println(err)
	}
	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(body))
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

ClientPost/main.go

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
)

func main() {
	url := "http://127.0.0.1:8005/req/post"
	// 模拟form表单提交数据 contentType := "application/x-www-form-urlencoded"
	// 传json数据: json contentType := "application/json"
	contentType := "application/json"
	data := `{
		"name": "root",
		"password": "123456"
	}`
	resp, _ := http.Post(url, contentType, strings.NewReader(data))
	b, _ := ioutil.ReadAll(resp.Body)
	fmt.Println(string(b))
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
上次更新: 2022/06/23, 23:41:50
flag包
gin入门

← flag包 gin入门→

最近更新
01
ctr和crictl显示镜像不一致
03-13
02
alpine镜像集成常用数据库客户端
03-13
03
create-cluster
02-26
更多文章>
Theme by Vdoing | Copyright © 2015-2024 op81.com
苏ICP备18041258号-2
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式