gin中的路由
- 一. gin.Context.Params URL路径参数获取
- 二. URL 传参获取
- 三. 表单参数
- 四. 文件上传
- 五. 接收请求头
-
- 使用c.Request.Header方法
- 使用c.GetHeader方法
一. gin.Context.Params URL路径参数获取
- 在gin中所有跟请求相关的数据都包装在了gin.Context结构中(这里先简单看一下Context,后面有专门文档讲解)
type Context struct {
writermem responseWriter
Request *http.Request
Writer ResponseWriter
Params Params
handlers HandlersChain
index int8
fullPath string
engine *Engine
params *Params
skippedNodes *[]skippedNode
mu sync.RWMutex
Keys map[string]interface{}
Errors errorMsgs
Accepted []string
queryCache url.Values
formCache url.Values
sameSite http.SameSite
}
- gin.Context,内部有一个Params字段,该字段是一个Param结构的切片,内部保存了url参数,并且Context中还提供了一个Param(“key”)方法,可以根据指定key获取对应的value
type Params []Param
func (c *Context) Param(key string) string {
return c.Params.ByName(key)
}
type Param struct {
Key string
Value string
}
- 示例:
- 注册路由时,url路径上使用"/:路径key"指定路径key
- 在处理器接口中获取到Context下的Params属性,根据该属性获取指定值
package moduleRoute
import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"
)
func CreateRouter() *gin.Engine {
router := gin.Default()
router.GET("/getUrl/:year/:day", GetUrlFunc)
return router
}
func GetUrlFunc(c *gin.Context) {
var params gin.Params = c.Params
for _, item := range params {
fmt.Println(item.Key)
fmt.Println(item.Value)
}
year := c.Param("year")
day := c.Param("day")
str := fmt.Sprintf("year:%v day:%v", year, day)
c.String(http.StatusOK, str)
}
二. URL 传参获取
- 例如发送请求":8080/getUrl?key1=数据1&key2=数据2",获取key1,key2的值
router.GET("/getUrlKey", GetUrlKey)
func GetUrlKey(c *gin.Context) {
c.Request.URL.Query().Get("name")
name:= c.DefaultQuery("name", "默认值")
c.String(http.StatusOK, fmt.Sprintf("name %s", name))
}
三. 表单参数
- http的报⽂体传输数据就⽐query string稍微复杂⼀点,常⻅的格式就有四种,application/json , application/x-www-form-urlencoded , application/xml 和multipart/form-data 。后⾯⼀个主要⽤于图⽚上传。json格式的很好理解,urlencode其实也不难,⽆⾮就是把query string的内容,放到了body体⾥,同样也需要urlencode。默认情况下,c.PostFROM解析的是 x-www-form-urlencoded 或 from-data 的参数
- 接收请求接口
router.POST("/postFormVal", FormFunc)
func FormFunc(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
type1 := c.DefaultPostForm("type", "alert")
hobbys := c.PostFormArray("hobby")
c.String(http.StatusOK, fmt.Sprintf("type is %s, username is %s,passwordis % s, hobbyis % v", type1, username, password, hobbys))
}
四. 文件上传
- multipart/form-data 转⽤于⽂件上传。gin⽂件上传也很⽅便,和原⽣的net/http⽅法类似,不同是gin把原⽣的request封装到c.Request中
- 单个文件上传示例
func multipartFunc(c *gin.Context) {
file, _ := c.FormFile("file")
log.Println(file.Filename)
c.SaveUploadedFile(file, file.Filename)
c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
}
- 注意点: 使⽤ c.Request.FormFile 解析客户端⽂件name属性。如果不传⽂件,则会抛错,因此需要处理这个错误。此处我们略写了错误处理。⼀种是直接⽤c.SaveUploadedFile()保存⽂件。另⼀种⽅式是使⽤os的操作,把⽂件数据复制到硬盘上
- 上传多个文件(与单个文件不同是一次拿到多个,然后遍历上传)
func MultipartFuncs(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("get form err: %s", err.Error()))
return
}
files := form.File["files"]
for _, file := range files {
if err := c.SaveUploadedFile(file, file.Filename); err != nil {
c.String(http.StatusBadRequest, fmt.Sprintf("upload file err:%s", err.Error()))
return
}
}
c.String(http.StatusOK, fmt.Sprintf("Uploaded successfully %d files ",
len(files)))
}
五. 接收请求头
- 有以下三种方式获取请求头
- c.Request.Header
- c.GetHeader
- c.ShouldBindHeader使用绑定器
使用c.Request.Header方法
- c.Request.Header方法是一种获取请求头的方式,它可以返回一个map[string][]string类型的对象,包含了所有的请求头键值对。我们可以通过指定请求头的名称,获取对应的值
func main() {
r := gin.Default()
r.GET("/auth", func(c *gin.Context) {
token := c.Request.Header["Token"][0]
if token == "secret" {
c.String(200, "authorized")
} else {
c.String(401, "unauthorized")
}
})
r.Run(":8080")
}
使用c.GetHeader方法
- c.GetHeader方法是另一种获取请求头的方式,它可以直接返回一个字符串类型的值,表示指定的请求头的值。如果请求头不存在或为空,它会返回一个空字符串。
func main() {
r := gin.Default()
r.GET("/auth", func(c *gin.Context) {
token := c.GetHeader("Token")
if token == "secret" {
c.String(200, "authorized")
} else {
c.String(401, "unauthorized")
}
})
r.Run(":8080")
}