qs库

源代码:github.com/hapiman/qs

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>
*/
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值