gin 请求
请求参数 查询参数 Query func _query(c *gin.Context) { fmt.Println(c.Query("user")) fmt.Println(c.GetQu
gin 请求
发布时间:2023-10-11 (2023-10-11)

请求参数

查询参数 Query

func _query(c *gin.Context) {
  fmt.Println(c.Query("user"))
  fmt.Println(c.GetQuery("user"))
  fmt.Println(c.QueryArray("user")) // 拿到多个相同的查询参数
  fmt.Println(c.DefaultQuery("addr", "四川省"))
}

动态参数 Param

func _param(c *gin.Context) {
  fmt.Println(c.Param("user_id"))
  fmt.Println(c.Param("book_id"))
}


router.GET("/param/:user_id/", _param)
router.GET("/param/:user_id/:book_id", _param)

// ?param/12
// ?param/12/123

表单 PostForm

可以接收 multipart/form-data; application/x-www-form-urlencoded

func _form(c *gin.Context) {
  fmt.Println(c.PostForm("name"))
  fmt.Println(c.PostFormArray("name"))
  fmt.Println(c.DefaultPostForm("addr", "四川省")) // 如果用户没传,就使用默认值
  forms, err := c.MultipartForm()               // 接收所有的form参数,包括文件
  fmt.Println(forms, err)
}

原始参数 GetRawData

form-data


----------------------------638149124879484626406689
Content-Disposition: form-data; name="name"

枫枫
----------------------------638149124879484626406689
Content-Disposition: form-data; name="name"

zhangsan
----------------------------638149124879484626406689
Content-Disposition: form-data; name="addr"

长沙市
----------------------------638149124879484626406689--

x-www-form-urlencoded

name=abc&age=23

json

{
    "name": "枫枫",
    "age": 21
}
func _raw(c *gin.Context) {
  body, _ := c.GetRawData()
  contentType := c.GetHeader("Content-Type")
  switch contentType {
  case "application/json":
  
    // json解析到结构体
    type User struct {
      Name string `json:"name"`
      Age  int    `json:"age"`
    }
    var user User
    err := json.Unmarshal(body, &user)
    if err != nil {
      fmt.Println(err.Error())
    }
    fmt.Println(user)
  }
}

封装一个解析json到结构体上的函数

func bindJson(c *gin.Context, obj any) (err error) {
  body, _ := c.GetRawData()
  contentType := c.GetHeader("Content-Type")
  switch contentType {
  case "application/json":
    err = json.Unmarshal(body, &obj)
    if err != nil {
      fmt.Println(err.Error())
      return err
    }
  }
  return nil
}

四大请求方式

GET POST PUT DELETE

Restful风格指的是网络应用中就是资源定位和资源操作的风格。不是标准也不是协议。

GET:从服务器取出资源(一项或多项)

POST:在服务器新建一个资源

PUT:在服务器更新资源(客户端提供完整资源数据)

PATCH:在服务器更新资源(客户端提供需要修改的资源数据)

DELETE:从服务器删除资源

// 以文字资源为例

// GET    /articles          文章列表
// GET    /articles/:id      文章详情
// POST   /articles          添加文章
// PUT    /articles/:id      修改某一篇文章
// DELETE /articles/:id      删除某一篇文章
package main

import (
  "encoding/json"
  "fmt"
  "github.com/gin-gonic/gin"
)

type ArticleModel struct {
  Title   string `json:"title"`
  Content string `json:"content"`
}

type Response struct {
  Code int    `json:"code"`
  Data any    `json:"data"`
  Msg  string `json:"msg"`
}

func _bindJson(c *gin.Context, obj any) (err error) {
  body, _ := c.GetRawData()
  contentType := c.GetHeader("Content-Type")
  switch contentType {
  case "application/json":
    err = json.Unmarshal(body, &obj)
    if err != nil {
      fmt.Println(err.Error())
      return err
    }
  }
  return nil
}

// _getList 文章列表页面
func _getList(c *gin.Context) {
  // 包含搜索,分页
  articleList := []ArticleModel{
    {"Go语言入门", "这篇文章是《Go语言入门》"},
    {"python语言入门", "这篇文章是《python语言入门》"},
    {"JavaScript语言入门", "这篇文章是《JavaScript语言入门》"},
  }
  c.JSON(200, Response{0, articleList, "成功"})
}

// _getDetail 文章详情
func _getDetail(c *gin.Context) {
  // 获取param中的id
  fmt.Println(c.Param("id"))
  article := ArticleModel{
    "Go语言入门", "这篇文章是《Go语言入门》",
  }
  c.JSON(200, Response{0, article, "成功"})
}

// _create 创建文章
func _create(c *gin.Context) {
  // 接收前端传递来的json数据
  var article ArticleModel

  err := _bindJson(c, &article)
  if err != nil {
    fmt.Println(err)
    return
  }

  c.JSON(200, Response{0, article, "添加成功"})
}

// _update 编辑文章
func _update(c *gin.Context) {
  fmt.Println(c.Param("id"))
  var article ArticleModel
  err := _bindJson(c, &article)
  if err != nil {
    fmt.Println(err)
    return
  }
  c.JSON(200, Response{0, article, "修改成功"})
}

// _delete 删除文章
func _delete(c *gin.Context) {
  fmt.Println(c.Param("id"))
  c.JSON(200, Response{0, map[string]string{}, "删除成功"})
}

func main() {
  router := gin.Default()
  router.GET("/articles", _getList)       // 文章列表
  router.GET("/articles/:id", _getDetail) // 文章详情
  router.POST("/articles", _create)       // 添加文章
  router.PUT("/articles/:id", _update)    // 编辑文章
  router.DELETE("/articles/:id", _delete) // 删除文章
  router.Run(":80")
}

请求头相关

请求头参数获取

GetHeader,可以大小写不分,且返回切片中的第一个数据

router.GET("/", func(c *gin.Context) {
  // 首字母大小写不区分  单词与单词之间用 - 连接
  // 用于获取一个请求头
  fmt.Println(c.GetHeader("User-Agent"))
  //fmt.Println(c.GetHeader("user-agent"))
  //fmt.Println(c.GetHeader("user-Agent"))
  //fmt.Println(c.GetHeader("user-AGent"))

  // Header 是一个普通的 map[string][]string
  fmt.Println(c.Request.Header)
  // 如果是使用 Get方法或者是 .GetHeader,那么可以不用区分大小写,并且返回第一个value
  fmt.Println(c.Request.Header.Get("User-Agent"))
  fmt.Println(c.Request.Header["User-Agent"])
  // 如果是用map的取值方式,请注意大小写问题
  fmt.Println(c.Request.Header["user-agent"])

  // 自定义的请求头,用Get方法也是免大小写
  fmt.Println(c.Request.Header.Get("Token"))
  fmt.Println(c.Request.Header.Get("token"))
  c.JSON(200, gin.H{"msg": "成功"})
})

响应头相关

设置响应头

// 设置响应头
router.GET("/res", func(c *gin.Context) {
  c.Header("Token", "jhgeu%hsg845jUIF83jh")
  c.Header("Content-Type", "application/text; charset=utf-8")
  c.JSON(0, gin.H{"data": "看看响应头"})
})