当前位置: 首页 > 工具软件 > GIN > 使用案例 >

gin框架基本使用

童浩言
2023-12-01

前言

在go的web项目中,gin相当于java中的springmvc、gorm相当于java中的mybatis、gomod相当于java中的maven。
gin的中文文档

gin的基本使用

1 创建项目,用于项目管理 go mod

我们新建一个文件夹,在当前文件夹下打开cmd,输入共go mod (默认项目名为文件夹名,也可以自己指定项目名)
go mod后会在当前目录下生成go.mod文件,记录项目所下载的外部依赖(这个就相当于java中maven项目中pom文件)

2 下载安装gin(前提是电脑已经安装了git)

电脑安装配置git(已安装,直接忽略)

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

gin示例

package main

import (
// 引入gin包
	"github.com/gin-gonic/gin"
)

func main() {
	// 创建一个默认的路由引擎
	r := gin.Default()
	// GET:请求方式;/hello:请求的路径
	// 当客户端以GET方法请求/hello路径时,会执行后面的匿名函数
	r.GET("/hello", func(c *gin.Context) {
		// c.JSON:返回JSON格式的数据给客户端
		c.JSON(200, gin.H{  // 状态码200 和 map类型数据
			"message": "Hello world!",
		})
	})
	// 启动HTTP服务,默认在0.0.0.0:8080启动服务
	r.Run()
}

将上面的代码保存并编译执行,然后使用浏览器打开localhost:8080/hello就能看到一串JSON字符串"message": “Hello world!”。

Gin支持RESTful API的开发

func main() {
	r := gin.Default()
	r.GET("/hello", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "GET",
		})
	})

	r.POST("/hello", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "POST",
		})
	})

	r.PUT("/hello", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "PUT",
		})
	})

	r.DELETE("/hello", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"message": "DELETE",
		})
	})
}

3 Gin渲染(返回给前端的数据)

3.1 返回html

我们在项目中新建文件夹static,用于保存静态资源
然后把我们自定义的html文件放在static文件夹下(我这里叫hello.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>66666666666666666</h1>
</body>
</html>

Gin框架中使用LoadHTMLGlob()或者LoadHTMLFiles()方法进行HTML模板渲染。

func main() {
	// 加载默认引擎
	r := gin.Default()
	// 访问static下的所有文件
	r.LoadHTMLGlob("static/*")
	// 访问static下的单个文件
	//r.LoadHTMLFiles("static/hello.html")
	r.GET("/hello", func(c *gin.Context) {
	// 把hello.html返回给前端,并附带title信息
		c.HTML(http.StatusOK, "hello.html", gin.H{
			"title": "hello",
		})
	})
	// 运行在本机8080端口
	r.Run(":8080")
}

打开浏览器访问localhost:8080/hello,就可以看到html了

3.2 加载静态资源

如果我们的html文件有引入外部静态资源的请求,就需要用到Static函数了
例如

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    // 引入css文件 请求为“/css/index.css”
	<link rel="stylesheet" href="/css/index.css">
</head>
<body>
    <h1>66666666666666666</h1>
</body>
</html>

我们需要在static目录下新建css文件index.css

修改go文件

func main() {
	// 加载默认引擎
	r := gin.Default()
	// 加载静态文件  (接收/css请求,让请求去static目录下找index.css文件)
	r.Static("/css","./static")
	// 访问static下的所有文件
	r.LoadHTMLGlob("static/*")
	// 访问static下的单个文件
	//r.LoadHTMLFiles("static/hello.html")
	r.GET("/hello", func(c *gin.Context) {
	// 把hello.html返回给前端,并附带title信息
		c.HTML(http.StatusOK, "hello.html", gin.H{
			"title": "hello",
		})
	})
	// 运行在本机8080端口
	r.Run(":8080")
}

浏览器访问,然后我们就可以看到带有css样式的html页面了

3.3 返回json格式数据

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

	// gin.H 是map[string]interface{}的缩写 map键是string格式,值是任意格式
	r.GET("/someJSON", func(c *gin.Context) {
		// 方式一:自己拼接JSON
		c.JSON(http.StatusOK, gin.H{"message": "Hello world!"})
	})
	r.GET("/moreJSON", func(c *gin.Context) {
		// 方法二:使用结构体
		var msg struct {
			Name    string `json:"user"` //使用标签 返回的数据Name修改为user
			Message string
			Age     int
		}
		msg.Name = "小王"
		msg.Message = "Hello world!"
		msg.Age = 18
		c.JSON(http.StatusOK, msg)
	})
	r.Run(":8080")
}

打开浏览器访问就可以看到{ “user”:“小王”,“Message”:“Hello world!”,“Age”:18}

4 获取请求参数

4.1 获取path参数

请求的参数通过URL路径传递,例如:/user/search/王/shanghai。 获取请求URL路径中的参数的方式如下。

func main() {
	//Default返回一个默认的路由引擎
	r := gin.Default()
	r.GET("/user/search/:username/:address", func(c *gin.Context) {
		username := c.Param("username")
		address := c.Param("address")
		//输出json结果给调用方
		c.JSON(http.StatusOK, gin.H{
			"message":  "ok",
			"username": username,
			"address":  address,
		})
	})

	r.Run(":8080")
}

4.2 ShouldBind()参数绑定,获取json,form,路径参数

为了能够更方便的获取请求相关参数,提高开发效率,gin基于请求的Content-Type识别请求数据类型并利用反射机制自动提取请求中QueryString、form表单、JSON、XML等参数到结构体中。.ShouldBind()能够基于请求自动提取JSON、form表单和QueryString类型的数据,并把值绑定到指定的结构体对象。


type Login struct {
	// 使用标签  如果是form请求,把User改为user,json请求改为user,是否必须
	User     string `form:"user" json:"user" binding:"required"`
	Password string `form:"password" json:"password" binding:"required"`
}

func main() {
	router := gin.Default()

	// 绑定JSON的示例 ({"user": "go", "pass": "123456"})
	router.POST("/loginJSON", func(c *gin.Context) {
		var login Login

		if err := c.ShouldBind(&login); err == nil {
			fmt.Printf("login info:%#v\n", login)
			c.JSON(http.StatusOK, gin.H{
				"user":     login.User,
				"pass": login.Password,
			})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	// 绑定form表单示例 (user=go&pass=123456)
	router.POST("/loginForm", func(c *gin.Context) {
		var login Login
		// ShouldBind()会根据请求的Content-Type自行选择绑定器
		if err := c.ShouldBind(&login); err == nil {
			c.JSON(http.StatusOK, gin.H{
				"user":     login.User,
				"pass": login.Password,
			})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	// 绑定QueryString示例 (/login?user=go&pass=123456)
	router.GET("/loginForm", func(c *gin.Context) {
		var login Login
		// ShouldBind()会根据请求的Content-Type自行选择绑定器
		if err := c.ShouldBind(&login); err == nil {
			c.JSON(http.StatusOK, gin.H{
				"user":     login.User,
				"pass": login.Password,
			})
		} else {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		}
	})

	router.Run(":8080")
}

ShouldBind会按照下面的顺序解析请求中的数据完成绑定:

  1. 如果是 GET 请求,只使用 Form 绑定引擎(query)。
  2. 如果是 POST 请求,首先检查 content-type 是否为 JSON 或 XML,然后再使用 Form(form-data)。

5 重定向

5.1 http重定向

r.GET("/test", func(c *gin.Context) {
	c.Redirect(http.StatusMovedPermanently, "http://www.三体.com/")
})

5.2 路由重定向

r.GET("/hello", func(c *gin.Context) {
    // 指定重定向的URL
    c.Request.URL.Path = "/hello2"
    r.HandleContext(c)
})
r.GET("/hello2", func(c *gin.Context) {
    c.JSON(http.StatusOK, gin.H{"hello": "world"})
})

5.3 gin路由

普通路由

r.GET("/index", func(c *gin.Context) {...})
r.GET("/login", func(c *gin.Context) {...})
r.POST("/login", func(c *gin.Context) {...})

一个可以匹配所有请求方法的Any方法如下:

r.Any("/test", func(c *gin.Context) {...})

为没有配置处理函数的路由添加处理程序,默认情况下它返回404代码,下面的代码为没有匹配到路由的请求都返回404.html页面。

r.NoRoute(func(c *gin.Context) {
		c.HTML(http.StatusNotFound, "404.html", nil)
	})

路由组

我们可以将拥有共同URL前缀的路由划分为一个路由组。习惯性一对{}包裹同组的路由,

func main() {
	r := gin.Default()
	userGroup := r.Group("/user")
	{
		userGroup.GET("/index", func(c *gin.Context) {...})
		userGroup.GET("/login", func(c *gin.Context) {...})
		userGroup.POST("/login", func(c *gin.Context) {...})

	}
	shopGroup := r.Group("/shop")
	{
		shopGroup.GET("/index", func(c *gin.Context) {...})
		shopGroup.GET("/cart", func(c *gin.Context) {...})
		shopGroup.POST("/checkout", func(c *gin.Context) {...})
	}
	r.Run()
}
 类似资料: