From 38d8978f126f3ac7898038cc25c7617badf5dabb Mon Sep 17 00:00:00 2001 From: sesky4 Date: Wed, 27 Mar 2024 10:11:48 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=20OmitBehaviour=20?= =?UTF-8?q?=E6=9D=A5=E6=8E=A7=E5=88=B6=20json=20=E5=BA=8F=E5=88=97?= =?UTF-8?q?=E5=8C=96=E7=9A=84=20omitnil=20=E8=A1=8C=E4=B8=BA=20(#260)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add UseEmptyNil --- README.md | 4 +-- examples/common/omitempty.go | 45 ++++++------------------------ tencentcloud/common/json/encode.go | 17 ++++++++++- 3 files changed, 25 insertions(+), 41 deletions(-) diff --git a/README.md b/README.md index 0f02e95d15..f5b0e0b159 100644 --- a/README.md +++ b/README.md @@ -612,9 +612,7 @@ func main() { 在 >= v1.0.739 的版本, SDK使用`omitnil`标签来序列化请求, 此时nil数组会被忽略掉, 但是空数组可以被正常发送。 -需要注意的是这个改动在大部分情况下对于用户是无感知的, 但是在特殊情况下依然可能会造成行为不一致。 - -参考[示例](https://github.com/TencentCloud/tencentcloud-sdk-go/blob/master/examples/common/omitempty.go) +在 >= v1.0.885 版本中我们对这一特性增加了开关, 当你不希望发送一个空数组时, 可以通过 `json.OmitBehaviour = json.OmitEmpty` 来关闭该特性, 参考[示例](https://github.com/TencentCloud/tencentcloud-sdk-go/blob/master/examples/common/omitempty.go) # 支持产品列表 diff --git a/examples/common/omitempty.go b/examples/common/omitempty.go index fa85a7ff82..290b0d8a2a 100644 --- a/examples/common/omitempty.go +++ b/examples/common/omitempty.go @@ -3,7 +3,7 @@ package main import ( "fmt" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common" - tchttp "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/http" + "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/json" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/profile" "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common/regions" trtc "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/trtc/v20190722" @@ -11,17 +11,17 @@ import ( ) func main() { - //SDK 使用 `omitempty` 标签来序列化你的 request 对象, 因为这样可以避免上报空数组/对象. - //但对有的接口而言, 长度为0的数组 和 nil数组 是有区别的, 如果你希望在请求中携带空数组, 需要使用Common Client 来发送请求. + // SDK 使用 `omitnil` 标签来序列化你的 request 对象, 因为这样可以区分 `nil数组` 和 `长度为0的数组` - // 错误的做法 - wrongWay() + // SDK 默认会发送 `长度为0的数组` 而忽略 `nil数组` + sendJsonRequest() - // 正确的做法 - rightWay() + // 当你不希望发送一个 `长度为0的数组` 时, 可以通过 json.OmitBehaviour 来关闭此特性 + json.OmitBehaviour = json.OmitEmpty + sendJsonRequest() } -func wrongWay() { +func sendJsonRequest() { credential := common.NewCredential( os.Getenv("TENCENTCLOUD_SECRET_ID"), os.Getenv("TENCENTCLOUD_SECRET_KEY")) @@ -43,32 +43,3 @@ func wrongWay() { fmt.Println(response.ToJsonString()) } - -func rightWay() { - credential := common.NewCredential( - os.Getenv("TENCENTCLOUD_SECRET_ID"), - os.Getenv("TENCENTCLOUD_SECRET_KEY")) - cpf := profile.NewClientProfile() - cpf.Debug = true - - client := common.NewCommonClient(credential, regions.Guangzhou, cpf) - request := tchttp.NewCommonRequest("trtc", "2019-07-22", "UpdatePublishCdnStream") - req := map[string]interface{}{ - "PublishCdnParams": []*trtc.McuPublishCdnParam{}, - } - - // 发送的请求body为 `{"PublishCdnParams":[]}` - err := request.SetActionParameters(req) - if err != nil { - panic(err) - } - - response := tchttp.NewCommonResponse() - - err = client.Send(request, response) - if err != nil { - fmt.Printf("fail to invoke api: %v \n", err) - } - - fmt.Println(string(response.GetBody())) -} diff --git a/tencentcloud/common/json/encode.go b/tencentcloud/common/json/encode.go index 6b3dc77c96..eecf128774 100644 --- a/tencentcloud/common/json/encode.go +++ b/tencentcloud/common/json/encode.go @@ -635,12 +635,27 @@ type structEncoder struct { fieldEncs []encoderFunc } +const ( + OmitNil = 0 + iota + OmitEmpty +) + +var OmitBehaviour = OmitNil + +func shouldOmit(f field, fv reflect.Value) bool { + if OmitBehaviour == OmitNil { + return !fv.IsValid() || (f.omitNil || f.omitEmpty) && isNilValue(fv) + } else { + return !fv.IsValid() || (f.omitNil || f.omitEmpty) && isEmptyValue(fv) + } +} + func (se *structEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) { e.WriteByte('{') first := true for i, f := range se.fields { fv := fieldByIndex(v, f.index) - if !fv.IsValid() || (f.omitNil || f.omitEmpty) && isNilValue(fv) { + if shouldOmit(f, fv) { continue } if first {