Go语言Gin框架的基本用法

目录

【基本的HTTP请求】

GET请求

POST请求

文件操作

重定向 

HTTP获取三方服务数据 

不同格式的内容输出

异步请求

【中间件】

中间件校验数据

登录中间件

【启动多个服务】 


Gin框架官网:https://gin-gonic.com/zh-cn/,新增一个Go文件,引入 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) //get方法
	//r.Run("127.0.0.1:9090")
	r.Run(":9090")  //如果不指定IP地址、端口号,默认为本机IP地址、8080端口

}

func getMsg(c *gin.Context) {
	name:=c.Query("name")
	//返回字符串类型数据
	//c.String(http.StatusOK,"欢迎您:%s",name)
	//返回json数据
	c.JSON(http.StatusOK,gin.H{
		"code":http.StatusOK,//状态
		"msg":"成功", //描述信息
		"data":"欢迎您:"+name,//数据
	})
}

浏览器访问 http://127.0.0.1:8080/get?name=zhangsan

Go语言Gin框架的基本用法_第1张图片

POST请求

r.POST("/post", controllers.BasicPostData)

func BasicPostData(c *gin.Context) {
	name := c.DefaultPostForm("name", "Gin") //获取body中的数据(form形式)
	fmt.Println("name", name)
	form, err := c.GetPostForm("name") //获取body中的数据(form形式)
	fmt.Println(form, err)
	c.JSON(http.StatusOK, "欢迎您:"+name)
}

通过postman请求 http://127.0.0.1:8080/post

Go语言Gin框架的基本用法_第2张图片

80e4e902783447c28a091b64c272e5db.png

文件操作

主要演示从服务器下载文件和上传文件到服务器,代码如下:

r.GET("/get-file", controllers.GetFile)
r.POST("/upload-file", controllers.UploadFile)
r.POST("/upload-file-batch", controllers.UploadFileBatch)

// 从服务端获取或下载文件
func GetFile(c *gin.Context) {
	fileName := "/home/rx/Documents/tmp/1.jpeg" //输出图片
	//fileName := "/home/rx/Documents/tmp/file.zip" //下载文件
	c.File(fileName)
}

// 将文件上传到服务端
func UploadFile(c *gin.Context) {
	file, err := c.FormFile("fileName")
	if err != nil {
		c.String(http.StatusBadRequest, "文件上传错误!")
	}
	//存储路径
	dst := "/home/rx/Documents/tmp/"
	c.SaveUploadedFile(file, dst+file.Filename) //存储文件
	c.String(http.StatusOK, fmt.Sprintf("%s 上传完成", file.Filename))
}

// 批量将文件上传到服务端
func UploadFileBatch(c *gin.Context) {
	//多文件的上传
	form, err := c.MultipartForm() //获取form
	if err != nil {
		c.String(http.StatusBadRequest, "上传文件错误")
	}
	files := form.File["fileName"] //上传的所有文件
	dst := "/home/rx/Documents/tmp/"
	//遍历文件
	for _, file := range files {
		c.SaveUploadedFile(file, dst+file.Filename)
	}
	c.String(http.StatusOK, fmt.Sprintf("%d 个文件上传完成!", len(files)))
}

执行效果如下: 

Go语言Gin框架的基本用法_第3张图片

Go语言Gin框架的基本用法_第4张图片

重定向 

//重定向到另外的域名
r.GET("/redirect1", func(c *gin.Context) {
	url := "http://www.baidu.com"                //重定向的URL
	c.Redirect(http.StatusMovedPermanently, url) //301永久重定向
})
//重定向到当前服务的其它路由
r.GET("/redirect2", func(c *gin.Context) {
	c.Request.URL.Path = "/get" //重定向到 http://127.0.0.1:8080/get
	r.HandleContext(c)
})

访问 http://127.0.0.1:8080/redirect1 会直接跳转到 “baidu.com”;访问 http://127.0.0.1:8080/redirect2 页面不会跳转,但会显示 /get 路由的内容。

Go语言Gin框架的基本用法_第5张图片

HTTP获取三方服务数据 

如果你用过PHP,一定知道PHP中有一个强大的函数是CURL,可以通过HTTP请求获取和发送数据与三方服务交互。Gin框架中实现这个功能也很简单,直接看代码:

r.GET("/curl", controllers.BasicCurlData)

func BasicCurlData(c *gin.Context) {
	url := "https://profile-avatar.csdnimg.cn/2334e87504d344588c50c0125c4e39da_rxbook.jpg!1"
	response, err := http.Get(url)
	if err != nil || response.StatusCode != http.StatusOK {
		c.Status(http.StatusServiceUnavailable)
		return
	}
	body := response.Body
	contentLength := response.ContentLength
	contentType := response.Header.Get("Content-Type")
	//数据写入响应体
	c.DataFromReader(http.StatusOK, contentLength, contentType, body, nil)
}

请求 http://127.0.0.1:8080/curl 可以获取到设定的URL中的内容。

不同格式的内容输出

可以输出JSON、XML、YAML等格式:

r.GET("/output", controllers.Output)

func Output(c *gin.Context) {
	flag := c.Query("flag")
	if flag == "json" {
		outputJson(c)
	} else if flag == "xml" {
		outputXML(c)
	} else if flag == "yaml" {
		outputYAML(c)
	}
}

// 输出json
func outputJson(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"code":    200,
		"message": "success",
	})
}

// 输出XML
func outputXML(c *gin.Context) {
	type Message struct {
		Code    int
		Message string
	}
	info := Message{}
	info.Code = 200
	info.Message = "Success"
	c.XML(http.StatusOK, info)
}

// 输出YAML
func outputYAML(c *gin.Context) {
	c.YAML(http.StatusOK, gin.H{
		"code":    200,
		"message": "输出YAML内容",
	})
}

Go语言Gin框架的基本用法_第6张图片

异步请求

假设某个方法需要执行一段很耗时的任务,如果是同步执行,效果如下:

func BasicPostData(c *gin.Context) {
	//耗时任务
	//同步执行三个任务
	for i := 0; i < 3; i++ {
		longTimeCost(c, i)
	}
}

func longTimeCost(cp *gin.Context, i int) {
	println("第" + strconv.Itoa(i) + "个任务开始执行:" + cp.Request.URL.Path)
	time.Sleep(time.Second * 5)
	println("第" + strconv.Itoa(i) + "个任务执行完毕")
}

Go语言Gin框架的基本用法_第7张图片

改成异步:

//异步执行三个任务
for i := 0; i < 3; i++ {
	go longTimeCost(c, i)
}

Go语言Gin框架的基本用法_第8张图片

【中间件】

中间件校验数据

使用中间件可以对数据进行规则校验,比如校验用户名是否合法,金额是否是数字类型等等。下面是一个简单的示例,校验token是否合法:

func Router() *gin.Engine {
	r := gin.Default() //默认路由引擎:包括 Logger and Recovery middleware
	//r:=gin.New() //没有任何中间件的路由引擎
	r.Use(service.Middleware()) //中间件校验
    r.POST("/post", controllers.BasicPostData)
    return r
}

// 中间件校验数据
func Middleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		fmt.Println(">> 中间件执行开始 <<")
		token := c.Query("token")
		if token != "123456" {
			c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
				"code": http.StatusBadRequest,
				"msg":  "token错误",
				"data": nil,
			})
			return
		}
		fmt.Println(">> 中间件执行结束 <<")
		c.Next() //执行后续操作
	}
}

然后再调用接口,如果token不正确则会被拦截:

Go语言Gin框架的基本用法_第9张图片

登录中间件

使用Gin框架自带的 `BasicAuth` 方法可以快速实现一个用户登录校验的中间件,代码如下:

func Router() *gin.Engine {
	r := gin.Default() //默认路由引擎:包括 Logger and Recovery middleware
	//r:=gin.New() //没有任何中间件的路由引擎
    r.Use(service.AuthMiddleware()) //登录中间件校验
    r.POST("/get", controllers.BasicGetData)
    return r
}

// 登录中间件
func AuthMiddleware() gin.HandlerFunc {
	//初始化用户
	accounts := gin.Accounts{ // gin.Accounts 是 map[string]string 类型
		"admin":    "123456",
		"zhangsan": "888888",
	}
	//动态添加用户
	accounts["lisi"] = "666666"
	accounts["wangwu"] = "777777"
	//将用户添加到登录中间件中
	auth := gin.BasicAuth(accounts)

    //获取登录的用户信息
	loginUserName := c.MustGet(gin.AuthUserKey).(string)
	fmt.Println("loginUserName", loginUserName)

	return auth
}

打开浏览器的访问效果(第一次需要输入用户名和密码,下次不需要,直到重新打开浏览器):

Go语言Gin框架的基本用法_第10张图片

Go语言Gin框架的基本用法_第11张图片

【启动多个服务】 

在一个Gin框架中启动多个服务,代码如下:

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"golang.org/x/sync/errgroup"
	"net/http"
	"time"
)

var g errgroup.Group

func main() {
	//服务器1:
	server01 := &http.Server{
		Addr:         ":8081",
		Handler:      router01(),
		ReadTimeout:  5 * time.Second,  //读取超时时间
		WriteTimeout: 10 * time.Second, //写入超时时间
	}
	//服务器2:
	server02 := &http.Server{
		Addr:         ":8082",
		Handler:      router02(),
		ReadTimeout:  5 * time.Second,
		WriteTimeout: 10 * time.Second,
	}
	//开启服务
	g.Go(func() error { //开启服务器程序1
		return server01.ListenAndServe()
	})
	g.Go(func() error { //开启服务器程序2
		return server02.ListenAndServe()
	})
	//让监听程序一直处于等待状态
	if err := g.Wait(); err != nil {
		fmt.Println("执行失败:", err)
	}
}

func router01() http.Handler {
	r1 := gin.Default()
	r1.GET("/", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"code": http.StatusOK,
			"msg":  "服务器01的响应",
		},
		)
	})
	return r1
}

func router02() http.Handler {
	r1 := gin.Default()
	r1.GET("/", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"code": http.StatusOK,
			"msg":  "服务器02的响应",
		},
		)
	})
	return r1
}

运行后,分别访问两个端口:

Go语言Gin框架的基本用法_第12张图片

你可能感兴趣的:(Go语言Gin框架,golang,gin,开发语言)