文章目录

gin.New

路由包含多个HandlerFunc函数

使用中间件

如何写log日志

gin.New

我们之前的例子都是利用了gin.Default(),那么gin.New()跟它有什么区别?来简单看下源码

gin.Default()源码如下

func Default() *Engine {

debugPrintWARNINGDefault()

engine := New()

engine.Use(Logger(), Recovery())

return engine

}

1

2

3

4

5

6

gin.New()源码如下

func New() *Engine {

debugPrintWARNINGNew()

engine := &Engine{

RouterGroup: RouterGroup{

Handlers: nil,

basePath: "/",

root: true,

},

FuncMap: template.FuncMap{},

RedirectTrailingSlash: true,

RedirectFixedPath: false,

HandleMethodNotAllowed: false,

ForwardedByClientIP: true,

AppEngine: defaultAppEngine,

UseRawPath: false,

UnescapePathValues: true,

MaxMultipartMemory: defaultMultipartMemory,

trees: make(methodTrees, 0, 9),

delims: render.Delims{Left: "{{", Right: "}}"},

secureJsonPrefix: "while(1);",

}

engine.RouterGroup.engine = engine

engine.pool.New = func() interface{} {

return engine.allocateContext()

}

return engine

}

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

我们看到gin.New()返回一个*Engine 指针,而gin.Default()不但返回一个*Engine 指针,而且还进行了debugPrintWARNINGDefault()和engine.Use(Logger(), Recovery())其他的一些中间件操作

Default returns an Engine instance with

the Logger and Recovery middleware already attached.

1

2

所以gin.New()更精简。目前我只是罗列github上关于gin框架的知识点,后续如果有时间和精力在去研究gin源码

路由包含多个HandlerFunc函数

之前我举的例子都是一个路由对应一个视图函数

看看router对应的源码方法,就可以得知视图函数可以是多个

func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {

return group.handle("GET", relativePath, handlers)

}

1

2

3

我们通过一个例子来试验下

package main

import (

"fmt"

"github.com/gin-gonic/gin"

)

 

func main() {

router := gin.New()

//使用日志

router.Use(gin.Logger())

//使用Panic处理方案

router.Use(gin.Recovery())

//路由途径多个函数

router.GET("/index",index(),chain)

router.Run(":8080")

}

func index() gin.HandlerFunc {

return func(c *gin.Context) {

fmt.Println("before middleware")

}

}

func chain(c *gin.Context){

fmt.Println("index chainFun")

}

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

我们在命令行执行如下操作指令

$ curl -X GET http://localhost:8080/index

然后我们就会看到log输出如下:依次执行index、chain视图函数

before middleware

index chainFun

1

2

使用中间件

在gin框架中有一些内置的中间件,诸如以下的log输出、错误处理等

//使用日志

router.Use(gin.Logger())

//使用Panic处理方案

router.Use(gin.Recovery())

1

2

3

4

我们还可以自己构造中间件,gin框架让我们构造中间件,进行request前后处理很方面,我们可以直接通过一个例子来感受下即可

package main

import (

"fmt"

"github.com/gin-gonic/gin"

)

 

func main() {

router := gin.New()

//使用日志

router.Use(gin.Logger())

//使用Panic处理方案

router.Use(gin.Recovery())

//中间件

authorized:=router.Group("/author")

authorized.Use(AuthRequired())

{

authorized.POST("/login", loginEndpoint)

}

router.Run(":8080")

}

func loginEndpoint(c *gin.Context){

value,exist:=c.Get("request")

fmt.Println("authorized loginEndpoint --exist:",exist,"--value:",value)

}

func AuthRequired() gin.HandlerFunc {

return func(c *gin.Context) {

fmt.Println("before middleware")

c.Set("request", "clinet_request")

c.Next()

fmt.Println("after middleware")

}

}

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

以上代码的意思就是对/author组下面的使用中间件Use(AuthRequired()),也就是代码中的AuthRequired函数,在这里我们进行了c.Set("request", "clinet_request")操作,然后通过c.Next()去执行对应的视图,也就是代码中的/login,在其对应的视图函数loginEndpoint里可以获取之前设置的值

我们通过curl -X POST http://localhost:8080/author/login来看下后台的输出结果

before middleware

authorized loginEndpoint --exist: true --value: clinet_request

after middleware

1

2

3

如何写log日志

log日志对分析软件问题所在很重要,在gin框架中,也为我们提供了一个http日志的输出,很简单,看例子即可

package main

import (

"github.com/gin-gonic/gin"

"io"

"os"

)

 

func main() {

f, _ := os.Create("gin.log")

gin.DefaultWriter = io.MultiWriter(f,os.Stdout)

router := gin.Default()

router.GET("/ping", func(c *gin.Context) {

c.String(200, "pong")

})

router.Run(":8080")

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23