一.简介
negroni是一个web中间件,方便使用net/http的库;它实现了http.Handle接口,兼容http.Handle.
获取方式:go get github.com/urfave/negroni
negroni的主要的结构:
type Negroni struct {
middleware middleware //节点结构
handlers []Handler //对应的中间件的执行链
}
type middleware struct {
handler Handler
next *middleware
}
type Handler interface {
ServeHTTP(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc)
}
type HandlerFunc func(ResponseWriter, *Request)
二.使用
1)简单的demo(向浏览器输出):
func main() {
n := negroni.Classic()
n.UseHandler(http.HandlerFunc(myHandler))
n.Run()
}
func myHandler(rw http.ResponseWriter, r *http.Request) {
io.WriteString(rw, "Hello World")
}
Classic()返回一个Negroni实例(会添加异常恢复,日志和静态文件服务器三个中间件)
UseHandler()将Handle添加到Negroni的实例中的执行链的最后面(可以参考UseHandler()里面调用的build())
func build(handlers []Handler) middleware {
var next middleware
if len(handlers) == 0 {
return voidMiddleware()
} else if len(handlers) > 1 {
next = build(handlers[1:])
} else {
next = voidMiddleware()
}
return middleware{handlers[0], &next}
}
Run()和ListenAndServe()一样.当然也可以自己使用Negroni的New()定义自己的Negroni实例
2)中间件的添加:
func (n *Negroni) Use(handler Handler)
func (n *Negroni) UseFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc))
func (n *Negroni) UseHandler(handler http.Handler)
func (n *Negroni) UseHandlerFunc(handlerFunc func(rw http.ResponseWriter, r *http.Request))
这四个函数可以将中间件动态添加到执行链中,后三个函数最终都会调用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)
}
Negroni自定义了Handler,与http.Handler唯一不同是多了next参数,各个中间件自己判断是否使用next()执行下一个中间件
测试demo(模拟登陆鉴权):
func main() {
//流程:注册myHandlerOne模拟鉴权,根据path判断是否执行myHandleTwo
n := negroni.Classic()
n.UseFunc(myHandlerOne)
mux := http.NewServeMux()
mux.Handle("/index", http.HandlerFunc(myHandlerTwo))
n.UseHandler(mux)
n.Run()
}
func myHandlerOne(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
io.WriteString(rw, "login in\n")
fmt.Println(r.URL.Path)
if r.URL.Path == `/index` {
next(rw, r)
}
}
func myHandlerTwo(rw http.ResponseWriter, r *http.Request) {
io.WriteString(rw, "Hello World")
}
使用Negroni这种方式可以控制中间件的执行,可以中断