目录
一、Gin 介绍
二、Gin 环境搭建
三、Gin 框架中的路由
四、Gin中HTML 模板渲染
五、静态文件服务
六、路由详解
Gin 是一个 Go (Golang) 编写的轻量级 http web 框架,运行速度非常快,如果你是新手或者完成一些项目规模不大,可以考虑使用gin框架,它最擅长api接口高并发,如果有其他需求,还可以考虑使用gin重写接口,截止目前,gin的GitHub收藏量已经破67.9k 。
要使用gin框架,首先要安装gin,https://gin-gonic.com/zh-cn/docs/,这是gin的官方介绍文档,若碰到什么问题可以去里面寻找答案。
1、下载并安装 gin:
首先在终端(确保你已经正确配置好go的环境或者使用go mod init 项目名初始化项目)输入:
go get -u github.com/gin-gonic/gin
就可以远程拉取gin,如果拉取失败可以输入:
go env -w GOPROXY=https://goproxy.cn,direct
设置国内七牛云代理,也可以设置阿里云等其他,direct最好加上,他表示如果国内代理没有找到相应的包就可以直接去原来地址拉取。
2、简单导入并使用gin
下载完gin就可以导入到项目并使用了,导入gin使用:
import "github.com/gin-gonic/gin"
一般来说编译器会自动识别并加载,若出现报错可以先初始化项目,使用go mod init 项目名,若还是报错,则使用 go mod tidy自动整理导入包。
如果使用诸如 http.StatusOK 之类的常量,当然你也可以用直接200或401等,若要规范则需要引入 net/http 包:
import "net/http"
在项目目录下新建main.go文件,它是整个项目运行的入口,同时配置路由:
package main //一个项目只能有一个mian包
improt(
"github.com/gin-gonic/gin" //若导入多个包可以用()
)
func main(){
// 创建一个默认的路由引擎
route=gin.Default()
//配置路由
route.GET("/",func(ctx *gin.Context) {
//向浏览器返回JSON格式的数据,gin自带JSON序列化器,不用像就Java等要导入
ctx.JSON(200,gin.H{
"message": "入生苦短,我用golang!",
})
})
//启动HTTP服务,默认8080端口
route.Run()
//若要改变端口,使用 route.Run(":8081"),不要漏了前面:
}
运行项目使用命令
go run mian.go
1、路由
路由是由一个URI(或者说路径)和一个特定的HTTP方法(GET、POST等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。
gin框架支持目前在Web开发中较为成熟和广泛使用的restful API,在restful架构中,不同的请求方式表示执行不同的操作,简化了增删改查的请求,四种请求方式如下:
GET请求: 向服务器获取资源(一项或多项)一般用于查询
POST请求: 向服务器发送资源 一般用于新增
PUT 请求 在服务器更新资源 一般用于更新
DELETE请求 在服务器删除资源 一般用于删除
下面简单为这几个请求举个例子,可以使用postman或apifox进行测试
//GET请求方式 route.GET("请求路径",func(ctx *gin.Context){ ctx.String(200,"GET请求方式") }) //POST请求方式 route.POST("请求路径",func(ctx *gin.Context){ ctx.String(200,"POST请求方式") }) //PUT请求方式 route.POST("请求路径",func(ctx *gin.Context){ ctx.String(200,:"PUT请求方式") }) //PUT请求方式 route.POST("请求路径",func(ctx *gin.Context){ ctx.String(200,:"PUT请求方式") })
若想从GET请求路径中获取参数值,如想得到localhost:8080/user?name=zhangsan 中的name值,可以:
route.GET("/user",func(ctx *gin.Context){
name:=ctx.Query("name")
ctx.String(200,"name=%s",name)
})
若获取动态路由中的参数,如/user/zhangsan
//name的值由浏览器输入,可变化 route.GET("/user/:name",func(ctx *gin.Context){ name:=c.Param("name") ctx.String(200,"name=%s",name) })
2、响应格式
gin支持向浏览器响应不同的格式,有String,JSON,JSOPN,XMLHTML等,下面具体距离
①返回一个字符串
route:=gin.Default()
route.GET("/user",func(ctx *gin.Context) {
name:=ctx.Query("name")
ctx.String(200,"name=%s",name)
})
②返回一个JSON数据
//方式一:自己拼接JSON
route.GET("/userJSON",func(ctx *gin.Context) {
//gin.H可以看成map[string]interface{},interface{} 可以代表任意类型
ctx.JSON(200,gin.H{"msg":"hello,gin!"})
})
//方式二:定义一个结构体封装数据
route.GET("/userJSON",func(ctx *gin.Context) {
var msg struct{
Name string `json:"user"`//`json:""`是struct tag,可以去搜一下用法
Message string
Age int
}
msg.Name="gin"
msg.Message="hello world!"
msg.Age=20
ctx.JSON(http.StatusOK,msg)
})
route.Run()
③ JSOPN
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(":8080")
}
④返回XML数据
func main() {
route := gin.Default()
// gin.H 是 map[string]interface{}的缩写
route.GET("/someXML", func(ctx *gin.Context) {
// 方式一:自己拼接 JSON
ctx.XML(http.StatusOK, gin.H{"message": "Hello world!"})
})
route.GET("/moreXML", func(ctx *gin.Context) {
// 方法二:使用结构体
type MessageRecord struct {
Name string
Message string
Age int
}
var msg MessageRecord
msg.Name = "gin"
msg.Message = "Hello world!"
msg.Age = 18
ctx.XML(http.StatusOK, msg)
})
route.Run(":8080")
}
⑤HTML,指定html页面,可用于渲染模板
router.GET("/", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "user/index.html", map[string]interface{}{
"title": "前台首页,替换html中{title}"
})
})
1、html文件在同一个目录
首先在项目根目录新建 templates 文件夹,然后在文件夹中新建 index.htm,参考代码如下:
Document
html 模板
{{.title}}
使用 ctx.HTML 可以渲染模板,渲染模板前需要使用 LoadHTMLGlob()或者 LoadHTMLFiles()方法加载模板。
router.GET("/", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "templates/index.html", map[string]interface{}{
"title": "前台首页"
})
})
router.GET("/", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "index.html", gin.H{
"title": "this is gin",
})
})
多个html文件在同一文件在,在templates文件目录下创建template1.html和template2.html
package main
import ( "net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/*")
//router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
router.GET("/", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "index.html", gin.H{
"title": "this is gin",
})
})
router.Run(":8080")
}
2、html在不同目录下
在templates新建两个文件夹default和admin,在default和admin分别新建index.html文件,
{{ define "admin/index.html" }}
Document
后台模板
{{.title}}
{{ end }}
其中 define和end是成对出现,相当于是给模板定义了一个名字
{{ define "default/index.html" }}
Document
前台模板
{{.title}}
{{end}}
在mian.go中实现不同文件目录的html渲染
package main
import ( "net/http"
"github.com/gin-gonic/gin"
)
func main() {
router := gin.Default()
router.LoadHTMLGlob("templates/**/*")
router.GET("/", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "default/index.html", gin.H{
"title": "前台首页",
})
})
router.GET("/admin", func(ctx *gin.Context) {
ctx.HTML(http.StatusOK, "admin/index.html", gin.H{
"title": "后台首页",
})
})
router.Run(":8080")
}
当我们渲染的 HTML 文件中引用了静态文件时,我们需要配置静态 web 服务 route.Static("/static", "./static") 前面的/static 表示路由 后面的./static 表示路径:
func main() {
route := gin.Default()
route.Static("/static", "./static")
route.LoadHTMLGlob("templates/**/*")
// ... route.Run(":8080")
}
路由(Routing)是一个URI(或者叫路径)和一个特定的HTTP方法(GET、POST等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。
1、GET请求传值
GET /user?uid=20&page=1
router.GET("/user", func(ctx *gin.Context) {
uid := ctx.Query("uid")
page := ctx.DefaultQuery("page", "0")
ctx.String(200, "uid=%v page=%v", uid, page)
})