一个简单http服务框架,就是注册一堆路由,然后根据路由调用不同的逻辑去处理。
那么这个时候搞一个中间做预处理,是一个不错的想法。
定义一个中间件单元:
```
1 package main
2
3 import (
4 "net/http"
5 )
6
7 // AdaptorHandle middleware func type
8 type AdaptorHandle func(w http.ResponseWriter, r *http.Request) (next bool, err error)
9
10 // MiddleWareAdaptor router middlewares mapped by url
11 type MiddleWareAdaptor struct {
12 URLs map[string][]AdaptorHandle
13 }
14
15 // MakeMiddleWareAdaptor make a middleware adaptor
16 func MakeMiddleWareAdaptor() *MiddleWareAdaptor {
17 mwa := &MiddleWareAdaptor{
18 URLs: make(map[string][]AdaptorHandle),
19 }
20
21 return mwa
22 }
23
24 // Regist regist a adaptor
25 func (mw *MiddleWareAdaptor) Regist(url string, Adaptor ...AdaptorHandle) {
26 for _, adp := range Adaptor {
27 mw.URLs[url] = append(mw.URLs[url], adp)
28 // mw.URLs[url] = adp
29 }
30 }
31
32 // Exec exec middleware adaptor funcs...
33 func (mw *MiddleWareAdaptor) Exec(url string, w http.ResponseWriter, r *http.Request) (bool, error) {
34 if adps, ok := mw.URLs[url]; ok {
35 for _, adp := range adps {
36 if next, err := adp(w, r); !next || (err != nil) {
37 return next, err
38 }
39 }
40 }
41 return true, nil
42 }
```
然后将路由处理函数用中间件入口包裹起来:
```
1 func middlewareHandler(next http.Handler) http.Handler {
2 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3 // before call handler
4 start := time.Now()
5 do, _ := mwa.Exec(r.URL.Path, w, r) // exec middleware
6 // call next handler
7 if do {
8 log.Println("middleware done. next...")
9 next.ServeHTTP(w, r)
10 } else {
11 log.Println("middleware done.break...")
12 }
13 // after call handle
14 log.Printf("Comleted %s in %v", r.URL.Path, time.Since(start))
15 })
16 }
17
18 mux.Handle("/", middlewareHandler(&uPlusRouterHandler{}))
19
20 type uPlusRouterHandler struct {
21 }
22
23 func (rh *uPlusRouterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
24 ...
25 }
````
有疑问加站长微信联系(非本文作者)