Gin框架学习(中)-请求 | 青训营

35 阅读4分钟

青训营笔记阅读笔记第七天 -- 请求

请求

请求参数

查询参数Query

func _query(c *gin.Context) {
    fmt.Println(c.Query("user"))
    fmt.Println(c.GetQuery("user"))   // 拿到查询参数和状态(true/false)
    fmt.Println(c.QueryArray("user")) // 拿到多个相同的查询参数
}

在浏览器中输入

127.0.0.1/query?id=2&user=3
或
127.0.0.1/query?id=2&user=3&user=lisi

观察ide控制台里面的变化

运行效果 :

image-20230811095933971.png

动态参数 :

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)

查询路径 :

127.0.0.1/param/190
// 或
127.0.0.1/param/1/2

运行效果 :

image-20230811103430848.png

image-20230811103341602.png

表单参数 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)
}

接受表单要用POST方法

router.POST("/form", _form)

运行效果 :

image-20230811104834243.png

image-20230811104813783.png

原始参数

// 原始参数
func _raw(c *gin.Context) {
    body, _ := c.GetRawData()
    fmt.Println(string(body))
}
​
    router.POST("/raw", _raw)

from-data :

image-20230811110009711.png

运行效果 :

----------------------------159781848357328443244474
Content-Disposition: form-data; name="name"
​
abc
----------------------------159781848357328443244474
Content-Disposition: form-data; name="sddr"
​
长沙
​
----------------------------159781848357328443244474
Content-Disposition: form-data; name="pwd"123
----------------------------159781848357328443244474--

image-20230811110126385.png

x-www-form-urlencoded

image-20230811110225837.png

name=abc&age=18

image-20230811110303616.png

json

image-20230811110425103.png

{
    "name":"张三",
    "age" : "18", 
}

使用c.GetHeader("Content-type")能获取解析数据的类型;

contentType := c.GetHeader("Content-type")
    fmt.Println(contentType)

只对json数据处理,讲json解析到结构体上。

// 原始参数
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)
    }
}

四大请求方式

方式 :

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")
}

getlist

文章列表页面 : 响应json格式 : 封装好的结构体

效果 :

image-20230818223426892.png

getDetail

效果 :

image-20230818223622390.png

create

创建文章 : 接收前端传来的json数据,创建文章

效果 :

image-20230818223753115.png

update

编辑文章

image-20230818223849509.png

请求头

请求头参数获取

  • gin.H实际上就是map[string]interface{}

1.获取单个请求头 : 例 :

c.GetHeader("User-Agent")

注意 : 对于内容首字母大小不分,单词之间用 - 连接

2.获取所有的请求头信息

c.Request.Header

Header : (key : string , value : string类型的一个切片)

一个普通的 map[string][]string

里面提供了get方法,例如以下三句代码等价 :

fmt.Println(c.GetHeader("User-Agent"))
fmt.Println(c.Request.Header.Get("User-Agent"))
fmt.Println(c.Request.Header["User-Agent"])

具体代码 :

    // 获取请求头
    router.GET("/", func(c *gin.Context) {
        fmt.Println(c.GetHeader("User-Agent"))
        fmt.Println(c.Request.Header)
        fmt.Println(c.Request.Header.Get("User-Agent"))
        fmt.Println(c.Request.Header["User-Agent"])
        fmt.Println(c.Request.Header.Get("Token"))
        c.JSON(200, gin.H{"msg": "成功"})
    })

向127.0.0.1发请求,运行效果 :

image-20230818232756653.png

设置响应头

代码 :

    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": "看看响应头"})
    })

ContentType属性指定响应的 HTTP内容类型。如果未指定 ContentType,默认为TEXT/HTML