• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Gin框架

武飞扬头像
我不是皮卡丘啊
帮助1

一、Gin介绍

Gin是一个用Go编写的HTTPweb框架。它是一个类似于martini但拥有更好性能的API框架, 优于httprouter,速度提高了近 40 倍。 点击此处访问Gin官方中文文档。

二、安装

1、安装Gin

控制台输入

go get -u github.com/gin-gonic/gin

2、代码中导入

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

3、简单示例,验证

新建文件main.go,内容如下。

package main

import (
    "net/http"

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

func main() {
    // 1.创建路由
   r := gin.Default()
   // 2.绑定路由规则,执行的函数
   // gin.Context,封装了request和response
   r.GET("/", func(c *gin.Context) {
      c.String(http.StatusOK, "hello World!")
   })
   // 3.监听端口,默认在8080
   // Run("")里面不指定端口号默认为8080
   r.Run(":8000")
}
学新通

运行后访问: http://localhost:8000/

学新通

三、渲染前端与配置跨域

1、渲染html模板

Gin支持加载HTML模板, 然后根据模板参数进行配置并返回相应的数据,本质上就是字符串替换。LoadHTMLGlob()方法可以加载模板文件(参数为待渲染的html模板文件,如果参数为相对路径则为运行路径的相对路径)。

a、 渲染单个文件

比如:

r.LoadHTMLGlob("web/index.html")

b、 渲染文件夹下的所有文件

比如:

r.LoadHTMLGlob("web/*")

c、 渲染文件夹下的所有html后缀的文件

比如:

r.LoadHTMLGlob("web/*.html")

2、定义模板分割

r.Delims("<<<", ">>>")

第一个参数为:模板标签开始标记
第二个参数为:模板标签结束标记

3、渲染静态文件和目录

如果你需要引入静态文件需要定义一个静态文件目录

r.Static("/assets", "./assets")

若assets的目录结构为
学新通

可以根据 http://localhost:8000/assets/img/home.jpg 访问指定资源
学新通
如果r为路由组,则需要在assets前拼接路由组的路径包括其前缀

4、重定向

// 重定向两种默认应支持的首页访问方式
router.GET("/", func(c *gin.Context) {
	//重定向到/index.html
	c.Redirect(302, "/index.html")
})
router.GET("/index", func(c *gin.Context) {
	//重定向到/index.html
	c.Redirect(302, "/index.html")
})
router.GET("/index.html", func(c *gin.Context) {
	//返回渲染的html模板中的index.html
	c.HTML(http.StatusOK, "index.html", gin.H{
		"baseUrl": "http://"   host,
	})
})

5、配置跨域

r.Use(Next())

Nex()函数

// 允许跨域
func Next() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
		c.Header("Access-Control-Allow-Origin", "*")
		c.Header("Access-Control-Allow-Headers", "Access-Control-Allow-Headers,Authorization,User-Agent, Keep-Alive, Content-Type, X-Requested-With,X-CSRF-Token,AccessToken,Token")
		c.Header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, PATCH, OPTIONS")
		c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
		c.Header("Access-Control-Allow-Credentials", "true")

		// 放行所有OPTIONS方法
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusAccepted)
		}
		c.Next()
	}
}
学新通

四、路由相关

1、创建路由组

// 创建路由组
// 根据需要,可以为这种多级的路由组:r.Group("/v1/user")
userApi:= r.Group("/user")
// 创建用户
// 匹配POST请求的 /user
userApi.POST("", userCreate)
// 修改用户
// 匹配PUT请求的 /user/1 但不会匹配 /user/ 或者 /user
userApi.PUT("/:id", userUpdate)
// 获取用户
// 匹配GET请求的 /user/1 但不会匹配 /user/ 或者 /user
userApi.GET("/:id", userGet)
// 查询用户
// 匹配GET请求的 /user/list
userApi.GET("/list", userQuery)
// 删除用户
// 匹配DELETE请求的 /user/1 但不会匹配 /user/ 或者 /user
userApi.DELETE("/:id", userDelete)
学新通

Restful风格的API

2、路由参数

a、api参数

通过Context的Param方法来获取api参数
例如:

userApi.GET("/:id/:name", userGet)

userGet函数为

func userGet(ctx *gin.Context) {
	//api参数可以为单个或者多个也可以拼接多级
	//ctx.Param()函数获取时参数需要与api中的名称一致才能获取到
	id := ctx.Param("id")
	name:= ctx.Param("name")
	ctx.JSON(http.StatusOK, gin.H{"data": id,"name":name})
	return
}

可以根据 http://localhost:8000/user/1/admin 访问此接口
访问效果为:
学新通

b、url参数

通过Context的Query方法与DefaultQuery方法来获取url参数
例如:

userApi.GET("/list", userQuery)

userQuery函数为

func userQuery(ctx *gin.Context) {
	//获取
	id := ctx.Query("id")
	//获取,第二个参数为获取为空的默认值,如果参数不存在则放回第二个参数
	name := ctx.DefaultQuery("name", "user")
	ctx.JSON(http.StatusOK, gin.H{"data": id, "name": name})
	return
}

可以根据 http://localhost:8000/user/list 后面拼接查询参数,访问此接口
访问效果为:
学新通
学新通

c、表单参数

表单参数测试与观察请求效果需要安装postman
通过Context的PostForm方法来获取表单参数
例如:

userApi.POST("", userCreate)

userCreate函数为

func userCreate(ctx *gin.Context) {
	id := ctx.PostForm("id")
	name := ctx.PostForm("name")
	ctx.JSON(http.StatusOK, gin.H{"data": id, "name": name})
	return
}

如图,访问此接口
效果为:
学新通

d、json参数

json参数测试与观察请求效果需要安装postman
通过Context的GetRawData或者ShouldBindJSON方法来获取表单参数
例如:

userApi.PUT("/:id", userUpdate)

userUpdate函数为
GetRawData方法

func userUpdate(ctx *gin.Context) {
	// 注意:下面为了举例子方便,暂时忽略了错误处理
	b, _ := ctx.GetRawData() // 从ctx.Request.Body读取请求数据
	// 定义map或结构体
	var m map[string]interface{}
	// 反序列化
	_ = json.Unmarshal(b, &m)
	ctx.JSON(http.StatusOK, gin.H{"data": m["id"], "name": m["name"]})
	return
}

ShouldBindJSON方法

//先定义结构
type User struct {
	Id   string `form:"id" json:"id" binding:"required"`
	Name string `form:"name" json:"name" binding:"required"`
}
//函数实现
func userUpdate(ctx *gin.Context) {
	var user User
	if err := ctx.ShouldBindJSON(&user); err == nil {
		ctx.JSON(http.StatusOK, gin.H{"data": user.Id, "name": user.Name})
		return
	} else {
		ctx.JSON(http.StatusOK, gin.H{"err": err.Error()})
		return
	}
}
学新通

如图,访问此接口
效果为:学新通

e、参数绑定

为了能够更方便的获取请求相关参数,提高开发效率,我们可以基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中form表单、JSON、XML等参数到结构体中。
代码示例:
定义要获取的结构

type User struct {
	Id   string `form:"id" json:"id" binding:"required"`
	Name string `form:"name" json:"name" binding:"required"`
}

userCreate函数为

func userCreate(ctx *gin.Context) {
	var user User
	if err := ctx.ShouldBind(&user); err == nil {
		ctx.JSON(http.StatusOK, gin.H{"data": user.Id, "name": user.Name})
		return
	}else{
		ctx.JSON(http.StatusOK, gin.H{"err": err.Error()})
		return
	}
}

userUpdate函数为

func userUpdate(ctx *gin.Context) {
	var user User
	if err := ctx.ShouldBind(&user); err == nil {
		ctx.JSON(http.StatusOK, gin.H{"data": user.Id, "name": user.Name})
		return
	}else{
		ctx.JSON(http.StatusOK, gin.H{"err": err.Error()})
		return
	}
}

3、上传文件

一般都是post请求表单传参
例如:

userApi.POST("/upload", userUpload)

userUpload函数为

//先定义结构
type FileUpload struct {
	File *multipart.FileHeader `form:"file"`
	Type string                `form:"type"`
}
//函数实现
func userUpload(ctx *gin.Context) {
	var fileUpload FileUpload
	if err := ctx.ShouldBind(&fileUpload); err == nil {
		//获取运行路径
		ex, err := os.Executable()
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{"err": err.Error()})
			return
		}
		//定义接收文件的存放地址
		path := filepath.Dir(ex)   string(os.PathSeparator)   fileUpload.File.Filename
		//接收文件并保存到指定path
		err = ctx.SaveUploadedFile(fileUpload.File, path)
		ctx.JSON(http.StatusOK, gin.H{"data": path, "type": fileUpload.Type})
		return
	} else {
		ctx.JSON(http.StatusOK, gin.H{"err": err.Error()})
		return
	}
}
学新通

如图,访问此接口
效果为:
学新通
postman测试请求这个接口时,注意file字段的类型为file才能选择文件哦

五、中间件

1、统一注册中间件

对全局路由或者已注册的路由组统一注册中间件

r.Use(CheckToken())

2、单独注册中间件

userApi.POST("/upload",CheckToken(),userUpload)

3、中间件函数实现

func CheckToken() gin.HandlerFunc {
	return func(c *gin.Context) {
		//验证不通过直接跳出
		//c.JSON(http.StatusBadRequest, gin.H{"msg": "need token"})
		//c.Abort()
		//return
		//验证通过继续
		c.Next()
	}
}

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhiaegeh
系列文章
更多 icon
同类精品
更多 icon
继续加载