Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

In standard routing, when the input parameter is JSON Array, json.RawMessage cannot be used #3449

Closed
shuqingzai opened this issue Apr 2, 2024 · 1 comment
Labels
bug It is confirmed a bug, but don't worry, we'll handle it.

Comments

@shuqingzai
Copy link

What version of Go and system type/arch are you using?

#-> % go version
go version go1.21.7 darwin/amd64

What version of GoFrame are you using?

#-> % gf version
v2.6.4
Welcome to GoFrame!
Env Detail:
  Go Version: go1.21.7 darwin/amd64
  GF Version(go.mod):
    github.com/gogf/gf/v2@v2.6.4
CLI Detail:
  Installed At: /Code/go/bin/gf
  Built Go Version: go1.21.7
  Built GF Version: v2.6.4
Others Detail:
  Docs: https://goframe.org
  Now : 2024-03-11T13:36:04+08:00

Can this bug be re-produced with the latest release?

What did you do?

示例代码

package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
)

type HelloReq struct {
	g.Meta `path:"/hello" method:"POST" sm:"hello" tags:"示例"`

	Name    string          `json:"name" v:"required" dc:"名称"`
	JSONRaw json.RawMessage `json:"jsonRaw" dc:"原始JSON"`
}
type HelloRes struct {
	Name    string          `json:"name" v:"required" dc:"名称"`
	JSONRaw json.RawMessage `json:"jsonRaw" dc:"原始JSON"`
}

type Hello struct {
}

func (Hello) Say(_ context.Context, req *HelloReq) (res *HelloRes, err error) {
	fmt.Printf("req.Name: %s\n", req.Name)
	fmt.Printf("req.JSONRaw: %s\n", string(req.JSONRaw))
	res = &HelloRes{
		Name:    req.Name,
		JSONRaw: req.JSONRaw,
	}
	return
}

func main() {
	s := g.Server()
	s.Use(ghttp.MiddlewareHandlerResponse)
	s.Group("/", func(group *ghttp.RouterGroup) {
		group.Bind(
			new(Hello),
		)
	})
	s.Run()
}

请求示例

  1. JSON 使用 Object ,这是可以的
curl --location --request POST 'http://127.0.0.1:8199/hello' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--data-raw '{
  "name": "string",
  "jsonRaw": {
        "jkey": "value1",
        "jkey2": 2
    }
}'
  1. JSON 使用 Array ,无法序列化
curl --location --request POST 'http://127.0.0.1:8199/hello' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--data-raw '{
  "name": "string",
  "jsonRaw": [
    {
        "jkey": "value1",
        "jkey2": 2
    },
    {
        "jkey": "value12",
        "jkey2": 22
    }
  ]
}'

由于 Array 无法序列化,导致我直接输出原参数会报错

WriteJson failed: json.Marshal failed: json: error calling MarshalJSON for type json.RawMessage: invalid character '\x00' looking for beginning of value

参考:

case "RawMessage", "json.RawMessage":

其中使用 Bytes 转换,导致无法获取源数据,参考:

for i := range bytes {

What did you expect to see?

What did you see instead?

@shuqingzai shuqingzai added the bug It is confirmed a bug, but don't worry, we'll handle it. label Apr 2, 2024
@Issues-translate-bot Issues-translate-bot changed the title 标准路由中,入参是 JSON Array 时,无法使用 json.RawMessage In standard routing, when the input parameter is JSON Array, json.RawMessage cannot be used Apr 2, 2024
wln32 pushed a commit to wln32/gf that referenced this issue Apr 4, 2024
@wln32
Copy link
Member

wln32 commented Apr 6, 2024

hi @shuqingzai 你可以尝试注册一个自定义的转换函数,实现如下
由于数组类型的json.RawMessage,在gf解析参数的时候会被解析为[]any,内部实际是[]map[strin]any
所以自定义转换函数的参数是[]any,希望能够帮助到你

func SliceAnyToMyJSONRaw(src []any) (*json.RawMessage, error) {
	fmt.Println("[]any to jsonraw", src)
	// return src, nil
	bytes, err := json.Marshal(src)
	if err != nil {
		return nil, err
	}
	return (*json.RawMessage)(&bytes), nil
}

@gqcn gqcn closed this as completed in 83ba887 Apr 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug It is confirmed a bug, but don't worry, we'll handle it.
Projects
None yet
Development

No branches or pull requests

2 participants