Go语言经典库使用分析,未完待续,欢迎扫码关注公众号flysnow_org或者网站http://www.flysnow.org/,第一时间看后续系列。觉得有帮助的话,顺手分享到朋友圈吧,感谢支持。

上一篇介绍的Gorilla Handlers中间件,严格来说不能称之为一个库或者框架,他只是一系列包装http.Handler的中间件函数,并且他们之间没有任何关系,也没有定义一种规则如何让我们基于它来开发我们自己的中间件,总之它是孤立的,中间件之间没有关系的。

我们这篇文章介绍的Negroni中间件库,是一个非常经典的库,非常小,但是功能强大,因为他定义了中间件的框架和风格,让我们可以基于它开发出我们自己的中间件,并且可以集成到Negroni中。

Negroni还兼容原生的http.Handler,你完全可以把自己的http.Handler加入到Negroni的中间件链中,Negroni会自动调用他们处理我们的HTTP Request的。

入门介绍

Negroni托管在Github上,你完全可以通过以下方式获得它,然后在你的项目中使用。

go get -u github.com/urfave/negroni

然后我们看个例子,还是基于Gorilla Handler的例子吧,便于理解。

//Blog:www.flysnow.org
//Wechat:flysnow_org
func main() {n := negroni.Classic()n.UseHandler(handler())n.Run(":1234")
}
func handler() http.Handler{return http.HandlerFunc(myHandler)
}
func myHandler(rw http.ResponseWriter, r *http.Request) {rw.Header().Set("Content-Type", "text/plain")io.WriteString(rw,"Hello World")
}

negroni.Classic()返回一个Negroni实例,然后通过这个实例,我们就可以添加一些中间件了。因为Negroni完全兼容http.Handler,所以我们自己对于HTTP Request的真实业务处理也可以作为Negroni的一个中间件。

通过Negroni的Run方法,就可以启动一个服务了,这个Run方法和http.ListenAndServe是等价的,只不过做了一些处理,比如会从环境变量PORT里获取服务监听的端口。

运行,然后访问http://localhost:1234,会看到如下输出:

[negroni] 2017-08-20T18:09:47+08:00 | 200 |  591.81µs | localhost:1234 | GET /
[negroni] 2017-08-20T18:09:47+08:00 | 200 |  29.677µs | localhost:1234 | GET /favicon.ico

这个为什么呢?哦,原来是我们的negroni.Classic()初始化Negroni实例的方式,这种方式会默认添加3个中间件。

func Classic() *Negroni {return New(NewRecovery(), NewLogger(), NewStatic(http.Dir("public")))
}

一个是Panic Recovery,一个是Log,一个是静态文件服务器。如果你不想使用他们,或者你有自己定义好的可以替代他们的中间件,可以使用New方法。

func New(handlers ...Handler) *Negroni { return &Negroni{handlers:   handlers,middleware: build(handlers),}
}

参数是一个可变的中间件处理参数,是否传入一些处理中间件,由你来决定。

Negroni配合路由

Negroni是一个让你更容易的使用中间件的微型库,至于具体的业务处理Handler,需要我们自己来写,不过Negroni强大之处在于,我们可以把我们自己的业务处理Hanlder当做Negroni的中间件,当然路由也不例外,go http mux路由本身就是一种Handler。

//Blog:www.flysnow.org
//Wechat:flysnow_org
func main() {n := negroni.Classic()mux := http.NewServeMux()mux.Handle("/",handler())mux.HandleFunc("/flysnow", func(rw http.ResponseWriter, r *http.Request) {io.WriteString(rw,"Blog:www.flysnow.org\n")io.WriteString(rw,"Wechat:flysnow_org")})n.UseHandler(mux)n.Run(":1234")
}
func handler() http.Handler{return http.HandlerFunc(myHandler)
}
func myHandler(rw http.ResponseWriter, r *http.Request) {rw.Header().Set("Content-Type", "text/plain")io.WriteString(rw,"Hello World")
}

对比前面的示例,稍稍改动了下,通过一个路由处理不同的URL,然后把这个路由作为Negroni中间件的一部分。一般来说,路由器作为Negroni的最后一个路由被添加。

当然路由框架有很多个,如果你不是使用的默认的,你也可以选择其他的,比如Gorilla Mux,那么我们示例可以这么改写。

//Blog:www.flysnow.org
//Wechat:flysnow_org
func main() {n := negroni.Classic()router:=mux.NewRouter()router.Handle("/",handler())router.HandleFunc("/flysnow", func(rw http.ResponseWriter, r *http.Request) {io.WriteString(rw,"Blog:www.flysnow.org\n")io.WriteString(rw,"Wechat:flysnow_org")})n.UseHandler(router)n.Run(":1234")
}

从这里可以又可以看到Negroni的灵活性,完全兼容net/http,无缝融合,所以我们也鼓励使用原生的net/http处理库。

动态新增中间件

在创建了一个Negroni实例后,我们可以为它添加中间件,这些被添加的中间件组成一个中间件链,先添加的会被先执行。

中间件的添加,得益于几个Negroni的Use函数,这些函数的功能是一样的,抽象出来的几个Use函数便于我们添加不同类型的中间件。

//Blog:www.flysnow.org
//Wechat:flysnow_org
Use(handler Handler)
UseFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc))
UseHandler(handler http.Handler)
UseHandlerFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request))

除了第1个Use函数,其他三个函数最终都会调用Use函数,把中间件添加到中间件的处理链中。

func (n *Negroni) Use(handler Handler) {if handler == nil {panic("handler cannot be nil")}n.handlers = append(n.handlers, handler)n.middleware = build(n.handlers)
}

从上面的Use函数的实现可以看出,Negroni有两个字段,其中handler是一个切片,用于存储所有的Handler;一个是middleware,用于存储基于Handher构建而成的中间件链。

每次调用Use函数添加中间件,都会重新构建赋值给这两个字段,这样就完成了中间件的添加。

小结

这一篇主要介绍下Negroni的使用,以及路由的配置和中间件的添加,对Negroni有一些大概的了解,下一篇会继续介绍Negroni的处理器Handler,Handler和HandlerFunc之间的转换,如何构建中间件链等。

相关文章推荐

Go语言经典库使用分析(四)| Gorilla Handlers 源代码实现分析

Go语言经典库使用分析(三)| Gorilla Handlers 详细介绍

Go语言经典库使用分析(二)| Gorilla Context

Go语言经典库使用分析(一)| 开篇

Go语言经典库使用分析,未完待续,欢迎扫码关注公众号flysnow_org或者网站http://www.flysnow.org/,第一时间看后续系列。觉得有帮助的话,顺手分享到朋友圈吧,感谢支持。

Go语言经典库使用分析(五)| Negroni 中间件(一)相关推荐

  1. java体系的中间件适用于go吗,Go语言经典库使用分析(五)| Negroni 中间件(一)...

    Go语言经典库使用分析,未完待续,欢迎扫码关注公众号flysnow_org或者网站http://www.flysnow.org/,第一时间看后续系列.觉得有帮助的话,顺手分享到朋友圈吧,感谢支持. 上 ...

  2. Go语言经典库使用分析(六)| Negroni 中间件(二)

    Go语言经典库使用分析,未完待续,欢迎扫码关注公众号flysnow_org或者网站http://www.flysnow.org/,第一时间看后续系列.觉得有帮助的话,顺手分享到朋友圈吧,感谢支持. 上 ...

  3. Go语言经典库使用分析(二)| Gorilla Context

    Go语言经典库使用分析,未完待续,欢迎扫码关注公众号flysnow_org或者网站http://www.flysnow.org/,第一时间看后续系列.觉得有帮助的话,顺手分享到朋友圈吧,感谢支持. 在 ...

  4. C语言经典例题--打印前五十个素数

    利用while循环 #include <stdio.h>int main() {int x;x = 2;int cnt = 0;while(cnt<50){int i;int isP ...

  5. c开发 易语言支持库,易写易库-用易语言开发易语言支持库.pdf

    易写易库-用易语言开发易语言支持库 易写易库(EXEK)用户手册 版本:0.2 作者:liigo,/liigo 时间:2008.10 概述 EXEK EXEK "易写易库(EEXXEEKK) ...

  6. c语言超长编程程序,全国青少年软件编程等级考试C语言经典程序题10道五

    全国青少年软件编程等级考试C语言经典程序题10道五 [程序41] 题目:学习static定义静态变量的用法 1.程序分析: 2.程序源代码: #include "stdio.h" ...

  7. 经典C语言程序100例之六五

    经典C语言程序100例之六五 如题 话不多说了,直接上代码 如题 [程序65] 题目:一个最优美的图案. 1.程序分析: 话不多说了,直接上代码 2.程序源代码: #include "gra ...

  8. acm水仙花数java,水仙花数之C语言经典案例分析

    水仙花数之C语言经典案例分析 一.[什么是水仙花数] 水仙花数(Narcissistic number)也被称为超完全数字不变数(pluperfect digital invariant, PPDI) ...

  9. 猴子吃桃c语言程序到第n天,猴子吃桃问题之《C语言经典案例分析》

    猴子吃桃问题之<C语言经典案例分析> 一.[什么是猴子吃桃] 猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个.第二天早上又将第一天剩下的桃子吃掉一半,有多吃了 ...

最新文章

  1. 关于Talend的Patch分支对应Eclipse开发环境的配置总结.
  2. 判断一个jquery对象是否为空jquery对象
  3. optee中utee syscall的实现(系统调用实现)
  4. idea 项目编译不成功-循环依赖的问题
  5. JMeter入门(03)多台JMeter联合测试
  6. 数据预处理代码分享——机器学习与数据挖掘 1
  7. win7右键点击文件夹进入命令窗口方法
  8. 数据结构 - 栈(数组模拟栈操作)
  9. python-朴素贝叶斯分类器
  10. 2017.5.9 积木大赛 思考记录
  11. androidpn的学习研究(八)androidpn 中业务类XmppIoHandler实现分析
  12. 笔记︱精准营销解决方案以及营销组合评估
  13. 前端实习4个月的心得(uniapp)
  14. Linux开发板无法连接ssh
  15. 国土防线2计算机内存不足,国土防线2革命配置要求高吗?PC配置要求介绍
  16. 如何下载B站视频,解决视频没有声音/音画分离问题(IDM+Potplayer)
  17. 【串口服务器rs485通信教程】存储型网关工作模式
  18. 利用Python暴力破解邻居家WiFi密码
  19. 能ping通IP地址,ping不通主机名问题解决
  20. 永久实现jupyter notebook多行输出

热门文章

  1. 实战玩客云刷armbian及共享打印机教程
  2. ppt关闭受保护视图
  3. ElasticSearch搜索引擎(高级)
  4. Baxter实战——执行双臂机器人通过rviz打开嵌入式视觉
  5. Macbook 开机后黑屏,电池满电却瞬间没电问题
  6. 服务器性能测试工具及实战,性能测试实战--《软件测试52讲》
  7. 运算符的优先级(从高到低)
  8. Human-like learning在对话机器人中的魔性运用
  9. 精简《JavaScript高级程序设计》五、引用类型(上)
  10. BZOJ - 3687