在前面的分享
golang 网络编程(5)中间件
我们通过学习自己动手写了两个拦截器,输出日志和简单权限校验。这也是我们中间件通常要做的事。其实很多时候我们不需要自己做过多事,想喝咖啡我们还有必要去种、烘焙、研磨吗?直接麦当劳了。
不过我们简单了解一下中间件实现原理还是很有必要的。先拿日志系统举例吧。通常我们的日志需要以文件形式保存下来,而不是在控制台输出。
我们会用到 "github.com/gorilla/handlers"
这个第三方包。
func index(w http.ResponseWriter, r *http.Request){
log.Println("Execute index handler")
fmt.Fprintf(w,"welcome")
}
func about(w http.ResponseWriter, r *http.Request){
log.Println("Execute about handler")
fmt.Fprintf(w,"about")
}
我们先定义两个路由器,分别在浏览器输出文本。
logFile, err := os.OpenFile("server.log",os.O_WRONLY|os.O_CREATE|os.O_APPEND,0666)
// logFile, err := os.OpenFile("server.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
这里通过 go 语言提供 os 包来创建一个用于保存日志的文件server.log
http.Handle("/", handlers.LoggingHandler(logFile, handlers.CompressHandler(indexHandler)))
http.Handle("/about", handlers.LoggingHandler(logFile, handlers.CompressHandler( aboutHandler)))
这里使用了handlers
提供的LoggingHandler
和CompressHandler
来将日志进行压缩后输入到文件 logFile 中,这里压缩是使用 gzip 或 Deflate 对请求返回进行压缩。
完整代码如下
package main
import(
"fmt"
"log"
"net/http"
"os"
"github.com/gorilla/handlers"
)
func index(w http.ResponseWriter, r *http.Request){
log.Println("Execute index handler")
fmt.Fprintf(w,"welcome")
}
func about(w http.ResponseWriter, r *http.Request){
log.Println("Execute about handler")
fmt.Fprintf(w,"about")
}
func iconHandler(w http.ResponseWriter, r *http.Request) {
}
func main(){
http.HandleFunc("/favicon.icon",iconHandler)
indexHandler := http.HandlerFunc(index)
aboutHandler := http.HandlerFunc(about)
logFile, err := os.OpenFile("server.log",os.O_WRONLY|os.O_CREATE|os.O_APPEND,0666)
// logFile, err := os.OpenFile("server.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil{
panic(err)
}
http.Handle("/", handlers.LoggingHandler(logFile, handlers.CompressHandler(indexHandler)))
http.Handle("/about", handlers.LoggingHandler(logFile, handlers.CompressHandler( aboutHandler)))
server := &http.Server{
Addr: ":8080",
}
log.Println("Listening...")
server.ListenAndServe()
}
::1 - - [24/Apr/2019:05:39:31 +0800] "GET / HTTP/1.1" 200 31
::1 - - [24/Apr/2019:05:39:31 +0800] "GET /favicon.ico HTTP/1.1" 200 31
::1 - - [24/Apr/2019:05:39:38 +0800] "GET /about HTTP/1.1" 200 31
::1 - - [24/Apr/2019:05:39:38 +0800] "GET /favicon.ico HTTP/1.1" 200 31
这一次我们又引入了github.com/justinas/alice
这个第三方包,使用 alice 原因是让我们代码看起来更优雅。
commonHandlers := alice.New(loggingHandler, handlers.CompressHandler)
对我们日志进行整合封装。
package main
import(
"io"
"log"
"net/http"
"os"
"github.com/justinas/alice"
"github.com/gorilla/handlers"
)
func loggingHandler(next http.Handler) http.Handler{
logFile, err := os.OpenFile("server.log",os.O_WRONLY|os.O_CREATE|os.O_APPEND,0666)
if err != nil{
panic(err)
}
return handlers.LoggingHandler(logFile,next)
}
func index(w http.ResponseWriter, r *http.Request){
w.Header().Set(
"Content-Type",
"text/html",
)
io.WriteString(
w,
`<doctype html>
<html>
<head>
<title>Index</title>
</head>
<body>
Hello Zidea!
</body>
</html>`, )
}
func about(w http.ResponseWriter, r *http.Request){
w.Header().Set(
"Content-Type",
"text/html",
)
io.WriteString(
w,
`<doctype html>
<html>
<head>
<title>About</title>
</head>
<body>
about HTTP Middleware
</body>
</html>`, )
}
func iconHandler(w http.ResponseWriter, r *http.Request) {
// http.ServeFile(w, r, "./favicon.ico")
}
func main(){
http.HandleFunc("/favicon.ico", iconHandler)
indexHandler := http.HandlerFunc(index)
aboutHandler := http.HandlerFunc(about)
commonHandlers := alice.New(loggingHandler, handlers.CompressHandler)
http.Handle("/", commonHandlers.ThenFunc(indexHandler))
http.Handle("/about", commonHandlers.ThenFunc(aboutHandler))
server := &http.Server{
Addr: ":8080",
}
log.Println("Listening...")
server.ListenAndServe()
}
::1 - - [24/Apr/2019:05:53:01 +0800] "GET /about HTTP/1.1" 200 110
::1 - - [24/Apr/2019:05:53:05 +0800] "GET /welcome HTTP/1.1" 200 103
th-9.jpeg
网友评论