From 83ba887df7591ee7cc1ca80cd96df514975b09bf Mon Sep 17 00:00:00 2001 From: wln32 <49137144+wln32@users.noreply.github.com> Date: Sun, 7 Apr 2024 14:09:52 +0800 Subject: [PATCH] fix: #3449 accept slice parameter as json.RawMessage for http request (#3452) --- ...ghttp_z_unit_feature_router_strict_test.go | 66 +++++++++++++++++++ util/gconv/gconv_convert.go | 10 ++- util/gconv/gconv_z_unit_struct_test.go | 27 ++++++++ 3 files changed, 102 insertions(+), 1 deletion(-) diff --git a/net/ghttp/ghttp_z_unit_feature_router_strict_test.go b/net/ghttp/ghttp_z_unit_feature_router_strict_test.go index b528f4863..923c3ab2c 100644 --- a/net/ghttp/ghttp_z_unit_feature_router_strict_test.go +++ b/net/ghttp/ghttp_z_unit_feature_router_strict_test.go @@ -15,6 +15,7 @@ import ( "github.com/gogf/gf/v2/encoding/gjson" "github.com/gogf/gf/v2/errors/gerror" "github.com/gogf/gf/v2/frame/g" + "github.com/gogf/gf/v2/internal/json" "github.com/gogf/gf/v2/net/ghttp" "github.com/gogf/gf/v2/test/gtest" "github.com/gogf/gf/v2/util/guid" @@ -419,3 +420,68 @@ func Test_Router_Handler_Strict_ParameterCaseSensitive(t *testing.T) { } }) } + +type testJsonRawMessageIssue3449Req struct { + g.Meta `path:"/test" method:"POST" sm:"hello" tags:"示例"` + + Name string `json:"name" v:"required" dc:"名称"` + JSONRaw json.RawMessage `json:"jsonRaw" dc:"原始JSON"` +} +type testJsonRawMessageIssue3449Res struct { + Name string `json:"name" v:"required" dc:"名称"` + JSONRaw json.RawMessage `json:"jsonRaw" dc:"原始JSON"` +} + +type testJsonRawMessageIssue3449 struct { +} + +func (t *testJsonRawMessageIssue3449) Test(ctx context.Context, req *testJsonRawMessageIssue3449Req) (res *testJsonRawMessageIssue3449Res, err error) { + return &testJsonRawMessageIssue3449Res{ + Name: req.Name, + JSONRaw: req.JSONRaw, + }, nil +} + +// https://github.com/gogf/gf/issues/3449 +func Test_JsonRawMessage_Issue3449(t *testing.T) { + + s := g.Server(guid.S()) + s.Use(ghttp.MiddlewareHandlerResponse) + s.Group("/", func(group *ghttp.RouterGroup) { + group.Bind(new(testJsonRawMessageIssue3449)) + }) + s.SetDumpRouterMap(false) + s.Start() + defer s.Shutdown() + + time.Sleep(100 * time.Millisecond) + gtest.C(t, func(t *gtest.T) { + client := g.Client() + client.SetPrefix(fmt.Sprintf("http://127.0.0.1:%d", s.GetListenedPort())) + v1 := map[string]any{ + "jkey1": "11", + "jkey2": "12", + } + + v2 := map[string]any{ + "jkey1": "21", + "jkey2": "22", + } + data := map[string]any{ + "Name": "test", + "jsonRaw": []any{ + v1, v2, + }, + } + + expect1 := `{"code":0,"message":"","data":{"name":"test","jsonRaw":[{"jkey1":"11","jkey2":"12"},{"jkey1":"21","jkey2":"22"}]}}` + t.Assert(client.PostContent(ctx, "/test", data), expect1) + + expect2 := `{"code":0,"message":"","data":{"name":"test","jsonRaw":{"jkey1":"11","jkey2":"12"}}}` + t.Assert(client.PostContent(ctx, "/test", map[string]any{ + "Name": "test", + "jsonRaw": v1, + }), expect2) + + }) +} diff --git a/util/gconv/gconv_convert.go b/util/gconv/gconv_convert.go index b3f264f1b..2ff5b1a94 100644 --- a/util/gconv/gconv_convert.go +++ b/util/gconv/gconv_convert.go @@ -7,9 +7,12 @@ package gconv import ( + "context" "reflect" "time" + "github.com/gogf/gf/v2/internal/intlog" + "github.com/gogf/gf/v2/internal/json" "github.com/gogf/gf/v2/os/gtime" ) @@ -270,7 +273,12 @@ func doConvert(in doConvertInput) (convertedValue interface{}) { return Maps(in.FromValue) case "RawMessage", "json.RawMessage": - return Bytes(in.FromValue) + // issue 3449 + bytes, err := json.Marshal(in.FromValue) + if err != nil { + intlog.Errorf(context.TODO(), `%+v`, err) + } + return bytes default: if in.ReferValue != nil { diff --git a/util/gconv/gconv_z_unit_struct_test.go b/util/gconv/gconv_z_unit_struct_test.go index 91339b4cc..cdc6e45b7 100644 --- a/util/gconv/gconv_z_unit_struct_test.go +++ b/util/gconv/gconv_z_unit_struct_test.go @@ -1303,6 +1303,33 @@ func Test_Struct_Issue1597(t *testing.T) { }) } +// https://github.com/gogf/gf/issues/3449 +func Test_Struct_Issue3449(t *testing.T) { + gtest.C(t, func(t *gtest.T) { + type S struct { + A int + B json.RawMessage + } + + jsonByte := []byte(`{ + "a":1, + "b":[{ + "k1": "11", + "k2": "12" + }, + { + "k1": "21", + "k2": "22" + }]}`) + data, err := gjson.DecodeToJson(jsonByte) + t.AssertNil(err) + s := &S{} + err = data.Scan(s) + t.AssertNil(err) + t.Assert(s.B, `[{"k1":"11","k2":"12"},{"k1":"21","k2":"22"}]`) + }) +} + // https://github.com/gogf/gf/issues/2980 func Test_Struct_Issue2980(t *testing.T) { type Post struct {