Compare commits
5 Commits
c50cb0039a
...
master
Author | SHA1 | Date | |
---|---|---|---|
faef357487 | |||
73999a8452 | |||
10a21dc357 | |||
8ef7aea4fe | |||
4092863a9a |
12
cache/ICache.go
vendored
12
cache/ICache.go
vendored
@ -51,4 +51,16 @@ type ICache interface {
|
|||||||
//
|
//
|
||||||
// Date : 16:46 2024/6/3
|
// Date : 16:46 2024/6/3
|
||||||
SetValue(cacheKey string, cacheValue string) error
|
SetValue(cacheKey string, cacheValue string) error
|
||||||
|
// TTL 缓存剩余生命周期(单位: s)
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:39 2024/10/9
|
||||||
|
TTL(cacheKey string) int64
|
||||||
|
// PreHeatConfig 缓存预热配置
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:42 2024/10/9
|
||||||
|
PreHeatConfig() *define.CachePreHeatConfig
|
||||||
}
|
}
|
||||||
|
51
client.go
51
client.go
@ -148,9 +148,54 @@ func (hc *HttpClient) Request() *define.Response {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if cacheResult = hc.getCacheResult(); nil != cacheResult {
|
if cacheResult = hc.getCacheResult(); nil != cacheResult {
|
||||||
return cacheResult
|
// 判断是否开启预热
|
||||||
|
inputCachePreHeatConfig := hc.cacheInstance.PreHeatConfig()
|
||||||
|
var cachePreHeatConfig define.CachePreHeatConfig
|
||||||
|
serialize.JSON.TransitionIgnoreError(inputCachePreHeatConfig, &cachePreHeatConfig)
|
||||||
|
if !cachePreHeatConfig.Enable || (cachePreHeatConfig.MinTTL <= 0 && cachePreHeatConfig.MinPercent <= 0 && !cachePreHeatConfig.Force) {
|
||||||
|
// 无预热配置或未启用预热或者未设置预热规则
|
||||||
|
return cacheResult
|
||||||
|
}
|
||||||
|
go func() {
|
||||||
|
// 判断是否触发预热
|
||||||
|
if cachePreHeatConfig.Force {
|
||||||
|
_ = hc.requestBackendApi()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 将百分比的配置归一化成最小剩余时间的配置
|
||||||
|
if cachePreHeatConfig.MinPercent > 0 {
|
||||||
|
expectMinTTL := hc.cacheInstance.CacheTime() * cachePreHeatConfig.MinPercent / 100
|
||||||
|
if cachePreHeatConfig.MinTTL == 0 || cachePreHeatConfig.MinTTL > expectMinTTL {
|
||||||
|
cachePreHeatConfig.MinTTL = expectMinTTL
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if cachePreHeatConfig.MinTTL <= 0 {
|
||||||
|
// 未配置最小剩余时间
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ttl := hc.cacheInstance.TTL(cacheResult.CacheInfo.CacheKey)
|
||||||
|
if ttl < 0 {
|
||||||
|
// 不存在或者未设置有效期
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if ttl <= cachePreHeatConfig.MinTTL {
|
||||||
|
// 配置了最小剩余时间,并且key剩余有效期小于最小剩余时间
|
||||||
|
_ = hc.requestBackendApi()
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return hc.requestBackendApi()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// requestBackendApi 请求后端接口
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:47 2024/10/9
|
||||||
|
func (hc *HttpClient) requestBackendApi() *define.Response {
|
||||||
hc.Client.OnBeforeRequest(hc.getRequestValidateMiddleware()) // 请求参数验证中间件必注册
|
hc.Client.OnBeforeRequest(hc.getRequestValidateMiddleware()) // 请求参数验证中间件必注册
|
||||||
hc.Client.OnAfterResponse(hc.getResponseValidateMiddleware()) // 响应验证中间件必注册
|
hc.Client.OnAfterResponse(hc.getResponseValidateMiddleware()) // 响应验证中间件必注册
|
||||||
var (
|
var (
|
||||||
@ -300,7 +345,7 @@ func (hc *HttpClient) fillResponseBody(response *define.Response) {
|
|||||||
response.Data = businessData.String()
|
response.Data = businessData.String()
|
||||||
} else {
|
} else {
|
||||||
// 返回是普通类型
|
// 返回是普通类型
|
||||||
response.Data = serialize.JSON.MarshalForString(map[string]any{
|
response.Data = serialize.JSON.MarshalForStringIgnoreError(map[string]any{
|
||||||
"value": businessData.Value(),
|
"value": businessData.Value(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -376,7 +421,7 @@ func (hc *HttpClient) setCacheResult(response *define.Response) (bool, error) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
cacheKey := hc.cacheInstance.GetKey(hc.reqConfig)
|
cacheKey := hc.cacheInstance.GetKey(hc.reqConfig)
|
||||||
cacheValue := serialize.JSON.MarshalForString(response)
|
cacheValue := serialize.JSON.MarshalForStringIgnoreError(response)
|
||||||
if err := hc.cacheInstance.SetValue(cacheKey, cacheValue); nil != err {
|
if err := hc.cacheInstance.SetValue(cacheKey, cacheValue); nil != err {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
20
define/cache.go
Normal file
20
define/cache.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
// Package define ...
|
||||||
|
//
|
||||||
|
// Description : define ...
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 2024-10-09 18:39
|
||||||
|
package define
|
||||||
|
|
||||||
|
// CachePreHeatConfig 缓存预热配置, MinPercent / MinTTL 同时配置, 则任意一个满足, 均进行预热
|
||||||
|
//
|
||||||
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
|
//
|
||||||
|
// Date : 18:40 2024/10/9
|
||||||
|
type CachePreHeatConfig struct {
|
||||||
|
Enable bool `json:"enable"` // 缓存预热是否可用
|
||||||
|
MinPercent int64 `json:"min_percent"` // 最小百分比, 剩余有效期低于此百分比进行预热
|
||||||
|
MinTTL int64 `json:"min_ttl"` // 最小剩余生命周期, 低于此百分比进行预热
|
||||||
|
Force bool `json:"force"` // 启用预热的情况下, 强制预热, 会忽略 MinPercent / MinTTL 的配置
|
||||||
|
}
|
12
go.mod
12
go.mod
@ -3,19 +3,19 @@ module git.zhangdeman.cn/gateway/httpclient
|
|||||||
go 1.22.3
|
go 1.22.3
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241023104258-2e0a298aa558
|
||||||
github.com/go-resty/resty/v2 v2.13.1
|
github.com/go-resty/resty/v2 v2.15.3
|
||||||
github.com/tidwall/gjson v1.17.1
|
github.com/tidwall/gjson v1.18.0
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec // indirect
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241023090605-10cff9173059 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 // indirect
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect
|
||||||
github.com/BurntSushi/toml v1.4.0 // indirect
|
github.com/BurntSushi/toml v1.4.0 // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // indirect
|
github.com/go-ini/ini v1.67.0 // indirect
|
||||||
github.com/stretchr/testify v1.9.0 // indirect
|
github.com/stretchr/testify v1.9.0 // indirect
|
||||||
github.com/tidwall/match v1.1.1 // indirect
|
github.com/tidwall/match v1.1.1 // indirect
|
||||||
github.com/tidwall/pretty v1.2.1 // indirect
|
github.com/tidwall/pretty v1.2.1 // indirect
|
||||||
golang.org/x/net v0.26.0 // indirect
|
golang.org/x/net v0.30.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
12
go.sum
12
go.sum
@ -1,9 +1,15 @@
|
|||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec h1:ENemx9RGAU9nqpPYC4S6C/Dnw9gwcx96+sTISG/6rsY=
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec h1:ENemx9RGAU9nqpPYC4S6C/Dnw9gwcx96+sTISG/6rsY=
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||||
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241023090605-10cff9173059 h1:TPAYdTKKUjgxtCnK38d1Tb4teyQp1C7wYHPdR32yZtM=
|
||||||
|
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241023090605-10cff9173059/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687 h1:uQcGqdzi4UdpZlp4f4FUPeBqoygP58pEKJkmN3ROsE0=
|
||||||
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687/go.mod h1:gf7SW2TXATgux8pfdFedMkXWv2515OtIIM/5c4atkFw=
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20240325080031-1f58204e8687/go.mod h1:gf7SW2TXATgux8pfdFedMkXWv2515OtIIM/5c4atkFw=
|
||||||
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241023104258-2e0a298aa558 h1:ZVJyyDKfYeA3TsN8UOi4IprkouK4wIIfCKe+F9byLWA=
|
||||||
|
git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241023104258-2e0a298aa558/go.mod h1:/9eicss/Dt9tp2jwZ/4cXDqDKo/Dez+HuT5/NGdqW+s=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 h1:GO3oZa5a2sqwAzGcLDJtQzmshSWRmoP7IDS8bwFqvC4=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253 h1:GO3oZa5a2sqwAzGcLDJtQzmshSWRmoP7IDS8bwFqvC4=
|
||||||
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20231227095334-7eb5cdbf9253/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI=
|
||||||
|
git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI=
|
||||||
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
|
||||||
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
@ -12,12 +18,16 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
|||||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||||
github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
|
github.com/go-resty/resty/v2 v2.13.1 h1:x+LHXBI2nMB1vqndymf26quycC4aggYJ7DECYbiz03g=
|
||||||
github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
|
github.com/go-resty/resty/v2 v2.13.1/go.mod h1:GznXlLxkq6Nh4sU59rPmUw3VtgpO3aS96ORAI6Q7d+0=
|
||||||
|
github.com/go-resty/resty/v2 v2.15.3 h1:bqff+hcqAflpiF591hhJzNdkRsFhlB96CYfBwSFvql8=
|
||||||
|
github.com/go-resty/resty/v2 v2.15.3/go.mod h1:0fHAoK7JoBy/Ch36N8VFeMsK7xQOHhvWaC3iOktwmIU=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
|
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||||
|
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||||
@ -40,6 +50,8 @@ golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
|||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
|
||||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||||
|
golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4=
|
||||||
|
golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
7
resty.go
7
resty.go
@ -10,6 +10,7 @@ package httpclient
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"git.zhangdeman.cn/gateway/httpclient/define"
|
"git.zhangdeman.cn/gateway/httpclient/define"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
"git.zhangdeman.cn/zhangdeman/serialize"
|
"git.zhangdeman.cn/zhangdeman/serialize"
|
||||||
"github.com/go-resty/resty/v2"
|
"github.com/go-resty/resty/v2"
|
||||||
"github.com/tidwall/gjson"
|
"github.com/tidwall/gjson"
|
||||||
@ -67,12 +68,12 @@ func setRestyBody(reqConfig *define.Request, request *resty.Request) {
|
|||||||
if nil == reqConfig.Body || len(reqConfig.Body) == 0 {
|
if nil == reqConfig.Body || len(reqConfig.Body) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.Contains(strings.ToLower(reqConfig.ContentType), "application/json") {
|
if strings.Contains(strings.ToLower(reqConfig.ContentType), consts.MimeTypeJson) {
|
||||||
request.SetBody(reqConfig.Body)
|
request.SetBody(reqConfig.Body)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.Contains(strings.ToLower(reqConfig.ContentType), "application/x-www-form-urlencodeds") {
|
if strings.Contains(strings.ToLower(reqConfig.ContentType), consts.MimeTypeXWWWFormUrlencoded) {
|
||||||
bodyStr := serialize.JSON.MarshalForString(reqConfig.Body)
|
bodyStr := serialize.JSON.MarshalForStringIgnoreError(reqConfig.Body)
|
||||||
bodyData := map[string]string{}
|
bodyData := map[string]string{}
|
||||||
jsonObj := gjson.Parse(bodyStr)
|
jsonObj := gjson.Parse(bodyStr)
|
||||||
jsonObj.ForEach(func(key, value gjson.Result) bool {
|
jsonObj.ForEach(func(key, value gjson.Result) bool {
|
||||||
|
Reference in New Issue
Block a user