0


golang,gin框架的请求参数(一)--推荐

golang,gin框架的请求参数(一)

gin框架的重要性不过多的强调,重点就gin使用中的参数传递,获取进行梳理文件,满足使用需求。

获取前端请求参数的几种方法:

一、获取参数【浏览器地址获取参数】

1.浏览器地址栏获取参数

1.获取 URL (query)参数

例如:/user/search?username=zhangsan&address=北京。 获取请求的query参数的方法如下:
URL 参数可以通过DefaultQuery() 和 Query() 两个参数获取

这两个【DefaultQuery() 和 Query() 】的区别就是,DefaultQuery()可以放个默认参数,如果没有存参数那么就是使用默认参数,

Query()如果不给参数,就是默认为“”

示例:

1.1后端代码:
package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
    // 如果指定的key 没有对应的值就使用默认值
    username1 := ctx.DefaultQuery("username", "lisi")

    // 根据key 获取值
    username2 := ctx.Query("username")

    address := ctx.Query("address")

    // 返回JSON 字符串
    ctx.JSON(http.StatusOK, gin.H{
        "message":   "ok",
        "username1": username1,
        "username2": username2,
        "address":   address,
    })
}
func main() {

    // 创建默认路由
    r := gin.Default()

    // 绑定路由规则
    r.GET("/user/search", urlQueryHandle)

    // 监听端口
    r.Run(":9000")
}

1.2浏览器访问,从中可以看到我们没有给任何参数,后端Query查询的都是为“”

1.3带参数的访问

http://127.0.0.1:9000/user/search?username=tom&address=xian&username=jerry

?username=tom&address=xian&username=jerry

1.3.1postman获取参数


2.获取参数【获取Path参数(RestFul风格)】

请求的参数通过URL路径传递,例如:/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下。

以下代码是上述两种浏览器获取参数的办法,具体看代码品味下;

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
    // 如果指定的key 没有对应的值就使用默认值
    username1 := ctx.DefaultQuery("username", "lisi")

    // 根据key 获取值
    username2 := ctx.Query("username")

    address := ctx.Query("address")

    // 返回JSON 字符串
    ctx.JSON(http.StatusOK, gin.H{
        "message":   "ok",
        "username1": username1,
        "username2": username2,
        "address":   address,
    })
}

// /user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
// paramsPathHandle 获取url path中参数
func paramsPathHandle(ctx *gin.Context) {

    // 获取参数值
    username := ctx.Param("username")
    address := ctx.Param("address")

    // 数据返回
    ctx.JSON(http.StatusOK, gin.H{
        "message":  "ok",
        "username": username,
        "address":  address,
    })
}

func main() {

    // 创建默认路由
    r := gin.Default()
    //两种浏览器地址获取参数的办法
    // 绑定路由规则 /user/search?username=zhangsan&address=北京
    r.GET("/user/search", urlQueryHandle)
    // 2. 绑定路由规则/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
    r.GET("/user/search/:username/:address", paramsPathHandle)

    // 监听端口
    r.Run(":9000")
}

二、表单获取参数获取 Form参数

表单提交POST请求时,http常见的传输格式有四种application/json (json格式)

  • text/plain (text格式)
  • application/x-www-form-urlencode(表单默认提交格式)
  • application./xml (xml格式)
  • multipart/form-data( 文件上传)

可以通过 DefaultPostForm() 和 PostForm() 两个方法获取(默认解析的是 x-www-form-urlencode 和 form-data 格式的参数)

2.1获取form表单数据

2.1.1application/x-www-form-urlencode(表单默认提交格式)

因为发起post请求,前端只能用postman模拟了

返回结果

2.1.2form-data表单提交方式

2.2获取json参数【**ctx.GetRowData()**】

2.2.1请求数据application./json(json格式)

2.2.2 application./xml (xml格式)

2.3文件上传事项

2.3.1文件上传接收的文件格式要求:

格式是: multipart/form-data

2.3.2多文件上传

2.4表单数据获取的代码

package main

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

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
    // 如果指定的key 没有对应的值就使用默认值
    username1 := ctx.DefaultQuery("username", "lisi")

    // 根据key 获取值
    username2 := ctx.Query("username")

    address := ctx.Query("address")

    // 返回JSON 字符串
    ctx.JSON(http.StatusOK, gin.H{
        "message":   "ok",
        "username1": username1,
        "username2": username2,
        "address":   address,
    })
}

// /user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
// paramsPathHandle 获取url path中参数
func paramsPathHandle(ctx *gin.Context) {

    // 获取参数值
    username := ctx.Param("username")
    address := ctx.Param("address")

    // 数据返回
    ctx.JSON(http.StatusOK, gin.H{
        "message":  "ok",
        "username": username,
        "address":  address,
    })
}

//=================================

// formParamsHandle 获取form表单提交数据
func formParamsHandle(ctx *gin.Context) {

    // 获取不到值时就是用默认值
    username1 := ctx.DefaultPostForm("username", "lisi")

    username2 := ctx.PostForm("username")
    address := ctx.PostForm("address")

    // 以Json 字符串的形式返回
    ctx.JSON(http.StatusOK, gin.H{
        "message":   "ok",
        "username1": username1,
        "username2": username2,
        "address":   address,
    })
}

// json参数
// paramsJsonHandle 获取json字符串相关的参数
func paramsJsonHandle(ctx *gin.Context) {

    // 获取request.Body() 中的数据(这里没有进行错误处理)
    // 返回的是字节数组
    dataBytes, _ := ctx.GetRawData()

    // 定义一个map
    var m map[string]interface{}

    // 反序列化 别忘了&
    _ = json.Unmarshal(dataBytes, &m)

    // 数据返回
    ctx.JSON(http.StatusOK, m)

}

//文件上传
/*
  单个文件上传
    文件上传接收的文件格式是: multipart/form-data
*/

// singleFileUploadHandle 当文件上传
func singleFileUploadHandle(ctx *gin.Context) {

    // 获取文件
    // 根据上传时的参数名获取上传的文件内容 --> 返回对象为 *multipart.FileHeader
    fileHeader, err := ctx.FormFile("file")
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": err.Error(),
        })
        return
    }

    // 保存文件内容
    // 拼接文件名, 这里直接写死了
    targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%s", fileHeader.Filename)
    //targetFileName := fmt.Sprintf("%s", fileHeader.Filename)

    // 将文件保存到指定的目录
    err = ctx.SaveUploadedFile(fileHeader, targetFileName)
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": err.Error(),
        })
    } else {
        ctx.JSON(http.StatusOK, gin.H{
            "message": fmt.Sprintf("%s upload success!", fileHeader.Filename),
        })
    }
}

//多文件上传

/**
  多文件上传
*/

// multiFileUploadHandle 多文件上传
func multiFileUploadHandle(ctx *gin.Context) {

    // form 是一个存储文件信息的结构体
    /**
      type Form struct {
        Value map[string][]string
        File  map[string][]*FileHeader
    */
    form, err := ctx.MultipartForm()
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": err.Error(),
        })
        return
    }

    // 获取文件列表,并保存, 返回的是一个切片 []*FileHeader
    files := form.File["file"]
    for i, file := range files {
        targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%d_%s", i, file.Filename)
        err = ctx.SaveUploadedFile(file, targetFileName)

        if err != nil {
            ctx.JSON(http.StatusInternalServerError, gin.H{
                "message": err.Error(),
            })
            return
        }
    }
    ctx.JSON(http.StatusOK, gin.H{
        "message": fmt.Sprintf("upload success!"),
    })
}

func main() {

    // 创建默认路由
    r := gin.Default()
    //两种浏览器地址获取参数的办法
    // 绑定路由规则 /user/search?username=zhangsan&address=北京
    r.GET("/user/search", urlQueryHandle)
    // 2. 绑定路由规则/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
    r.GET("/user/search/:username/:address", paramsPathHandle)

    //========================表单提交方法======================
    // 绑定路由规则
    r.POST("/user/search", formParamsHandle)

    //json
    // 绑定路由规则
    r.POST("/user/json", paramsJsonHandle)

    //

    // 绑定路由规则--文件上传
    r.POST("/upload/single", singleFileUploadHandle)

     绑定路由规则--多文件上传
    r.POST("/upload/multi", multiFileUploadHandle)
    // 监听端口
    r.Run(":9000")
}

2.5参数绑定--优化数据方式

使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中

2.5.1url query参数解析

2.5.2form表单参数解析

2.5.3json 数据解析

三、程序的所有代码

package main

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

// /user/search?username=zhangsan&address=北京
// urlQuery 获取 url中?后面携带的参数
func urlQueryHandle(ctx *gin.Context) {
    // 如果指定的key 没有对应的值就使用默认值
    username1 := ctx.DefaultQuery("username", "lisi")

    // 根据key 获取值
    username2 := ctx.Query("username")

    address := ctx.Query("address")

    // 返回JSON 字符串
    ctx.JSON(http.StatusOK, gin.H{
        "message":   "ok",
        "username1": username1,
        "username2": username2,
        "address":   address,
    })
}

// /user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
// paramsPathHandle 获取url path中参数
func paramsPathHandle(ctx *gin.Context) {

    // 获取参数值
    username := ctx.Param("username")
    address := ctx.Param("address")

    // 数据返回
    ctx.JSON(http.StatusOK, gin.H{
        "message":  "ok",
        "username": username,
        "address":  address,
    })
}

//=================================

// formParamsHandle 获取form表单提交数据
func formParamsHandle(ctx *gin.Context) {

    // 获取不到值时就是用默认值
    username1 := ctx.DefaultPostForm("username", "lisi")

    username2 := ctx.PostForm("username")
    address := ctx.PostForm("address")

    // 以Json 字符串的形式返回
    ctx.JSON(http.StatusOK, gin.H{
        "message":   "ok",
        "username1": username1,
        "username2": username2,
        "address":   address,
    })
}

// json参数
// paramsJsonHandle 获取json字符串相关的参数
func paramsJsonHandle(ctx *gin.Context) {

    // 获取request.Body() 中的数据(这里没有进行错误处理)
    // 返回的是字节数组
    dataBytes, _ := ctx.GetRawData()

    // 定义一个map
    var m map[string]interface{}

    // 反序列化 别忘了&
    _ = json.Unmarshal(dataBytes, &m)

    // 数据返回
    ctx.JSON(http.StatusOK, m)

}

//文件上传
/*
  单个文件上传
    文件上传接收的文件格式是: multipart/form-data
*/

// singleFileUploadHandle 当文件上传
func singleFileUploadHandle(ctx *gin.Context) {

    // 获取文件
    // 根据上传时的参数名获取上传的文件内容 --> 返回对象为 *multipart.FileHeader
    fileHeader, err := ctx.FormFile("file")
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": err.Error(),
        })
        return
    }

    // 保存文件内容
    // 拼接文件名, 这里直接写死了
    targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%s", fileHeader.Filename)
    //targetFileName := fmt.Sprintf("%s", fileHeader.Filename)

    // 将文件保存到指定的目录
    err = ctx.SaveUploadedFile(fileHeader, targetFileName)
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": err.Error(),
        })
    } else {
        ctx.JSON(http.StatusOK, gin.H{
            "message": fmt.Sprintf("%s upload success!", fileHeader.Filename),
        })
    }
}

//多文件上传

/**
  多文件上传
*/

// multiFileUploadHandle 多文件上传
func multiFileUploadHandle(ctx *gin.Context) {

    // form 是一个存储文件信息的结构体
    /**
      type Form struct {
        Value map[string][]string
        File  map[string][]*FileHeader
    */
    form, err := ctx.MultipartForm()
    if err != nil {
        ctx.JSON(http.StatusInternalServerError, gin.H{
            "message": err.Error(),
        })
        return
    }

    // 获取文件列表,并保存, 返回的是一个切片 []*FileHeader
    files := form.File["file"]
    for i, file := range files {
        targetFileName := fmt.Sprintf("C:/Users/黑熊精/Pictures/%d_%s", i, file.Filename)
        err = ctx.SaveUploadedFile(file, targetFileName)

        if err != nil {
            ctx.JSON(http.StatusInternalServerError, gin.H{
                "message": err.Error(),
            })
            return
        }
    }
    ctx.JSON(http.StatusOK, gin.H{
        "message": fmt.Sprintf("upload success!"),
    })
}

// shuldbind数据的绑定的办法
// 使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中
// 用户信息信息结构体
// 加上 binding:"required" 标签,说明该参数是必填的,如果不填就会报错
type UserInfo struct {
    Username string `json:"username" form:"username" binding:"required"`
    Address  string `json:"address" form:"address" binding:"required"`
}

// 获取query参数
func queryHandle(ctx *gin.Context) {
    var userInfo UserInfo

    // 获取数据
    err := ctx.ShouldBind(&userInfo)
    if err == nil {
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "ok",
            "username": userInfo.Username,
            "address":  userInfo.Address,
        })
    } else {
        ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    }
}

func jsonHandle(ctx *gin.Context) {
    var userInfo UserInfo

    // 获取数据
    err := ctx.ShouldBind(&userInfo)
    if err == nil {
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "ok",
            "username": userInfo.Username,
            "address":  userInfo.Address,
        })
    } else {
        ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    }
}

func fromHandle(ctx *gin.Context) {
    var userInfo UserInfo

    // 获取数据
    err := ctx.ShouldBind(&userInfo)
    if err == nil {
        ctx.JSON(http.StatusOK, gin.H{
            "message":  "ok",
            "username": userInfo.Username,
            "address":  userInfo.Address,
        })
    } else {
        ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
    }
}

func main() {

    // 创建默认路由
    r := gin.Default()
    //两种浏览器地址获取参数的办法
    // 绑定路由规则 /user/search?username=zhangsan&address=北京
    r.GET("/user/search", urlQueryHandle)
    // 2. 绑定路由规则/user/search/lisi/北京。 获取请求URL路径中的参数的方式如下
    r.GET("/user/search/:username/:address", paramsPathHandle)

    //========================表单提交方法======================
    // 绑定路由规则
    r.POST("/user/search", formParamsHandle)

    //json
    // 绑定路由规则
    r.POST("/user/json", paramsJsonHandle)

    //

    // 绑定路由规则--文件上传
    r.POST("/upload/single", singleFileUploadHandle)

     绑定路由规则--多文件上传
    r.POST("/upload/multi", multiFileUploadHandle)

    //使用 ShouldBind() 方法, 根据请求方式,自动提取 JSON, form表单 和 Query 类型的参数,放入结构体中
    // 绑定路由规则
    r.GET("/user/query", queryHandle)
    r.POST("/user/form", fromHandle)
    r.POST("/user/jsons", jsonHandle)
    // 监听端口
    r.Run(":9000")
}
标签: golang gin 开发语言

本文转载自: https://blog.csdn.net/wtt234/article/details/131953861
版权归原作者 雨师@ 所有, 如有侵权,请联系我们删除。

“golang,gin框架的请求参数(一)--推荐”的评论:

还没有评论