Go-gin学习

115 阅读3分钟

下载并安装Gin

go get github.com/gin-gonic/gin

Gin如何实现http的get方法

package main

import (
   "github.com/gin-gonic/gin"
   "net/http"
)

func main() {
   r := gin.Default()
   r.GET("/get", getMsg)
   r.Run(":9090") // 默认是本机 等价于 r.Run("127.0.0.1:9090")
}

func getMsg(c *gin.Context) {
   name := c.Query("name")
   //c.String(http.StatusOK, "欢迎您:%s", name) // 返回字符串格式
   c.JSON(http.StatusOK, gin.H{  // 返回json格式
      "code": http.StatusOK,
      "msg":  "成功" + name,
   })
}

Gin如何实现http的post方法

package main

import (
   "fmt"
   "github.com/gin-gonic/gin"
   "net/http"
)

func main() {
   r := gin.Default()
   r.POST("/post", postMsg)
   r.Run(":9090")
}

func postMsg(c *gin.Context) {
   name := c.DefaultPostForm("name", "") // 第二个参数是默认值
   fmt.Println(name)
   form, b := c.GetPostForm("name") // 第二个参数返回bool值,可以反映出用户是否传参
   fmt.Println(form, b)
   c.JSON(http.StatusOK, "欢迎你"+name) // http.StatusOK === 200
}

Gin如何实现重定向

package main

import (
   "github.com/gin-gonic/gin"
   "net/http"
)

func main() {
   r := gin.Default()
   // 一般重定向:重定向到外部网络
   r.GET("/redirect1", func(c *gin.Context) {
      url := "https://www.baidu.com"
      c.Redirect(http.StatusMovedPermanently, url) // http.StatusMovedPermanently === 301
   })
   //路由重定向:重定向到具体的路由
   r.GET("/redirect2", func(c *gin.Context) {
      c.Request.URL.Path = "/redirect3"
      r.HandleContext(c)
   })
   r.GET("/redirect3", func(c *gin.Context) {
      c.JSON(http.StatusOK, gin.H{
         "code": http.StatusOK,
         "msg":  "响应成功",
      })
   })
   r.Run(":9090")
}

Gin如何获取第三方数据

package main

import (
   "github.com/gin-gonic/gin"
   "net/http"
)

func main() {
   r := gin.Default()
   r.GET("/getOtherData", func(c *gin.Context) {
      url := "http://www.baidu.com"
      resp, err := http.Get(url)
      if err != nil || resp.StatusCode != http.StatusOK {
         c.Status(http.StatusServiceUnavailable) // http.StatusServiceUnavailable === 503
         return
      }
      body := resp.Body
      contentLength := resp.ContentLength
      contentType := resp.Header.Get("Content-Type")

      c.DataFromReader(http.StatusOK, contentLength, contentType, body, nil)
   })
   r.Run(":9090")
}

Gin如何多形式渲染

package main

import (
   "github.com/gin-gonic/gin"
   "net/http"
)

func main() {
   r := gin.Default()
   //json格式输出
   r.GET("/json", func(c *gin.Context) {
      c.JSON(200, gin.H{
         "html": "<b>hello,Gin框架</b>",
      })
   })

   //原样输出html(html渲染)
   r.GET("/someHTML", func(c *gin.Context) {
      c.PureJSON(http.StatusOK, gin.H{
         "html": "<b>hello,Gin框架</b>",
      })
   })

   //输出xml形式(XML渲染)
   r.GET("/someXML", func(c *gin.Context) {
      type Message struct { // 结构体
         Name string
         Msg string
         Age int
      }
      info:=Message{}
      info.Name="阿晓"
      info.Msg="hello"
      info.Age=23

      info.Msg = "hello"
      c.XML(http.StatusOK, info)
   })
   //返回yaml形式(yaml渲染)
   r.GET("/someYAML", func(c *gin.Context) {
      c.YAML(http.StatusOK, gin.H{
         "message": "Gin框架的多形式渲染",
         "status":  200,
      })
   })

   //开启服务
   r.Run(":9090")
}

Gin文件服务器

package main

import "github.com/gin-gonic/gin"

func main() {
   r := gin.Default()
   r.GET("/file", fileServer)
   r.Run(":9090")
}

func fileServer(c *gin.Context) {
   path := "E:/GoSrc/src/"
   fileName := path + c.Query("name")
   c.File(fileName) // 可以返回本地资源,通过浏览器直接可以访问
}

Gin 单文件上传

package main

import (
   "fmt"
   "github.com/gin-gonic/gin"
   "net/http"
)

func main() {
   r:=gin.Default()
   r.POST("/upload", func(c *gin.Context) {
      file, err := c.FormFile("fileName")
      if err!=nil {
         c.String(http.StatusBadRequest,"文件上传错误!")
      }
      //存储路径
      dst:="E:/GoSrc/src/"
      c.SaveUploadedFile(file,dst+file.Filename)//存储文件
      c.String(http.StatusOK,fmt.Sprintf("%s 上传完成",file.Filename))
   })
   r.Run(":9090")
}

Gin 多文件上传

package main

import (
   "fmt"
   "github.com/gin-gonic/gin"
   "net/http"
)

func main() {
   r:=gin.Default()
   r.POST("/upload", func(c *gin.Context) {
      //多文件的上传
      form, err := c.MultipartForm() //获取form
      if err!=nil {
         c.String(http.StatusBadRequest,"上传文件错误")
      }
      files := form.File["file_key"] //上传的所有文件
      dst:="E:/GoSrc/src/"
      //遍历文件
      for _,file:=range files{
         c.SaveUploadedFile(file,dst+file.Filename)
      }
      c.String(http.StatusOK,fmt.Sprintf("%d 个文件上传完成!", len(files)))
   })
   r.Run(":9090")
}

Gin 如何自定义中间件

package main

import (
   "fmt"
   "github.com/gin-gonic/gin"
   "net/http"
   "strconv"
)

func main() {
   r:=gin.Default() //默认路由引擎:包括 Logger and Recovery middleware
   //r:=gin.New() //没有任何中间件的路由引擎
   r.Use(Middleware())
   r.GET("/middleware", func(c *gin.Context) {
      fmt.Println("服务端执行开始执行....")
      name:=c.Query("name")
      ageStr:=c.Query("age")
      age,_:=strconv.Atoi(ageStr)
      log.Println(name,age)
      res:= struct {
         Name string `json:"name"` //为结构体添加标签,在json中显示为:name
         Age int `json:"age"`
      }{name,age}
      c.JSON(http.StatusOK,res)
   })
   r.Run(":9090")

}

func Middleware() gin.HandlerFunc {
   return func(c *gin.Context) {
      fmt.Println("中间件开始执行=====")
      name:=c.Query("name")
      ageStr:=c.Query("age")
      age, err := strconv.Atoi(ageStr) //string转int
      if err!=nil {
         c.AbortWithStatusJSON(http.StatusBadRequest,"输入的数据错误,年龄不是整数")
         return
      }
      if age<0||age>100 {
         c.AbortWithStatusJSON(http.StatusBadRequest,"输入的数据错误,年龄数据错误")
         return
      }
      if len(name)<6|| len(name)>12 {
         c.AbortWithStatusJSON(http.StatusBadRequest,"用户名只能是6-12位")
         return
      }
      c.Next()//执行后续操作
      fmt.Println(name,age)


   }
}

//TODO:路由中间件的作用: 对路由到来的数据先进行预处理,包括数据加载、请求验证(过滤)等。

Gin 登录中间件

package main

import (
   "github.com/gin-gonic/gin"
   "net/http"
)
func main() {
   r := gin.Default()
   // 路由使用 gin.BasicAuth() 中间件
   r.Use(AuthMiddleware())
   r.GET("/login", func(c *gin.Context) {
      // 获取用户,它是由 BasicAuth 中间件设置的
      user := c.MustGet(gin.AuthUserKey).(string)
      c.JSON(http.StatusBadRequest, "登录成功,欢迎您:"+user)
   })
   // 监听并在 0.0.0.0:9090 上启动服务
   r.Run(":9090")
}
func AuthMiddleware() gin.HandlerFunc {
   //初始化用户
   accounts := gin.Accounts{ // gin.Accounts 是 map[string]string 类型
      "admin":  "adminpw",
      "system": "systempw",
   }
   //动态添加用户
   accounts["Go"]="123456789"
   accounts["Gin"]="gin123"
   //将用户添加到登录中间件中
   auth := gin.BasicAuth(accounts)
   return auth
}
//todo:登录中间件:对请求先进行认证(过滤)

Gin 同步异步

package main

import (
   "fmt"
   "github.com/gin-gonic/gin"
   "strconv"
   "time"
)

func main() {
   r:=gin.Default()
   //同步请求
   r.GET("/sync", func(c *gin.Context) {
      sync(c)
      c.JSON(200,">>>主程序(主go程)同步已经执行<<<")
   })
   //异步请求
   r.GET("/async", func(c *gin.Context) {
      for i:=0;i<6;i++{
         cCp:=c.Copy()
         go async(cCp,i)
      }
      c.JSON(200,"^^^主程序(主go程)异步已经执行^^^")
   })
   r.Run(":9090")
}

func async(cp *gin.Context, i int) {
   fmt.Println("第"+strconv.Itoa(i)+"个go程开始执行:"+cp.Request.URL.Path)
   time.Sleep(time.Second*3)
   fmt.Println("第"+strconv.Itoa(i)+"个go程执行结束+++++")

}

func sync(c *gin.Context) {
   println("开始执行同步任务:"+c.Request.URL.Path)
   time.Sleep(time.Second*3)
   println("同步任务执行完成!")
}