Content-Type=application/json;utf-8
场景为例。话不多说,直接上代码。
package utils
import (
jsoniter "github.com/json-iterator/go"
"sort"
"strings"
)
var jsont = jsoniter.Config{
//关闭对HTML字符串编码
EscapeHTML: false,
//json为简单字符串即不进行unescape(do not unescape object field)
ObjectFieldMustBeSimpleString: true,
//是否开启Number承载数据(整形、浮点型)
UseNumber: true,
}.Froze()
/**
* @param data json字符串字节流
* @desc 用于生成签名拼接字符串QueryString。
* 1.按ASCII码从小到大排序,空键/值和空字符串不参与组串
* 2.统一使用UTF8进行编码签名,防止编码方式或特殊字符不兼容问题
* 3.签名原始串中,字段名和字段值都采用原始值,即不进行URL Encode
* 4.注意整形、浮点型数据参与签名方式(如:浮点数3.10体现为3.1、0.0体现为0)
* 5.内嵌JSON或ARRAY解析拼接需转字符串且按紧凑方式,即内嵌各K/V或值之间不应有空格或换行符等等
* 6.内嵌对象中空对象或空字符串不做任何处理(即保留)
*/
func BuildSignQueryStr(data []byte) (string,error){
pstr := string(data)
var tempMap map[string]interface{}
jsont.Unmarshal([]byte(pstr), &tempMap)
keys := make([]string,0,len(tempMap))
for k,_ := range tempMap {
keys = append(keys, k)
}
sort.Strings(keys)
var sbuilder strings.Builder
for _,k := range keys {
if len(k) == 0 || strings.EqualFold("sign", k) {
continue
}
var v string
tv := tempMap[k]
if tv == nil {
continue
}
switch tv.(type) {
case string: v = tv.(string)
default:
v,_ = jsont.MarshalToString(tv)
}
if len(v) == 0 {
continue
}
if sbuilder.Len() > 0 {
sbuilder.WriteString("&")
}
sbuilder.WriteString(k)
sbuilder.WriteString("=")
sbuilder.WriteString(v)
}
return sbuilder.String(), nil
}