Gin框架

gin框架中的路由


gin框架中的路由使用的是httprouter这个库

  • 简单路由
  • 动态路由

函数:(输出数据的四种格式)

  • ctx.String():返回一个字符串
    r.GET("/", func(ctx *gin.Context) {
    // 200为状态码
    ctx.String(200, "string")
    })
  • ctx.JSON()
  • ctx.XML()
  • c.HTML()
  • c.YAML()

1. gin遵循RESTful风格的api


2. API例子


3. HTTP常见请求方法:GET(查) POST(增) PUT(改) DELETE(删)


func main(){
//使用默认中间件(logger和recovery中间件)创建gin路由
router := gin.Default()//返回默认的路由引擎,(可以自己写)

router.GET("/someGet", getting)
router.POST("/somePost", posting)
router.PUT("/somePut", putting)
router.DELETE("/someDelete", deleting)
router.PATCH("/somePatch", patching)
router.HEAD("/someHead", head)
router.OPTIONS("/someOptions", options)

//默认8080端口启动服务,除非定义PORT的环境变量
router.Run()
//router.Run(":3000") hardcode 端口号
}

4. 模板与渲染


  1. Gin框架中使用ctx.HTML可以渲染模板,渲染模板前需要解析模板,使用LoadHTMLGlob()或者LoadHTMLFiles()方法加载模板
    例:

    <!DOCTYPE html>
    <html lang="en">
    <head>

    <meta charset="UTF-8">
    <meta http-equiv="X_UA_Compatible" content="IE=edge">
    <meta name="viewPort" content="width=device-width, initial-scale=1.0">

    <title> Document </title>
    </head>

    <body>
    <h1>这是一个html模板</h1>

    <h3>{{.title}}</h3>
    </body>
    </html>
    {{define "template/hello.tmpl"}}

    <!DOCTYPE html>

    <html lang="zh-CN">
    <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>Hello</title>
    </head>

    <body>
    <p>Hello {{.}}</p>
    </body>
    </html>

    {{end}}
        r.LoadHTMLGlob("template/*")
    //r.LoadHTMLFiles("template/hello.tmpl", "template/index.html")
    r.GET("/hello", func(ctx *gin.Context) {
    ctx.HTML(
    http.StatusOK, "template/hello.tmpl",
    gin.H{"title" : "首页"})
    })
    r.GET("/index", func(ctx *gin.Context) {
    ctx.HTML(
    http.StatusOK, "index.html",
    gin.H{"title" : "首页"})
    })
    ```
    1. gin 自定义模板方法
    ```go
    r.SetFuncMap(template.FuncMap{
    "safe" : func(str string) template.HTML {
    //将str进行html解析
    return template.HTML(str)
    },
    })
    //自定义函数需要在解析之前
    • 使用:修改index.html <h3>{{.title | safe}}</h3> 模板调用safe函数
  2. 静态文件:html页面中用到的样式文件,如.css, .js, 图片, 音乐等

    router.Static("模板中引用的目录", "实际的目录(本机)")

5. 获取参数 url?xxx=xxx&xxx=xxx


  1. 获取请求参数
    • querystring指的是URL中?后面携带的参数
    • 函数
      • context.DefaultQuery(“需要查询的字符串”, “默认值”)
      • context.Query(“需要查询的字符串”)
  2. 动态获取
    • context.Param()
      router.GET("/xxx/:value1/:value2", func(context *gin.Context){
      //获取动态传入的值
      v1 := context.Param("value1")
      v2 := context.Param("value2")
      })
  3. 表单处理

6. 路由


  1. 重定向
    • url重定向,成功状态码:301
      context.Redirect(301, "url")
    • 路由重定向
      context.Request.URL.Path = "路由"
      router.HandleContext(context)
  2. NoRoute
    //代表没有路由的页面(一般为404页面)
    router.NoRouter(func()...)
  3. 路由组
    userGroup := router.Group("/user")
    {
    //代表:/user/add
    userGroup.GET("/add", .....)
    .........
    }

7. 文件上传


  • 单文件上传
  • 多文件上传
    • 同名多文件上传
  • 上传文件的存储
    • (例:按日期)

8. 自定义控制器


* 控制器处理
* 添加结构体
* 继承方法,控制器继承

9. 中间件(拦截器)


context.Set()   //设置全局变量
context.Next() //通过
context.Abort() //阻止
```
* 中间件事项
1. GIN.Default()自带两个中间件(Logger, Recovery),如果不想使用上面两个默认的中间件可以使用gin.New()新建一个没有任何中间件的路由
2. gin中间件中使用goroutine
3. 当在`中间件`或handler中启动新的goroutine时,**不能使用**原始的上下文(ctx \*gin.Context),必须使用其只读副本`ctx.Copy`
```go
// 4.在中间件中启用新的goroutine后,不能使用context,必须使用copy
func InitMiddleWare3(c *gin.Context) {
log.Println(time.Now())
c.Set("username", "heihei")

//启用goroutine统计日志
CP := c.Copy()
//拷贝副本传入goroutine
go func() {
time.Sleep(time.Second * 3)
//log.Println("====>>>>", c.Request.URL.Path)
//不应该这样使用
log.Println("=========>>>>", CP.Request.URL.Path)
}()
}

HTTP是无状态协议,对同一个网站的多次访问是没有任何关系的.
如果要实现多个页面的共享数据,可以使用Cookie或Session实现
cookie是存储在访问者的计算机的浏览器中的.

  • 设置和获取cookie
    ctx.SetCookie(name, value string, maxAge int, path domain string, secure, httpOnly bool)
  • 删除cookie:设置maxAge为-1

11. Session


Session是另一种记录客户状态的机制,与Cookie不同,session是保存在服务器上的

  • gin中没有提供session相关的文档,我们可以使用第三方的session中间件来实现

12. 服务器端口


//开启服务默认为8080端口,可自定义
router.Run(":port")

13.重启或停止


使用http.Server内置的Shutdown()方法优雅的关机

14.写入日志文件

//LoggerWithFormatter 中间件会写入日志到gin.DefaultWriter
//默认gin.DefaultWriter = os.Stdout
router.Use(gin.LoggerWithFormatter(func(params gin.LogFormatterParams) string {
//我的自定义格式,调用自带的结构体参数
return fmt.Sprintln(
"params.:", params.BodySize, "\n",
"params.:", params.ClientIP, "\n",
"params.:", params.ErrorMessage, "\n",
"params.:", params.Keys, "\n",
"params.:", params.Latency, "\n",
"params.:", params.Method, "\n",
"params.:", params.Path, "\n",
"params.:", params.Request.Proto, "\n",
"params.:", params.StatusCode, "\n",
"params.:", params.TimeStamp.Format(time.RFC1123), "\n",
"params.:", params.Request.UserAgent(),
)
}))

//全局使用recovery中间件
router.Use(gin.Recovery())
router.GET("/ping", func(ctx *gin.Context) {
ctx.String(200, "pong")
})