Golang中querystring
的处理
将结构体转化成category=c1&category=c2&page=2&page_size=50&search=my+search
的形式
+--------------+
+---------------->| query string +------------------+
| +---------+----+ |
| ^ | |
| url.Values.Encode | | url.ParseQuery |
| | v |
| +----+---------+ |
| | url.Values | |
| +---------+----+ |
| ^ | |
| qs.MarshalValues | | qs.UnmarshalValues |
| | v |
| +----+---------+ |
+-----------------+ struct |<-----------------+
qs.Marshal +--------------+ qs.Unmarshal
复制代码
示例
package main
import "fmt"
import "github.com/pasztorpisti/qs"
type Query struct {
Search string
Page int
PageSize int
Categories []string `qs:"category"`
}
func main() {
// 默认情况
queryStr, err := qs.Marshal(&Query{
Search: "my search",
Page: 2,
PageSize: 50,
Categories: []string{"c1", "c2"},
})
fmt.Println("Marshal-Result:", queryStr, err)
var q Query
err = qs.Unmarshal(&q, queryStr)
fmt.Println("Unmarshal-Result:", q, err)
// Output:
// Marshal-Result: category=c1&category=c2&page=2&page_size=50&search=my+search <nil>
// Unmarshal-Result: {my search 2 50 [c1 c2]} <nil>
}
复制代码
如果需要对数据进行定制,实现MarshalQS
或者UnmarshalQS
接口即可
package main
import (
"encoding/hex"
"fmt"
"github.com/pasztorpisti/qs"
)
// This example shows how to implement the MarshalQS and UnmarshalQS interfaces
// with a custom type that wants to handle its own marshaling and unmarshaling.
func main() {
// Using the []byte type with its default marshaling.
defaultMarshaling()
// Using the Byte array type that implements custom marshaling.
customMarshaling()
}
func defaultMarshaling() {
queryStr, err := qs.Marshal(map[string][]byte{
"a": {0, 1, 2},
"b": {3, 4, 5},
})
fmt.Println("Default-Marshal-Result:", queryStr, err)
var query map[string][]byte
err = qs.Unmarshal(&query, queryStr)
fmt.Printf("Default-Unmarshal-Result: len=%v a=%v b=%v %v\n",
len(query), query["a"], query["b"], err)
}
func customMarshaling() {
queryStr, err := qs.Marshal(map[string]Bytes{
"a": {0, 1, 2},
"b": {3, 4, 5},
})
fmt.Println("Custom-Marshal-Result:", queryStr, err)
var query map[string]Bytes
err = qs.Unmarshal(&query, queryStr)
fmt.Printf("Custom-Unmarshal-Result: len=%v a=%v b=%v %v\n",
len(query), query["a"], query["b"], err)
}
// Bytes implements the MarshalQS and the UnmarshalQS interfaces to marshal
// itself as a hex string instead of the usual array serialisation used in
// standard query strings.
//
// The default marshaler marshals the []byte{4, 2} array to the "key=4&key=2"
// query string. In contrast the Bytes{4, 2} array is marshaled as "key=0402".
type Bytes []byte
func (b Bytes) MarshalQS(opts *qs.MarshalOptions) ([]string, error) {
return []string{hex.EncodeToString(b)}, nil
}
func (b *Bytes) UnmarshalQS(a []string, opts *qs.UnmarshalOptions) error {
s, err := opts.SliceToString(a)
if err != nil {
return err
}
*b, err = hex.DecodeString(s)
return err
}
// Compile time check: Bytes implements the qs.MarshalQS interface.
var _ qs.MarshalQS = Bytes{}
// Compile time check: *Bytes implements the qs.UnmarshalQS interface.
var _ qs.UnmarshalQS = &Bytes{}
/* 输出结果
Default-Marshal-Result: a=0&a=1&a=2&b=3&b=4&b=5 <nil>
Default-Unmarshal-Result: len=2 a=[0 1 2] b=[3 4 5] <nil>
Custom-Marshal-Result: a=000102&b=030405 <nil>
Custom-Unmarshal-Result: len=2 a=[0 1 2] b=[3 4 5] <nil>
*/
复制代码