Оригинальный автор, публичный аккаунт [программист чтение], прошу обратить внимание на паблик-аккаунт, просьба указывать источник перепечатываемой статьи.
Я написал две статьи ранее иGin
Статьи, связанные с фреймворком обучения, в основном оGin
Установка фреймворка, обработка определенийHTTP
Различные методы запроса и способы возврата данных в разных форматах в соответствии с требованиями клиента, но в середине отсутствует звено, то есть как получить клиента перед возвратом данныхHTTP
Какие параметры заносятся в запрос, об этом мы и поговорим в этой статье.
Gin
фреймворк справитсяHTTP
Такие операции, как параметры запроса и способ ответа, инкапсулированы вgin.Conetxt
структура и являетсяgin.Context
Есть так много доступных методов, так что поймитеgin.Context
Определения структуры и методыGin
рамочное письмоWeb
Проекты очень важны.
Нижеgin.Context
Код определения структуры:
type Context struct {
Request *http.Request
Writer ResponseWriter
Params Params
// Keys is a key/value pair exclusively for the context of each request.
Keys map[string]interface{}
// Errors is a list of errors attached to all the handlers/middlewares who used this context.
Errors errorMsgs
// Accepted defines a list of manually accepted formats for content negotiation.
Accepted []string
// contains filtered or unexported fields
}
сверхуgin.Context
Из структурного определения ,gin.Context
в упаковкеhttp.Request
иhttp.ResponseWriter
Получить параметры запроса
1. Path
путь относится к части, начинающейся с/после доменного имени в запрошенном URL-адресе, например адрес домашней страницы Nuggets:https://juejin.im/timeline
,/timeline
Часть — это путь, вы можете использовать метод Param() в gin.Context, чтобы получить эту часть параметров.
func (c *Context) Param(key string) string
Используйте метод Param() для получения параметров в пути:
r.GET("/user/:id",func(c *gin.Context){
id := c.Param("id")
})
В дополнение к использованию метода Param() в gin.Context вы также можете использовать поле Params в gin.Context для получения параметров в пути.Определение Params выглядит следующим образом:
type Params []Param
func (ps Params) ByName(name string) (va string)
func (ps Params) Get(name string) (string, bool)
Пример использования поля Params в gin.Context для получения параметров пути выглядит следующим образом:
r.GET("/user/:id",func(c *gin.Context){
id,err := c.Params.Get("id")
//id := c.Params.ByName("id")
})
2. Query
запрос относится к части после вопросительного знака в адресе запроса URL, называемой параметром запроса, как в следующем адресе,query=%E6%96%87%E7%AB%A0&type=all
являются параметрами запроса.
https://juejin.im/search?query=%E6%96%87%E7%AB%A0&type=all
gin.Context
Для получения параметров части запроса предусмотрены следующие методы.
1. Получить один параметр
func (c *Context) GetQuery(key string) (string, bool)
func (c *Context) Query(key string) string
func (c *Context) DefaultQuery(key, defaultValue string) string
Вышеупомянутые три метода используются для получения одного значения,GetQuery
СравниватьQuery
Возвращает еще один параметр типа error, по сутиQuery
метод просто инкапсулируетGetQuery
метод и игнорироватьGetQuery
Метод возвращает ошибку, а метод DefaultQuery возвращает значение по умолчанию, если соответствующее значение параметра не получено.
Пример выглядит следующим образом:
r.GET("/user", func(c *gin.Context) {
id,_ := c.GetQuery("id")
//id := c.Query("id")
//id := c.DefaultQuery("id","10")
c.JSON(200,id)
})
просить:http://localhost:8080/user?id=11
отклик:11
2. Получить массив
Разница между методом GetQueryArray и QueryArray такая же, как у GetQuery и Query.
func (c *Context) GetQueryArray(key string) ([]string, bool)
func (c *Context) QueryArray(key string) []string
Пример выглядит следующим образом:
r.GET("/user", func(c *gin.Context) {
ids := c.QueryArray("id")
//id,_ := c.QueryArray("id")
c.JSON(200,ids)
})
просить:http://localhost:8080/user?id=10&id=11&id=12
отклик:["10","11","12"]
3. Получить карту
Разница между методом GetQueryArray и QueryArray такая же, как у GetQuery и Query.
func (c *Context) QueryMap(key string) map[string]string
func (c *Context) GetQueryMap(key string) (map[string]string, bool)
Пример выглядит следующим образом:
r.GET("/user", func(c *gin.Context) {
ids := c.QueryMap("ids")
//ids,_ := c.GetQueryMap("ids")
c.JSON(200,ids)
})
просить:http://localhost:8080/user?ids[10]=zhang
отклик:{"10":"zhang"}
3. Body
Как правило, параметры запроса HTTP Post передаются на сервер через часть тела, особенно данные с большим объемом данных или высокими требованиями к безопасности, такие как пароль учетной записи и другие параметры в функции входа в систему.
gin.Context предоставляет нам следующие четыре метода для получения данных в теле, но следует отметить, что следующие четыре метода могут быть получены толькоContent-type
даapplication/x-www-form-urlencoded
илиmultipart/form-data
Времяbody
данные в .
Использование следующего метода такое же, как тип использования метода для получения запроса выше. Разница заключается только в источнике данных. Образец программы здесь не будет написан.
func (c *Context) PostForm(key string) string
func (c *Context) PostFormArray(key string) []string
func (c *Context) PostFormMap(key string) map[string]string
func (c *Context) DefaultPostForm(key, defaultValue string) string
func (c *Context) GetPostForm(key string) (string, bool)
func (c *Context) GetPostFormArray(key string) ([]string, bool)
func (c *Context) GetPostFormMap(key string) (map[string]string, bool)
func (c *Context) GetRawData() ([]byte, error)
привязка данных
В предыдущем примере мы напрямую использовалиgin.Context
Предоставленный метод передается в запросеpath
,query
,body
Параметры выставлены, но предыдущие методы не могут обрабатывать более сложные структуры данных в запросе.Например, когда Content-type имеет значение application/json или application/xml, данные, которые он приносит, будут очень сложными, поэтому нам нужно Используйте другой метод для получения этих данных, этот метод называется数据绑定
.
Gin
Платформа инкапсулирует операции привязки данных в пакете gin/binding.gin/binding包
Определенные константы, заявляющиеgin/binding
пакет поддерживаетсяContent-type
Формат.
const (
MIMEJSON = "application/json"
MIMEHTML = "text/html"
MIMEXML = "application/xml"
MIMEXML2 = "text/xml"
MIMEPlain = "text/plain"
MIMEPOSTForm = "application/x-www-form-urlencoded"
MIMEMultipartPOSTForm = "multipart/form-data"
MIMEPROTOBUF = "application/x-protobuf"
MIMEMSGPACK = "application/x-msgpack"
MIMEMSGPACK2 = "application/msgpack"
MIMEYAML = "application/x-yaml"
)
gin.binding
Пакеты также определены для обработки различныхContent-type
Структура обработки, которая отправляет данные и делает их доступными для других пакетов в виде переменных, выглядит следующим образом:
var (
JSON = jsonBinding{}
XML = xmlBinding{}
Form = formBinding{}
Query = queryBinding{}
FormPost = formPostBinding{}
FormMultipart = formMultipartBinding{}
ProtoBuf = protobufBinding{}
MsgPack = msgpackBinding{}
YAML = yamlBinding{}
Uri = uriBinding{}
)
Но на самом деле нам не нужно звонитьgin/binding
код пакета для завершения функции привязки данных, потому чтоgin.Context
уже вgin.Context
На основе инкапсуляции множества более быстрых методов, которые мы можем использовать:
gin.Context
Связанные методы связывания инкапсуляции делятся наBind
Методы серии с префиксомShouldBind
Разница между этими двумя сериями методов заключается в том, что метод с префиксом Bind будет напрямую возвращать клиенту ответ с HTTP-статусом 400, когда вводимые пользователем данные не соответствуют соответствующему формату.
Серия методов с префиксом Bind
1. Path
func (c *Context) BindUri(obj interface{}) error
Пример кода:
type User struct {
Uid int //用户id
Username string //用户名
}
func main() {
r := gin.Default()
r.GET("/bind/:uid/username", func(c *gin.Context) {
var u User
e := c.BindUri(&u)
if e == nil{
c.JSON(200,u)
}
})
r.Run()
}
просить:http://localhost:8080/bind/1/小张
входить:{1,"小张"}
2. Query
func (c *Context) BindQuery(obj interface{}) error
Пример кода:
r.GET("/bind/:uid/username", func(c *gin.Context) {
var u User
e := c.BindQuery(&u)
if e == nil{
c.JSON(200,u)
}
})
просить:http://localhost:8080/bind?uid=1&username=小张
вывод:{1,"小张"}
3. Body
когда мыHTTP
просьбаBody
Чтобы установить разные форматы данных, вам нужно установить соответствующий заголовокContent-Type
Значение , чаще используемое какjson
,xml
,yaml
,gin.Context
Предоставьте следующие три метода для привязки данных в теле, соответствующих Content-type.
func (c *Context) BindJSON(obj interface{}) error
func (c *Context) BindXML(obj interface{}) error
func (c *Context) BindYAML(obj interface{}) error
В дополнение к трем вышеупомянутым методам, более часто используемый метод Bind(), метод Bind() автоматически выбирает различные типы привязки в соответствии со значением Content-Type.
func (c *Context) Bind(obj interface{}) error
Пример
r.POST("bind",func(c *gin.Context){
u := User{}
c.Bind(&u)
})
Вышеупомянутые методы предназначены для получения фиксированного типа содержимого или автоматического выбора типа привязки в соответствии с типом содержимого.Мы также можем использовать следующие два метода для самостоятельного выбора типа привязки.
Вторым значением параметра следующих двух методов является константа, определенная в gin.binding, о которой мы говорили выше.
func (c *Context) BindWith(obj interface{}, b binding.Binding) error
func (c *Context) MustBindWith(obj interface{}, b binding.Binding) error
Пример
r.POST("bind",func(c *gin.Context){
u := User{}
c.BindWith(&u,binding.JSON)
c.MustBindWith(&u,binding.JSON)
})
Серия методов с префиксом ShouldBind
Соответствующий метод с префиксом ShouldBind в основном совпадает с методом с префиксом Bind, поэтому ниже нет соответствующего демонстрационного кода.
1. Path
func (c *Context) ShouldBindUri(obj interface{}) error
2. Query
func (c *Context) ShouldBindQuery(obj interface{}) error
3. Body
func (c *Context) ShouldBind(obj interface{}) error
func (c *Context) ShouldBindJSON(obj interface{}) error
func (c *Context) ShouldBindXML(obj interface{}) error
func (c *Context) ShouldBindYAML(obj interface{}) error
func (c *Context) ShouldBindBodyWith(obj interface{}, bb binding.BindingBody) (err error)
func (c *Context) ShouldBindWith(obj interface{}, b binding.Binding) error
резюме
Gin
кадр вnet/http
На основе пакета инкапсулировано множество методов, так что мы можем получать данные в различных форматах от клиента, но после получения данных от клиента нам все равно нужно проверить, легальны ли данные или то, что мы хотим. являетсяGin
В рамках数据验证器
знания, и иметь возможность писать статьи по этому поводу.
Ваше внимание — самое большое поощрение на моем писательском пути!