golang将结构体编码为URL查询参数插件库qs的使用
Golang将结构体编码为URL查询参数插件库qs的使用
安装
go get github.com/sonh/qs
基本使用
qs是一个零依赖的包,用于将结构体编码为url.Values。
import (
"github.com/sonh/qs"
)
包qs导出了NewEncoder()
函数来创建编码器。编码器会缓存结构体信息以加速编码过程,强烈建议使用单个实例。
使用WithTagAlias()
函数可以注册自定义标签别名(默认为qs
):
encoder = qs.NewEncoder(
qs.WithTagAlias("myTag"),
)
编码器有Values()
和Encode()
函数将结构体编码为url.Values
。
支持的数据类型
- 所有基本类型(
bool
,uint
,string
,float64
,…) struct
slice
,array
pointer
time.Time
- 自定义类型
示例
type Query struct {
Tags []string `qs:"tags"`
Limit int `qs:"limit"`
From time.Time `qs:"from"`
Active bool `qs:"active,omitempty"` // 省略空值
Ignore float64 `qs:"-"` // 忽略该字段
}
query := &Query{
Tags: []string{"docker", "golang", "reactjs"},
Limit: 24,
From: time.Unix(1580601600, 0).UTC(),
Ignore: 0,
}
encoder := qs.NewEncoder()
values, err := encoder.Values(query)
if err != nil {
// 处理错误
}
fmt.Println(values.Encode()) // (未转义) 输出: "from=2020-02-02T00:00:00Z&limit=24&tags=docker&tags=golang&tags=reactjs"
布尔值格式
使用int
选项将布尔值编码为整数:
type Query struct {
DefaultFmt bool `qs:"default_fmt"`
IntFmt bool `qs:"int_fmt,int"`
}
query := &Query{
DefaultFmt: true,
IntFmt: true,
}
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) // (未转义) 输出: "default_fmt=true&int_fmt=1"
时间格式
默认情况下,包将time.Time值编码为RFC3339格式。
包含"second"
或"millis"
选项表示该字段应编码为秒或毫秒:
type Query struct {
Default time.Time `qs:"default_fmt"`
Second time.Time `qs:"second_fmt,second"` // 使用`second`选项
Millis time.Time `qs:"millis_fmt,millis"` // 使用`millis`选项
}
t := time.Unix(1580601600, 0).UTC()
query := &Query{
Default: t,
Second: t,
Millis: t,
}
encoder := qs.NewEncoder()
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) // (未转义) 输出: "default_fmt=2020-02-02T00:00:00Z&millis_fmt=1580601600000&second_fmt=1580601600"
切片/数组格式
默认情况下,切片和数组编码为具有相同值名称的多个URL值。
type Query struct {
Tags []string `qs:"tags"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) // (未转义) 输出: "tags=foo&tags=bar"
包含comma
选项表示该字段应编码为单个逗号分隔的值:
type Query struct {
Tags []string `qs:"tags,comma"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) // (未转义) 输出: "tags=foo,bar"
包含bracket
选项表示多个URL值应在值名称后附加"[]":
type Query struct {
Tags []string `qs:"tags,bracket"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) // (未转义) 输出: "tags[]=foo&tags[]=bar"
index
选项将在值名称后附加带括号的索引号:
type Query struct {
Tags []string `qs:"tags,index"`
}
values, _ := encoder.Values(&Query{Tags: []string{"foo","bar"}})
fmt.Println(values.Encode()) // (未转义) 输出: "tags[0]=foo&tags[1]=bar"
嵌套结构体
所有嵌套结构体都使用带括号的父值名称进行范围编码:
type User struct {
Verified bool `qs:"verified"`
From time.Time `qs:"from,millis"`
}
type Query struct {
User User `qs:"user"`
}
query := Query{
User: User{
Verified: true,
From: time.Now(),
},
}
values, _ := encoder.Values(query)
fmt.Println(values.Encode()) // (未转义) 输出: "user[from]=1601623397728&user[verified]=true"
自定义类型
实现以下函数:
EncodeParam
将自身编码为查询参数IsZero
检查对象是否为零以确定编码时是否应省略
type NullableName struct {
First string
Last string
}
func (n NullableName) EncodeParam() (string, error) {
return n.First + n.Last, nil
}
func (n NullableName) IsZero() bool {
return n.First == "" && n.Last == ""
}
type Struct struct {
User NullableName `qs:"user"`
Admin NullableName `qs:"admin,omitempty"`
}
s := Struct{
User: NullableName{
First: "son",
Last: "huynh",
},
}
encoder := qs.NewEncoder()
values, err := encoder.Values(&s)
if err != nil {
// 处理错误
fmt.Println("failed")
return
}
fmt.Println(values.Encode()) // (未转义) 输出: "user=sonhuynh"
限制
- 如果
slice/array
中的元素是struct
数据类型,则多级嵌套有限制 - 目前还没有解码器
将在未来版本中改进
许可证
根据MIT许可证分发,更多详情请参阅代码中的许可证文件。
更多关于golang将结构体编码为URL查询参数插件库qs的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复