Gin框架快速入门
Posted Baret-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gin框架快速入门相关的知识,希望对你有一定的参考价值。
参考学习教程:
目录
一. 基本介绍
Gin
是一个用Go语言编写的web框架。它是一个类似于martini
但拥有更好性能的API框架, 由于使用了httprouter
,速度提高了近40倍。如果你需要极好的性能,使用 Gin 吧
二. 安装与使用
首先通过
go mod init 包名
命令创建一个go模块作为项目环境,然后进行后序操作
1、下载并安装 gin:
go get -u github.com/gin-gonic/gin
2、将 gin 引入到代码中:
import "github.com/gin-gonic/gin"
3、编写第一个gin实例:
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
// 创建一个默认的路由引擎
r := gin.Default()
// 当客户端通过get方式请求/hello时,会执行后面的匿名函数
r.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello Gin",
})
})
// 启动http服务,默认在8080端口
r.Run()
}
4、利用postman进行测试
5、使用Restful API示例
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
// 创建一个默认的路由引擎
r := gin.Default()
// 当客户端通过get方式请求/hello时,会执行后面的匿名函数
r.GET("/hello", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "Hello Gin",
})
})
r.GET("/book", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "GET",
})
})
r.POST("/book", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "POST",
})
})
r.PUT("/book", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "PUT",
})
})
r.DELETE("/book", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "DELETE",
})
})
// 启动http服务,默认在8080端口
r.Run()
}
然后利用postman进行测试,采用不同的请求方式,请求同样的路径/book,会返回不同结果
ps:浏览器默认只支持get/post请求,如果想要发put/delete请求,需要通过ajax来进行。因此这里推荐使用postman测试
三. Gin渲染
html渲染
1️⃣ 模板定义
首先创建一个存放模板文件的templates
文件夹,然后在其内部按照业务分别定义一个post
文件夹和一个user
文件夹,分别编写对应的index.html
模板文件
post/index.html
文件的内容如下:
{{define "post/index.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<title>post/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
user/index.html
文件的内容如下:
{{define "user/index.html"}}
<!DOCTYPE html>
<html lang="en">
<head>
<title>user/index</title>
</head>
<body>
{{.title}}
</body>
</html>
{{end}}
2️⃣ 模板解析&渲染
创建main.go
编写http server代码并进行html模板解析渲染,可以使用LoadHTMLGlob()
或者LoadHTMLFiles()
两种方法进行HTML模板渲染
package main
import (
"github.com/gin-gonic/gin"
"net/http"
)
func main() {
//创建默认的路由引擎
r := gin.Default()
//模板解析
// r.LoadHTMLFiles("./template/user/index.html", "./template/post/index.html")
r.LoadHTMLGlob("./template/**/*")
//以get方式发/post/index请求
r.GET("/post/index", func(c *gin.Context) {
//模板渲染
c.HTML(http.StatusOK, "post/index.html", gin.H{"title": "this is post/index.html"})
})
//以get方式发/user/index请求
r.GET("user/index", func(c *gin.Context) {
//模板渲染
c.HTML(http.StatusOK, "user/index.html", gin.H{"title": "this is user/index.html"})
})
//启动http服务在9090端口
r.Run(":9090")
}
3️⃣ postman测试
分别测试/user/index
和/post/index
查看结果
自定义模板函数
如果我们想传参<a href='https://bareth.blog.csdn.net/'>BaretH的博客</a>
,但是不希望自动转义成字符串,此时就可以自定义一个模板函数进行相应的处理,注意自定义函数的添加要在模板解析之前
package main
import (
"html/template"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
//创建默认的路由引擎
r := gin.Default()
//自定义函数safe
r.SetFuncMap(template.FuncMap{
"safe": func(str string) template.HTML {
return template.HTML(str)
},
})
//模板解析
r.LoadHTMLFiles("./index.html")
//以get方式发/post/index请求
r.GET("/index", func(c *gin.Context) {
//模板渲染
c.HTML(http.StatusOK, "index.html", "<a href='https://bareth.blog.csdn.net/'>BaretH的博客</a>")
})
//启动http服务在9090端口
r.Run(":9090")
}
这里定义了模板函数safe
,然后在模板文件中进行使用
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>自定义函数</title>
</head>
<body>
<div>{{ . | safe }}</div>
</body>
</html>
最后测试:
静态文件处理
当我们渲染的HTML文件中引用了静态文件时,我们只需要按照以下方式在渲染页面前调用gin.Static
方法即可
这里创建static
目录,然后新建index.css
body {
background-color: burlywood;
}
然后添加gin.Static
方法,该方法有两个参数,第一个为在html文件中引用的目录,第二个参数为实际的静态文件存放目录
package main
import (
"html/template"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
//创建默认的路由引擎
r := gin.Default()
//加载静态文件
r.Static("/xxx", "./statics")
//自定义函数safe
r.SetFuncMap(template.FuncMap{
"safe": func(str string) template.HTML {
return template.HTML(str)
},
})
//模板解析
r.LoadHTMLFiles("./index.html")
//以get方式发/post/index请求
r.GET("/index", func(c *gin.Context) {
//模板渲染
c.HTML(http.StatusOK, "index.html", "<a href='https://bareth.blog.csdn.net/'>BaretH的博客</a>")
})
//启动http服务在9090端口
r.Run(":9090")
}
然后在index.html
文件中引用css文件
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title>自定义函数</title>
<link href="/xxx/index.css"></link>
</head>
<body>
<div>{{ . | safe }}</div>
</body>
</html>
测试可以看到生效:
json渲染
目前主流的we开发方式有两种,一种是浏览器请求服务器,服务器返回完整的html页面内容;第二种就是通过前端框架如vue、react定义好一些模板文件,后端程序只需要返回给前端json格式数据,前端拿到json数据后自行渲染。那么在Gin框架中如何返回json格式数据呢?
在Go语言中,json格式数据可以以两种方式表示:map
和struct
,接下来我们模拟json数据,然后请求访问并返回
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
//模拟json数据
//方式一:map
user1 := gin.H{
"name": "zsr",
"age": 21,
"sex": "男",
}
//方式二:struct
type User struct {
Name string
Age int
Sex string
}
user2 := User{
"gcc",
21,
"女",
}
r.GET("/user1", func(c *gin.Context) {
c.JSON(http.StatusOK, user1)
})
r.GET("/user2", func(c *gin.Context) {
c.JSON(http.StatusOK, user2)
})
r.Run(":9090")
}
其中gin.H
本质上就是一个map
// H is a shortcut for map[string]interface{}
type H map[string]interface{}
测试结果:
注意这里的c.JSON
本质上就是json数据的序列化,默认就是通过Go语言中json包使用反射机制读取数据的,而在Go语言中,首字母小写表示是不可导出的,因此结构体中字段首字母要大写,让json包读取到结构体中的字段,那如过就想要结构体中字段的首字母小写呢?我们可以通过结构体tag来解决,给结构体字段做一些自定制操作
例如下述Name字段后加的json:name
表示当使用json包操作Name字段时,名字为小写的name
type User struct {
Name string `json:"name"`
Age int
Sex string
}
四. 获取参数
获取querystring参数
querystring指的是URL中?
后面携带的参数,是键值对的形式,例如:localhost:8080?name=zsr&age=21
我们可以通过c.DefaultQuery
(可指定默认值获取不到就返回默认值)、c.Query
(获取不到返回空)、c.GetQuery
(有两个返回值,一个是获取的值,一个是bool类型的表示是否获取成功)三种方法来获取:
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.GET("/hello", func(c *gin.Context) {
name := c.DefaultQuery("name", "用户名")
age := c.Query("age")
c.JSON(http.StatusOK, gin.H{
"name": name,
"age": age,
})
})
r.Run(":9090")
}
然后我们发起一个请求测试,可以看到成功返回请求参数
如果不传name和adreess参数,则返回指定的默认值
获取form表单参数
当前端请求的数据通过form表单提交时,如何获取数据呢?以下是一个小案例
首先是登录页login.html
,其中包含form表单有两个待提交参数username
和password
,提交时发起/home
请求
<!DOCTYPE html>
<html lang="en">
<head>
<title>login</title>
</head>
<body>
<form action="/home" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit" value="登录">
</form>
</body>
</html>
然后是主页home.html
,接收显示参数username
和password
<!DOCTYPE html>
<html lang="en">
<head>
<title>login</title>
</head>
<body>
<h1>您的用户名为:{{.username}}</h1>
<h1>您的密码为:{{.password}}</h1>
</body>
</html>
最后是main.go
package main
import (
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
r.LoadHTMLFiles("./login.html", "./home.html")
//处理/login的get请求
r.GET("/login", func(c *gin.Context) {
c.HTML(http.StatusOK, "login.html", nil)
})
//处理/home的post请求
r.POST("/home", func(c *gin.Context) {
//获取表单提交的数据
username := c.PostForm("username")
password := c.PostForm("password")
c.HTML(http.StatusOK, "home.html", gin.H{
"username": username,
"password": password,
})
})
r.Run(":9090")
}
其中获取参数时同样还有以下写法
//包含默认值
username := c.DefaultPostForm("username", "未知用户名")
password := c.DefaultPostForm("password", "未知密码")
//包含是否获取到结果的bool值
username, nameOk := c.GetPostForm("username")
if !nameOk {
username = "未知用户名"
}
password, pwdOk := c.GetPostForm("password")
if !pwdOk {
password = "未知密码"
}
访问测试:首先访问localhost:9090/login
,填写用户名和密码
点击登录,然后就会跳转到home.html
获取path参数
请求的参数通过URL路径传递,例如:/user/zsr/18
; 获取请求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")
}
测试访问:localhost:9090/user/zsr/18
注意:匹配的url不要冲突,比如现在新增以下请求处理,则会报错,因为路径冲突
r.GET("/user/:year/:month", func(c *gin.Context) 以上是关于Gin框架快速入门的主要内容,如果未能解决你的问题,请参考以下文章