美文网首页程序员GoGolang
golang 网络编程(6)中间件

golang 网络编程(6)中间件

作者: zidea | 来源:发表于2019-04-24 10:16 被阅读8次
golang_real.jpg

在前面的分享
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提供的LoggingHandlerCompressHandler来将日志进行压缩后输入到文件 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

相关文章

  • golang 网络编程(6)中间件

    在前面的分享golang 网络编程(5)中间件我们通过学习自己动手写了两个拦截器,输出日志和简单权限校验。这也是我...

  • golang 网络编程(5)中间件

    当构建 web 应用程序,可能对所有的请求会共享一些功能。例如我们每一个请求都会写入日志。 打印 http 请求或...

  • Golang网络编程TCP连接

    Golang网络编程 TCP编程编写服务端package mainimport ( "bufio" "fmt"...

  • 2016规划

    es、netty(IO+网络编程)、jsf、tomcat、Nginx+lua+C redis zk golang ...

  • GoLang TCP网络编程

    原文链接:http://blog.csdn.net/hacker00011000/article/details/...

  • golang 网络编程实践

    webmain.go proxy.go util/config.go util/func.go util/load...

  • golang 网络编程(3)

    先定义数据结构,我们可能总是习惯用我们熟知语言例如 java 中对应的类来理解 go 语言中结构,这就错了,在学习...

  • golang 网络编程(1)

    Http 请求是一种无状态的通讯模型,无状态可能对于初学者听起来有点 confusing。这里的无状态表明每一次请...

  • Golang网络编程UDP

    UDP协议 UDP协议中文名称使用户数据报协议。UDP是一种无连接的传输层协议不需要建立连接就可以直接进行数据发送...

  • Golang网络编程实战

    1. 开张课、课程内容、说下反向代理 2. 复习课 利用协程创建两个测试web服务 3. 最简单的请求 转发 、h...

网友评论

    本文标题:golang 网络编程(6)中间件

    本文链接:https://www.haomeiwen.com/subject/mxoigqtx.html