
本文目录
- 一、使用go.work创建工作区
- 二、gin框架快速上手
-
- [2.1 简单的请求实现](#2.1 简单的请求实现)
- [2.2 URI](#2.2 URI)
- [2.3 分组路由](#2.3 分组路由)
- [2.4 Get请求参数获取](#2.4 Get请求参数获取)
- [2.5 Post请求参数](#2.5 Post请求参数)
- [2.6 响应](#2.6 响应)
一、使用go.work创建工作区
依次输入下面命令,初始化工程。
cpp
mkdir ginlearn
cd .\ginlearn\
mkdir helloworld
go work init
cd helloworld
go mod init test.com/helloworld
cd ..
go work use ./helloworld
go work 工作区是一个目录结构,它允许开发者在同一个项目中管理多个模块(go mod)。工作区的核心是一个 go.work 文件,这个文件定义了工作区中包含的模块及其依赖关系。
首先ginlearn 的目录,作为工作区的根目录。在 ginlearn 目录下创建了一个子目录 helloworld,用于存放一个模块。在当前目录(ginlearn)下初始化一个 go work 工作区,会在当前目录下生成一个 go.work 文件,该文件用于定义工作区中包含的模块。
然后进入 helloworld 目录。使用 go mod init 初始化一个 Go 模块,模块路径为 test.com/helloworld。在 helloworld 目录下生成一个 go.mod 文件,用于管理该模块的依赖。使用 go work use
命令将 helloworld 模块添加到工作区中。
工作区的作用如下:在 ginlearn 工作区中,可以直接运行 go build 或 go run,而无需进入具体的模块目录。当多个模块依赖相同的包时,go work 会自动优化依赖的下载和缓存,避免重复下载,也就是共享依赖。
二、gin框架快速上手
2.1 简单的请求实现
使用命令go get -u github.com/gin-gonic/gin
安装gin框架。
可以看到gin.go中的default返回的是一个引擎的引用。

编写下面的代码,跑起来一个简单的gin应用。
go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.GET("/hello", func(ctx *gin.Context) {
//json需要返回两个数据,一个code,一个obj any泛型,也就是任意类型
ctx.JSON(200, gin.H{
"message": "你好,这是第一个gin应用",
})
})
r.Run()
}
gin中有一个H用法,就是一个map,string是键,值可以是任意。
通过post工具可以访问到结果。

常用的请求方法有:
go
r.GET("/get", func(ctx *gin.Context) {
ctx.JSON(200, "get")
})
r.POST("/post", func(ctx *gin.Context) {
ctx.JSON(200, "post")
})
r.DELETE("/delete", func(ctx *gin.Context) {
ctx.JSON(200, "delete")
})
r.PUT("/put", func(ctx *gin.Context) {
ctx.JSON(200, "put")
})
也有支持所有的方法。
go
r.Any("/any", func(ctx *gin.Context) {
ctx.JSON(200, "any")
})
2.2 URI
路径参数可以通过下面方式进行获取。
go
r.POST("/user/find/:id", func(ctx *gin.Context) {
param := ctx.Param("id")
ctx.JSON(200, param)
})
也有对应的模糊匹配的功能。
go
r.POST("/user/*path", func(ctx *gin.Context) {
param := ctx.Param("path")
ctx.JSON(200, param)
})
实现效果如下。
2.3 分组路由
在进行开发的时候,往往需要进行模块的划分,比如用户模块,以user开发,商品模块,以goods开头。
go
ug := r.Group("/user")
{
ug.GET("find", func(ctx *gin.Context) {
ctx.JSON(200, "user find")
})
ug.POST("save", func(ctx *gin.Context) {
ctx.JSON(200, "user save")
})
}
gg := r.Group("/goods")
{
gg.GET("find", func(ctx *gin.Context) {
ctx.JSON(200, "goods find")
})
gg.POST("save", func(ctx *gin.Context) {
ctx.JSON(200, "goods save")
})
}
2.4 Get请求参数获取
当请求路径为Requet: http://localhost:8080/user/save?id=11&name=zhangsan
的时候,可以通过下面的方式获取路径参数。
go
r.GET("/user/save", func(ctx *gin.Context) {
id := ctx.Param("id")
name := ctx.Query("name")
ctx.JSON(200, gin.H{
"id": id,
"name": name,
})
})

另外可以通过GetQuery来判断参数是否存在。
go
r.GET("/user/save", func(ctx *gin.Context) {
id, ok := ctx.GetQuery("id")
address, aok := ctx.GetQuery("address")
ctx.JSON(200, gin.H{
"id": id,
"idok": ok,
"address": address,
"aok": aok,
})
})
同样的,也可以根据类型获取。
go
type User struct{
Id int64 `form:"id"`
Name string `form:"name"`
Address string `form:"address" binding:"required"`
//必填项如果某个必填字段(如 Address)没有提供,ShouldBindQuery 会返回一个错误。
}
r.GET("/user/save", func(ctx *gin.Context) {
var user User
err := ctx.ShouldBindQuery(&user)
if err != nil {
log.Println(err)
}
ctx.JSON(200, user)
})
当多个请求参数名一样的时候,需要进行数组参数获取,比如:http://localhost:8080/user/save?address=Beijing&address=shanghai
可以使用下面的代码进行获取。
go
r.GET("/user/save", func(ctx *gin.Context) {
address := ctx.QueryArray("address")
ctx.JSON(200, address)
})
go
r.GET("/user/save", func(ctx *gin.Context) {
address, ok := ctx.GetQueryArray("address")
fmt.Println(ok)
ctx.JSON(200, address)
})
如果使用结构体绑定,需要在结构体中定义对应参数是数组,比如Address []string
来定义。
go
r.GET("/user/save", func(ctx *gin.Context) {
var user User
err := ctx.ShouldBindQuery(&user)
fmt.Println(err)
ctx.JSON(200, user)
})
当请求是map参数的时候,http://localhost:8080/user/save?addressMap[home]=Beijing&addressMap[company]=shanghai
,更改为对应的QueryMap
即可。
go
r.GET("/user/save", func(ctx *gin.Context) {
addressMap := ctx.QueryMap("addressMap")
addressMap, _ := ctx.GetQueryMap("addressMap")
ctx.JSON(200, addressMap)
})
2.5 Post请求参数
Post一般是表单参数和json参数。
go
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.POST("/user/save", func(ctx *gin.Context) {
id := ctx.PostForm("id")
name := ctx.PostForm("name")
address := ctx.PostFormArray("address")
addressMap := ctx.PostFormMap("addressMap")
ctx.JSON(200, gin.H{
"id": id,
"name": name,
"address": address,
"addressMap": addressMap,
})
})
r.Run(":9091")
}

对于Json格式的Post请求,可以通过下面的方式进行获取。
go
package main
import (
"fmt"
"github.com/gin-gonic/gin"
)
type User struct {
Id int64 `json:"id"`
Name string `json:"name"`
Address []string `json:"address" binding:"required"`
AddressMap map[string]string `json:"addressMap"`
}
func main() {
r := gin.Default()
r.POST("/user/save", func(ctx *gin.Context) {
var user User
err := ctx.ShouldBindJSON(&user)
fmt.Println(err)
ctx.JSON(200, user)
})
r.Run(":9091")
}

2.6 响应
字符串响应方式:
go
r.GET("/user/save", func(ctx *gin.Context) {
ctx.String(http.StatusOK, "this is a %s", "ms string response")
})
Json响应方式:
go
r.GET("/user/save", func(ctx *gin.Context) {
ctx.JSON(http.StatusOK, gin.H{
"success": true,
})
})
文件格式响应方式:
go
r.GET("/user/save", func(ctx *gin.Context) {
//ctx.File("./1.png")
ctx.FileAttachment("./1.png", "2.png")
})
设置HTTP响应头
go
r.GET("/user/save", func(ctx *gin.Context) {
ctx.Header("test", "headertest")
})
重定向
go
r.GET("/user/save", func(ctx *gin.Context) {
ctx.Redirect(http.StatusMovedPermanently, "http://www.baidu.com")
})
YAML方式
go
r.GET("/user/save", func(ctx *gin.Context) {
ctx.YAML(200, gin.H{"name": "ms", "age": 19})
})