Gin简单明了的教程---上

Posted 大忽悠爱忽悠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gin简单明了的教程---上相关的知识,希望对你有一定的参考价值。

Gin简单明了的教程---上


Gin官网


Gin 环境搭建

1.下载并安装 gin:

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

注意: 如果直接从github拉取失败,可以尝试更换代理,重新设置GOPROXY为国内代理源,然后再次尝试

go env -w GOPROXY=https://goproxy.cn,https://mirrors.aliyun.com/goproxy,https://goproxy.io,direct

2.将 gin 引入到代码中:

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

3.测试

package main

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

func main() 
	//创建一个默认的路由引擎
	router := gin.Default()
	//配置路由
	router.GET("/", func(c *gin.Context) 
		//返回JSON数据
		c.JSON(200, gin.H
			"status": 200,
			"data":   "SUCCESS",
		)
	)
	//启动HTTP服务,默认8080端口
	router.Run()

	//改变默认启动端口--如果是localhost可以省略
	router.Run(":8000")

golang 程序的热加载

热加载就是当我们对代码进行修改时,程序能够自动重新加载并执行,这在我们开发中 是非常便利的,可以快速进行代码测试,省去了每次手动重新编译。

beego 中我们可以使用官方给我们提供的 bee 工具来热加载项目,但是 gin 中并没有官方提 供的热加载工具,这个时候我们要实现热加载就可以借助第三方的工具。

go get github.com/pilu/fresh 
D:\\gin_demo>fresh

先查看GOPATH下bin目录下有无fresh.exe,没有的话,采用下面方式进行安装和下载:

git clone https://github.com/gravityblast/fresh.git
go install github.com/pilu/fresh@latest

  • 如果是linux系统,出现命令找不到的情况,需要设置软链接或者将对应可执行程序路径加入环境变量。
  • 如果是win系统,也是同理,加入环境变量。

在对应的项目文件下,打开命令行,执行fresh命令,会自动去寻找项目文件下的main文件,然后启动程序,然后一直监控当前目录下的文件是否被修改,如果是的话,就重启项目。

GoLand只有在电脑启动的时候才会去读取环境变量,因此如果不重启电脑,那么GoLand终端使用fresh命令,会报错


go get github.com/codegangsta/gin
gin run main.go

Gin 框架中的路由

看例子学习:

package main

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

func main() 
	//创建一个默认的路由引擎
	router := gin.Default()
	//配置路由--支持RestFul API

	//增
	router.POST("/", func(c *gin.Context) 
	    //?name=dhy&age=18
		name := c.Query("name")
		age := c.Query("age")
		//H类型为: map[string]interface 等同于Java中的Map<String,Object>
		c.JSON(200, gin.H
			"name": name,
			"age":  age,
		)
	)

	//删
	router.DELETE("/", func(c *gin.Context) 
		c.String(200, "delete")
	)

	//改
	router.PUT("/", func(c *gin.Context) 
		c.String(200, "put")
	)

	//查
	router.GET("/", func(c *gin.Context) 
		c.String(200, "this is Get query!")
	)

	//改变默认启动端口
	router.Run(":8080")


动态路由

	//查
	router.GET("/:id", func(c *gin.Context) 
		id := c.Param("id")
		//可以格式化字符串
		c.String(200, "get id= %v", id)
	)

响应结果

返回一个字符串

	//查
	router.GET("/", func(c *gin.Context) 
		id := c.Query("id")
		//可以格式化字符串
		c.String(200, "get id= %v", id)
	)

返回一个 JSON 数据

package main

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

func main() 
	//创建一个默认的路由引擎
	r := gin.Default()

	r.GET("/json", func(c *gin.Context) 
		aid := c.Query("aid")
		// 方式一:自己拼接 JSON
		c.JSON(http.StatusOK, gin.H
			"msg": aid,
		)
	)

	r.GET("/structJson", func(c *gin.Context) 
		// 结构体方式
		//通过json备注,可以指定key名
		//未导出的字段不会被序列化(小写属性名)
		var msg struct 
			Username string
			Msg      string `json:"msg"`
			Age      string `json:"age"`
		
		msg.Username = "name1"
		msg.Msg = "msg1"
		msg.Age = "18"
		c.JSON(200, msg)
	)

	//改变默认启动端口
	r.Run(":5200")

对于JSON序列化而言,在go语言中会忽略小写的属性名,并且默认key都是属性名大写的,可以通过在结构体属性名后面添加备注,指定显示的key名:


返回JSONP

package main

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

func main() 
	//创建一个默认的路由引擎
	r := gin.Default()

	r.GET("/JSONP", func(c *gin.Context) 
		data := map[string]interface
			"foo": "bar",
		
		// /JSONP?callback=x
		// 将输出:x(\\"foo\\":\\"bar\\")
		c.JSONP(http.StatusOK, data)
	)

	//改变默认启动端口
	r.Run(":5200")


JSONP跨域主要用于跨域解决,具体可参考下面这篇文章:

Golang Gin 实战(九)| JSONP跨域和劫持


渲染文件

package main

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

func main() 
	//创建一个默认的路由引擎
	r := gin.Default()

	r.GET("/", func(c *gin.Context) 
		//直接将文件内容写回显示在浏览器上
		c.File("main.go")
		//将文件以附件形式进行下载,参数是是文件路径,参数二是下载时显示的文件名
		c.FileAttachment("main.go", "神秘文件.txt")
	)

	//改变默认启动端口
	r.Run(":5200")


渲染html模板

package main

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

func main() 
	//创建一个默认的路由引擎
	r := gin.Default()
    //需要先加载模板文件
	r.LoadHTMLGlob("templates/*")

	r.GET("/", func(c *gin.Context) 
		//渲染,然后响应渲染后的模板文件
		c.HTML(
			http.StatusOK, "index.html",
			map[string]interface"title": "前台首页")
	)

	//改变默认启动端口
	r.Run(":5200")


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
 .title
</body>
</html>


Gin HTML 模板渲染

最简单的步骤就两步:

  • 加载模板文件
  • 渲染时传入模型数据,将最终渲染结果响应到浏览器
	//创建一个默认的路由引擎
	r := gin.Default()
	//template目录下面所有文件都是模板文件
	r.LoadHTMLGlob("templates/*")

	r.GET("/", func(c *gin.Context) 
		//渲染,然后响应渲染后的模板文件
		c.HTML(
			http.StatusOK, 
            //去template目录下寻找index.html模板文件
            "index.html",
			//模型数据
			map[string]interface"title": "前台首页")
	)

	//改变默认启动端口
	r.Run(":5200")

关于模板文件中的相关语法和使用,这里不展开了,如果有做单体应用需要用到模板文件支持的,可以自行查阅相关资料。


静态文件服务

当我们渲染的 HTML 文件中引用了静态文件时,我们需要配置静态 web 服务 r.Static(“/static”, “./static”) 前面的/static 表示路由 后面的./static 表示路径

	r := gin.Default()
	//将请求映射到一个静态资源目录下
	r.Static("/static", "./static")



路由详解

Get 请求传值

GET /user?uid=20&page=1

	r.GET("/user", func(c *gin.Context)  
		uid := c.Query("uid")
		//如果请求参数中没有携带page参数,则返回默认值
		page := c.DefaultQuery("page", "0") 
		c.String(200, "uid=%v page=%v", uid, page)
	)

动态路由传值

get /user/20

	r.GET("/user/:id", func(c *gin.Context) 
		id := c.Param("id")
		c.JSON(200, gin.H
			"news": id, //id 20
		)
	)

Post 请求传值 获取 form 表单数据

  • 通过 c.PostForm 接收表单传过来的数据
	r.POST("/doAddUser", func(c *gin.Context) 
		username := c.PostForm("username")
		password := c.PostForm("password")
		age := c.DefaultPostForm("age", "20")
		c.JSON(200, gin.H
			"usernmae": username, "password": password, "age": age,
		)
	)
  • postman进行数据提交


Get 传值绑定到结构体

/?username=zhangsan&password=123456

package main

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

//注意首字母大写,以及暴露给表单和json时的属性名
type Userinfo struct 
	Username string `form:"username" json:"user"`
	Password string `form:"password" json:"pwd"`


func main() 
	// 创建一个默认的路由引擎
	r := gin.Default()
	// 配置路由
	r.GET("/", func(c *gin.Context) 
		var userinfo Userinfo
		if err := c.ShouldBind(&userinfo); err == nil 
			c.JSON(http.StatusOK, userinfo)
		 else 
			c.JSON(http.StatusBadRequest, gin.H"error": err.Error())
		
	)
	r.Run()


Post 传值绑定到结构体

	r.POST("/", func(c *gin.Context) 
		var userinfo Userinfo
		if err := c.ShouldBind(&userinfo); err == nil 
			c.JSON(http.StatusOK, userinfo)
		 else 
			c.JSON(http.StatusBadRequest, gin.H"error": err.Error())
		
	)

和get数据绑定一样。


Xml数据绑定

如果请求提交的是xml形式的数据,该怎么完成数据绑定呢?

	type Article struct 
		Title   string `json:"title" xml:"title"`
		Content string `json:"content" xml:"content"`
	

	r.POST("/xml", func(ctx *gin.Context) 
		var article Article
		if err := ctx.ShouldBindXML(&article); err == nil 
			ctx.JSON(http.StatusOK, article)
		else 
			ctx.JSON(http.StatusBadRequest, gin.H 
				"err": err.Error())
		
	)

关于xml数据绑定,还有一种原始方式,如下:

	r.POST("/xml", func(ctx *gin.Context) 
		//获取请求体中原始的字节流
		data, _ := ctx.GetRawData()
		var article Article
		 //使用go官方提供的xml反序列化方式
		if err := xml.Unmarshal(data, &article); err == nil 
			ctx.JSON(http.StatusOK, article)
		 else 
			ctx.JSON(http.StatusBadRequest, gin.H
				"err": err.Error())
		
	)


还有JSON数据绑定,YML数据绑定等,都是一样的套路,这里不多展开,大家自行探索


路由分组

package main

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

func main() 
	r := gin.Default()

	userRouter := r.Group("/user")
	
		userRouter.GET("/id", func(ctx *gin.Context) 
			ctx.String(200, "getUserById")
		)

		userRouter.POST("/", func(ctx *gin.Context) 
			ctx.String(200, "post one user")
		)
	

	adminRouter := r.Group("/admin")
	
		adminRouter.GET("/id", func(ctx *gin.Context) 
			ctx.String(200, "getAdminById")
		)

		adminRouter.POST("/", func(ctx *gin.Context) 
			ctx.String(200, "post one admin")
		)
	

	r.Run()

这里的路由分组和java中spring框架在controller类上面标注@RequestMapping注解的请求域隔离功能类似


路由分离

如何将不同的路由放入不同的文件进行管理,就像spring不同的请求域由不同的controller处理类似。

  • 在项目新建文件夹router,然后在router目录下创建userRouter.go 和adminRouter.go,内容如下:
package router

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

func UserRouter(r *gin.Engine) 
	userRouter := r.Group("/user")
	
		userRouter.GET("/id", func(ctx *gin.Context) 
			ctx.String(200, "getUserById")
		)

		userRouter.POST("/", func(ctx *gin.Context) 
			ctx.String(200go-gin 框架的多级分组

gin+vue的前后端分离开源项目

❤️这应该是Postman最详细的中文使用教程了❤️(新手使用,简单明了)

gin-jwt对API进行权限控制

gin框架学习-Gin框架和Gorm框架搭建一个简单的API微服务

最新版Git(2.32.0)下载安装教程,简单明了 附带idea配置