Golang Middleware Part 1 · To Be A Better Man
如何在Golang中实现中间件-Part 1
当使用net/http
包实现服务的时候,一般使用的是如下的两中处理方式:
- http.HandleFunc
- http.Handle
http.HandleFunc
分析
当使用这种方式的时候,其接受两个参数,一个是字符串格式的匹配符(pattern),另外一个就是func(ResponWrite, *Request)
,
因此只要我们的中间件中返回该类型,那么中间件就是可以实现的
func main(){
http.HandleFunc("/", Hello)
http.ListenAndServe(":8080", nil)
}
func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Print("hello")
}
当我们运行如上的程序的时候,就会打印出hello
这个结果,说明我们的写法是没有问题的
实现
接下来,我们需要定义我们的中间件,它需要接收一个` http.HandlerFunc`类型,并且返回一个http.HandlerFunc
这样才能被使用
func MyMiddleware(next http.HandlerFunc)http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
fmt.Println("middleware")
//doSomethinds
next.ServeHTTP(w,r)
}
}
由于调用next.ServeHTTP(w, r)
等效于调用next(w, r)
,处理完后会返回响应w
,最终相应会传递到最外层的匿名函数,从而最终会返回到客户端
http.Handle
分析
http.Handle
接受两个参数,一个是匹配符,另外一个是http.Handler
,当我们查看源码的时候,发现其是一个接口类型
type Handler interface {
ServeHTTP(ResponseWriter, *Request)
}
因此我们最终得返回一个实现了该接口的类型,假设我们首先定义一个新的结构体,并为其添加一个`ServiceHTTP`
解决
type MyResponse struct {
next http.Handle
Code int64
Msg string
Errors []string
Data map[string]interface{}
}
func (res *MyResponse)ServeHTTP(w http.ResponseWriter, r *http.Request) {
result, err := json.Marshal(res)
if err 大专栏 Golang Middleware Part 1 · To Be A Better Mancolor:#f92672">!= nil {
fmt.Println(err.Error())
}
w.Write(result)
}
紧接着我们定义两个处理函数
func Hello(w http.ResponseWriter, r *http.Request) {
fmt.Println("hello")
}
func World(w http.ResponseWriter, r *http.Request) {
fmt.Println("world")
}
然后在主函数里面进行调用
var res = new(MyResponse)
res.next = Hello
http.Handle("/hello", res)
res.next = World
http.Handle("/world", res)
http.ListenAndServe(":8080", nil)
然后你会发现诡异的事情发生了,无论你访问哪一个路由地址,最终打印的都只是world
,这是因为Golang是一门静态的预编译语言,编译完成后,`res`总的next属性
将会永远指向World
的地址,
因此我们可以做一个映射,将next变成map类型,但是想一想,如果路由非常多的话,那将是一件多可怕的事情,因此我们需要另辟蹊径,有没有其他的办法可以实现,查看源码我们可以发现
之前我们所使用过的http.HandleFunc
与之相对应的还有一个类型http.HandlerFunc
,该类型实现了ServerHTTP
方式
type HandlerFunc func(ResponseWriter, *Request)
// ServeHTTP calls f(w, r).
func (f HandlerFunc) ServeHTTP(w ResponseWriter, r *Request) {
f(w, r)
}
接下来我们利用Goalng中的强制类型转换,就可以写出如下的中间件
func MySencondMiddleware(next http.HandlerFunc) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//do somethings
next.ServeHTTP(w, r)
})
}
Please enable JavaScript to view the comments powered by Disqus.
Golang Middleware Part 1 · To Be A Better Man的更多相关文章
- golang程序设计:Go middleware中间件以及Gin 中间件分析
先从业务开发角度出发,来逐渐引出中间件. 一.刚开始时业务开发 开始业务开发时,业务需求比较少. 当我们最开始进行业务开发时,需求不是很多. 第一个需求产是品向大家打声招呼:"hello w ...
- golang实现路由中间件middleware
registerHandlers.go package router import ( "../ctrl" "../funcs" "github.co ...
- golang 依赖控制反转(IoC)
主流开发语言,为了达到项目间的低耦合,都会借助IoC框架来实现.即抽象和实现分离,使用抽象层,不用关心这些抽象层的具体实现:抽象层的实现,可以独立实现.现在比较流行的领域驱动设计(ddd),为了达到将 ...
- golang中Context的使用场景
golang中Context的使用场景 context在Go1.7之后就进入标准库中了.它主要的用处如果用一句话来说,是在于控制goroutine的生命周期.当一个计算任务被goroutine承接了之 ...
- Golang 微框架 Gin 简介
框架一直是敏捷开发中的利器,能让开发者很快的上手并做出应用,甚至有的时候,脱离了框架,一些开发者都不会写程序了.成长总不会一蹴而就,从写出程序获取成就感,再到精通框架,快速构造应用,当这些方面都得心应 ...
- Golang处理数据库的nil数据
在用golang获取数据库的数据的时候,难免会遇到可控field.这个时候拿到的数据如果直接用string, time.Time这样的类型来解析的话会遇到panic. 那么如何处理这个问题呢,第一个出 ...
- Go实战--golang中使用JWT(JSON Web Token)
http://blog.csdn.net/wangshubo1989/article/details/74529333 之前写过关于golang中如何使用cookie的博客: 实战–go中使用cook ...
- golang 请求带验证信息的坑
最近用golang 和python对接接口,由于之前验证那块没有设置好,然后又为了进度,最近决定用http自带的basic 验证, php的代码很快就验证通过了 /** * @param $url * ...
- Learn golang: Top 30 Go Tutorials for Programmers Of All Levels
https://stackify.com/learn-go-tutorials/ What is Go Programming Language? Go, developed by Google in ...
随机推荐
- 史上最难PHPer笔试题,40分就能月薪过万!附答案
请批判性的学习,欢迎大牛指正错误 1.有关PHP字符串的说法,不对的是:A.如果一个脚本的编码是 ISO-8859-1,则其中的字符串也会被编码为 ISO-8859-1.B.PHP的字符串在内部是字节 ...
- [LC] 51. N-Queens
Given an integer n, return all distinct solutions to the n-queens puzzle. Each solution contains a d ...
- 在CentOS7上从源码编译安装redis,并做成服务程序
1.安装编译的依赖环境 # 安装pcre开发包: yum install -y pcre-devel # 安装ssl功能需要openssl库 yum -y install openssl-devel ...
- 关于Linux常用命令的使用
Linux常用命令 Linux centos常用镜像下载链接:http://mirror.centos.org/centos 一.关于yum 1.下载rpm包并存放至某个路径 命令:#yum inst ...
- Python学习中的随笔,好记性不如烂笔头
本文 为博主看了 vamei 的blog 写下的随笔 . 致敬Vamei 1.type() 可以显示参数的类型 如 : a=12 type(a) 为 int 2.python的基本类型 为 i ...
- 解决 nginx 启动错误 nginx: [emerg] host not found in upstream
解决办法来自于:https://blog.csdn.net/Hreticent/article/details/86074502 感谢这个朋友简单而清晰的解决办法. 在配置nginx支持PHP的时候, ...
- 计量经济与时间序列_ACF自相关与PACF偏自相关算法解析(Python,TB(交易开拓者))
1 在时间序列中ACF图和PACF图是非常重要的两个概念,如果运用时间序列做建模.交易或者预测的话.这两个概念是必须的. 2 ACF和PACF分别为:自相关函数(系数)和偏自相关函数(系数). ...
- 磁力搜索导航,MagnetW将搜索结果格式化统一显示
简介 magnetW基于magnetX的规则原理,将各个磁力站的搜索结果统一格式化 安装 从Github Releases或者Github Wiki下载对应平台 3.1.1 更新了一批规则 支持Soc ...
- windows Apache 配置支持HTTPS的SSL证书
在设置Apache + SSL之前, 需要做: 安装Apache, 下载安装Apache时请下载带有ssl版本的Apache安装程序. 并且ssl需要的文件在如下的位置: [Apache安装目录]/m ...
- LeetCode No.151,152,153
No.151 ReverseWords 翻转字符串里的单词 题目 给定一个字符串,逐个翻转字符串中的每个单词. 示例 输入: "the sky is blue" 输出: " ...