写在开头
这篇博客即属于博客也属于笔记,内容大部分来自于go编程课老师的Go Web开发(Gin 框架)简易入门教程。
本人做一些笔记整理成这篇博客。
net/http标准库
Go语言内置的net/http包,为我们提供了基础的路由函数组合和丰富的功能函数。
只是需要简单的API编写,net/http就完全足够了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package main
import ( "fmt" "log" "net/http" )
func main() { http.HandleFunc("/", handler) log.Fatal(http.ListenAndServe(":8000", nil)) }
func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path) fmt.Fprintf(w, "helloworld")
}
|
进阶
gin框架
Gin是一个用Go(Golang)编写的HTTP web框架。它是一个类似于martini但拥有更好性能的API框架,由于httprouter,速度提高了近40倍。
1 2 3 4 5 6 7 8 9 10 11 12
| package main
import "github.com/gin-gonic/gin"
func main() { r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{"message": "pong"}) }) r.Run() }
|
路由
输出渲染格式
gin可以很方便的渲染输出数据的格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| package main
import ( "net/http"
"github.com/gin-gonic/gin" )
func main() { r := gin.Default() r.GET("/someString", func(c *gin.Context) { c.String(http.StatusOK, "string") })
r.GET("/someJSON", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK}) })
r.GET("/moreJSON", func(c *gin.Context) { var msg struct { Name string `json:"user"` Message string Number int }
msg.Name = "Lena" msg.Message = "hey" msg.Number = 123 c.JSON(http.StatusOK, msg) })
r.GET("/someXML", func(c *gin.Context) { c.XML(http.StatusOK, gin.H{"message": "Hey", "status": http.StatusOK}) })
r.GET("/someYAML", func(c *gin.Context) { c.YAML(http.StatusOK, gin.H{"message": "Hey", "status": http.StatusOK}) })
r.Run() }
|
中间件
Default
函数会默认绑定准备好的中间件,Logger
和Recovery
,它们分别帮助我们打印日志输出和painc处理
1 2 3 4 5 6
| func Default() *Engine { debugPrintWARNINGDefault() engine := New() engine.Use(Logger(), Recovery()) return engine }
|
从中可以看出,Gin的中间件是通过Use方法设置的,它接收一个可变参数,所以我们同时可以设置多个中间件。
1 2 3 4 5 6
| func(engine *Engine) Use(middleware ...HandlerFunc) IRoutes { engine.RouterGroup.Use(middleware...) engine.rebuild404Handlers() engine.rebuild405Handlers() return engine }
|
而一个Gin的中间件,其实就是Gin定义的一个HandlerFunc
现在来自定义一个自己的中间件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package main
import ( "fmt" "time"
"github.com/gin-gonic/gin" )
func main() { r := gin.Default() r.Use(requestTime()) r.GET("/", func(c *gin.Context) { fmt.Println("I'm here, hello") c.String(200, "hello") }) r.Run(":8888") }
func requestTime() gin.HandlerFunc { return func(c *gin.Context) { start := time.Now() fmt.Println("这里被我拦截住了") fmt.Println("因为调用了c.Next() 我现在要走了") c.Next() fmt.Println("我又回来了") fmt.Println(time.Since(start)) } }
|
c.Next()
立即执行下一个HandlerFunc,完后跳转回来继续执行c.Next()接下去的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| package main
import ( "fmt"
"github.com/gin-gonic/gin" )
func main() { r := gin.New() r.Use(mymiddleware()) r.Use(mymiddleware2()) r.GET("/", func(c *gin.Context) { fmt.Println("test in") c.String(200, "自我定义中间件测试成功")
fmt.Println("test out")
})
r.Run()
}
func mymiddleware() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("mml 1 in") fmt.Println("mml 1 out") } }
func mymiddleware2() gin.HandlerFunc { return func(c *gin.Context) { fmt.Println("mml 2 in") c.Next() fmt.Println("mml 2 out") } }
|



c.Abort()
阻断执行下一个HandlerFunc,仅会执行接下去的代码,常用于权限控制拦截操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| package main
import ( "fmt" "net/http"
"github.com/gin-gonic/gin" )
func main() { r := gin.Default() r.Use(authority()) r.GET("/path/:name", func(c *gin.Context) { fmt.Println("欢迎") c.String(http.StatusOK, "Hello %s", c.Param("name")) }) r.Run(":8090") }
func authority() gin.HandlerFunc { return func(c *gin.Context) { isAdmain := c.Param("name") == "admin" if isAdmain { c.Next() } else { c.Abort() c.String(http.StatusOK, "sorry, you cann't in") } fmt.Println("end") } }
|
c.Set(key, value) 和 c.Get(key)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package main
import ( "fmt"
"net/http"
"github.com/gin-gonic/gin" )
func main() { r := gin.Default() r.Use(authority2()) r.GET("/", func(c *gin.Context) { value, ok := c.Get("key") if ok { fmt.Println(value) } c.String(http.StatusOK, "hello") }) r.Run(":8099") }
func authority2() gin.HandlerFunc { return func(c *gin.Context) { c.Set("key", "你好") c.Next() } }
|