本章目录:
0x01 Go语言基础之HTTP C/S实现
- 1.HTTP 服务端
- 2.HTTP 客户端
- 3.综合实践
- 3.1 Get 请求示例
- 3.2 Post 请求示例
- 3.3 PostForm 请求示例
- 3.4 Http 服务响应示例
0x01Go语言基础之HTTP C/S实现
描述: 在Socket网络编程中我们学习TCP协议与UDP协议的服务端与客户端代码的编写实践, 今天我们来学习在应用层中我们使用最多的HTTP协议,利用Go语言分别实现HTTP的Client端与Server端服务。
Go语言内置的net/http
包十分的优秀,其为我们提供了HTTP客户端和服务端的实现。
Q: 什么是 HTTP 协议?
答: 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准,设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
例如,我们在浏览器中访问的http的网站,其传输协议便是采用HTTP。
1.HTTP 服务端
描述: 利用Go语言提供的net/http包我们可以非常便利的使用并创建一个服务端, 值得说明的是如果仅仅是实现简单的API接口可以采用原生的http包中提供的方法, 而如果是编写一些Web后端项目通常是采用框架来实现,所以本章节主要对Go语言创建HTTP服务端的基础示例进行说明学习,而Go语言的Web应用开发框框在我后续笔记中将会进行实践讲解。
HTTP服务端实现常用方法原型:
-
func http.ListenAndServe(addr string, handler http.Handler) error
: 使用指定的监听地址和处理器启动一个HTTP服务端, 处理器参数通常是nil表示采用包变量DefaultServeMux作为处理器。 -
func http.Handle(pattern string, handler http.Handler){ DefaultServeMux.Handle(pattern, handler) }
: Handle在DefaultServeMux中注册给定模式的处理程序函数。 -
func http.HandleFunc(pattern string, handler func(http.ResponseWriter, *http.Request)){DefaultServeMux.HandleFunc(pattern, handler)}
: HandleFunc在DefaultServeMux中注册给定模式的处理程序函数。
Tips: go http http.Handle 和 http.HandleFunc 区别?
-
http.Handle()
需要自己去定义struct实现这个Handler接口。 -
http.HandleFunc()
则不需要我们自己定义structqi实现,只需要传入访问连接路径以及DefaultServeMux中注册给定模式的处理程序函数。
通常是使用HandleFunc方法,其更加方便简单。
示例1.http.Handle自定义实现Handler接口
执行结果如下图所示
示例2.http.HandleFunc实现用户请求处理
index.html
Http Server 端代码:
将上面的代码编译之后执行,打开电脑上的浏览器在地址栏输入127.0.0.1:8080
回车,此时返回如下页面。
示例3.自定义http.Server结构体参数与Handler实现
描述: 我们可以创建一个自定义的 Server
Handler实现, 通过http.Server指定设置结构体参数来管理服务端的行为。
执行结果:
Tips: 显然我们可以继续向ServeHTTP方法中添加case,但在一个实际的应用中,将每个case中的逻辑定义到一个分开的方法或函数中会很实用。对于更复杂的应用我们可以通过一个ServeMux将一批http.Handler聚集到一个单一的http.Handler中,通过组合来处理更加错综复杂的路由需求。
Tips: 【非常注意】【非常注意】【非常注意】自己实现的 http.Handler 且必须包含一个 ServeHTTP 方法名, 才能接受和响应客户端。
示例4.ServeMux.HandleFunc实现http服务端
语句http.HandlerFunc(handler.list)是一个转换而非一个函数调用,因为http.HandlerFunc是一个类型, 它有如下的定义:
简单示例:
Tips: 为了方便net/http包提供了一个全局的ServeMux实例DefaultServerMux和包级别的http.Handle和http.HandleFunc函数, 前面说过我们只需要传入nil值即可。
2.HTTP 客户端
描述: 如果你学过Python爬虫那么你也肯定知道,我们可以采用编程语言提供的相应函数或者方法就要可以对指定的网站进行请求,并可以将请求响应的数据进行清洗然后存储进数据中。
Go语言也为我们提供相应的内置包net/http
和net/url
以便于我们进行网站API接口(GET
、POST
、PUT
)请求和处理服务端响应的数据。
HTTP客户端请求函数原型:
-
func http.Get(url string) (resp *http.Response, err error)
: 向指定的URL发出Get请求,它将随重定向,最多10个重定向。 -
func http.Post(url string, contentType string, body io.Reader) (resp *http.Response, err -error)
: 指定的URL发出Post请求,调用方在完成读取后应关闭相应的主体。 -
func http.PostForm(url string, data url.Values) (resp *http.Response, err error)
: PostForm向指定的URL发出POST,并将数据的键和值URL编码为请求正文,Content-Type header
设置为application/x-www-form-urlencoded
。 -
func http.NewRequest(method string, url string, body io.Reader) (*http.Request, error)
: NewRequest使用后台上下文包装NewRequestWithContext. -
func (*http.Client).Do(req *http.Request) (*http.Response, error)
: 按照客户端上配置的策略(如重定向、cookie、身份验证),发送到HTTP请求并返回到HTTP响应。 -
func url.Parse(rawurl string) (*url.URL, error)
: Parse将rawurl解析为URL结构。 -
func (url.Values).Encode() string
: Encode将值编码为按键排序的“URL编码”形式(“bar=baz&foo=qux”)。
Tips : GET请求的参数需要使用Go语言内置的net/url
标准库来处理。
简单示例.
执行结果:
自定义 Client&Transport
描述: 要管理HTTP客户端的头域、重定向策略和其他设置,创建一个Client:
描述: 要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:
Tips: Client
和Transport
类型都可以安全的被多个goroutine同时使用, 出于效率考虑,应该一次建立、尽量重用。
Tips: 如果取数据比较频繁的场景建议使用长连接,否则使用短连接即可。
3.综合实践
3.1 Get 请求示例
get_client.go
执行结果:
3.2 Post 请求示例
post_client.go
执行结果:
3.3 PostForm 请求示例
postForm_client.go
执行结果:
3.4 Http 服务响应示例
描述: 下述http_serve.go代码包含上面三种请求示例的响应,以及请求参数获取以及输出。
http_serve.go
执行结果: