在前面的分享
golang 網(wǎng)絡(luò)編程(5)中間件
我們通過學(xué)習(xí)自己動手寫了兩個(gè)攔截器愧膀,輸出日志和簡單權(quán)限校驗(yàn)。這也是我們中間件通常要做的事谣光。其實(shí)很多時(shí)候我們不需要自己做過多事檩淋,想喝咖啡我們還有必要去種、烘焙、研磨嗎蟀悦?直接麥當(dāng)勞了媚朦。
不過我們簡單了解一下中間件實(shí)現(xiàn)原理還是很有必要的。先拿日志系統(tǒng)舉例吧日戈。通常我們的日志需要以文件形式保存下來询张,而不是在控制臺輸出。
我們會用到 "github.com/gorilla/handlers"
這個(gè)第三方包浙炼。
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")
}
我們先定義兩個(gè)路由器份氧,分別在瀏覽器輸出文本。
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 包來創(chuàng)建一個(gè)用于保存日志的文件server.log
http.Handle("/", handlers.LoggingHandler(logFile, handlers.CompressHandler(indexHandler)))
http.Handle("/about", handlers.LoggingHandler(logFile, handlers.CompressHandler( aboutHandler)))
這里使用了handlers
提供的LoggingHandler
和CompressHandler
來將日志進(jìn)行壓縮后輸入到文件 logFile 中弯屈,這里壓縮是使用 gzip 或 Deflate 對請求返回進(jìn)行壓縮蜗帜。
完整代碼如下
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
這個(gè)第三方包,使用 alice 原因是讓我們代碼看起來更優(yōu)雅资厉。
commonHandlers := alice.New(loggingHandler, handlers.CompressHandler)
對我們?nèi)罩具M(jìn)行整合封裝厅缺。
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