json: 无效使用字符串结构标签

huangapple go评论113阅读模式
英文:

json: invalid use of string struct tag

问题

我正在尝试编写一个简单的POST无服务器Go AWS Lambda函数。

package main

import (
	"fmt"
)

import (
	"encoding/json"
	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
)

// RequestBodyType是我们自定义的结构,用于处理来自客户端的JSON请求
type RequestBodyType struct {
	Event       string `json:"event,omitempty"`
	EventParams EventParamsType
}

// ResponseBodyType是我们自定义的结构,用于构建客户端的响应
type ResponseBodyType struct {
	Event       string `json:"event,omitempty"`
	EventParams EventParamsType
}

// 可能有问题的结构体?
type EventParamsType struct {
	Name string `json:"name,omitempty"`
	Age  int64  `json:"age,omitempty"`
}

// 使用AWS Lambda代理请求的处理程序函数
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {

	// RequestBody将用于接收来自客户端的JSON响应并构建它
	requestBody := RequestBodyType{
		Event: "",
		EventParams: EventParamsType{
			Name: "",
			Age:  0,
		},
	}

	// 反序列化JSON,如果出错则返回404
	err := json.Unmarshal([]byte(request.Body), &requestBody)
	if err != nil {
		return events.APIGatewayProxyResponse{Body: err.Error(), StatusCode: 404}, nil
	}

	// 我们将构建BodyResponse并以JSON形式发送回去
	responseBody := &ResponseBodyType{
		Event: requestBody.Event,
		EventParams: EventParamsType{
			Name: requestBody.EventParams.Name,
			Age:  requestBody.EventParams.Age,
		},
	}

	fmt.Println("RESPONSE BODY")
	fmt.Println(responseBody)

	// 将响应编组为JSON字节,如果出错则返回404
	response, err := json.Marshal(&responseBody)
	if err != nil {
		return events.APIGatewayProxyResponse{Body: err.Error(), StatusCode: 404}, nil
	}

	// 使用AWS Lambda代理响应返回响应
	return events.APIGatewayProxyResponse{Body: string(response), StatusCode: 200}, nil
}

func main() {
	lambda.Start(Handler)
}

如果我使用单个JSON对象键进行curl请求,一切正常,例如:

curl -X POST https://my.url/dev/event  -d '{"event": "test"}'

我会得到响应:

{"Event":"test","EventParams":{}}

但是,如果我使用嵌套的JSON对象进行请求,例如:

curl -X POST https://my.url/dev/event  -d '{"event": "test","eventParams": {"name": "peter","age": 13}}'

然后我会得到响应:

json: invalid use of ,string struct tag, trying to unmarshal "peter" into string

我认为我可能错误地设计了EventParamsType结构体?或者我构建ResponseBodyType的方式有问题?

英文:

I'm trying to write simple POST serverless Go AWS lambda function.

package main
import (
"fmt"
)
import (
"encoding/json"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
)
// RequestBodyType is our self-made struct to process JSON request from Client
type RequestBodyType struct {
Event       string `string:"event,string,omitempty"`
EventParams EventParamsType
}
// ResponseBodyType is our self-made struct to build response for Client
type ResponseBodyType struct {
Event       string `string:"event,string,omitempty"`
EventParams EventParamsType
}
// Probably problematic struct?
type EventParamsType struct {
Name string `json:"name,string,omitempty"`
Age  int64  `json:"age,omitempty"`
}
// Handler function Using AWS Lambda Proxy Request
func Handler(request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
// RequestBody will be used to take the json response from client and build it
requestBody := RequestBodyType{
Event: "",
EventParams: EventParamsType{
Name: "",
Age:  0,
},
}
// Unmarshal the json, return 404 if error
err := json.Unmarshal([]byte(request.Body), &requestBody)
if err != nil {
return events.APIGatewayProxyResponse{Body: err.Error(), StatusCode: 404}, nil
}
// We will build the BodyResponse and send it back in json form
responseBody := &ResponseBodyType{
Event:       requestBody.Event,
EventParams: EventParamsType{
Name: requestBody.EventParams.Name,
Age: requestBody.EventParams.Age,	
},
}
fmt.Println("RESPONSE BODY")
fmt.Println(responseBody)
// Marshal the response into json bytes, if error return 404
response, err := json.Marshal(&responseBody)
if err != nil {
return events.APIGatewayProxyResponse{Body: err.Error(), StatusCode: 404}, nil
}
//Returning response with AWS Lambda Proxy Response
return events.APIGatewayProxyResponse{Body: string(response), StatusCode: 200}, nil
}
func main() {
lambda.Start(Handler)
}

Everything works fine if I make curl request with single JSON object key, for example:

curl -X POST https://my.url/dev/event  -d '{"event": "test"}'

And I get response

{"Event":"test","EventParams":{}

But if I make request with nested json object, for example:

curl -X POST https://my.url/dev/event  -d '{"event": "test","eventParams": {"name": "peter","age": 13}}'

Then I get response

json: invalid use of ,string struct tag, trying to unmarshal "peter" into string

I believe I have probably design EventParamsType wrong way? Or am I building ResponseBodyType wrong way?

答案1

得分: 1

根据错误提示,你在JSON输入中使用的,string是无效的。请将其删除:

    Name string `json:"name,omitempty"`

在JSON标签中,,string是有效的,它表示该数字应该被编组为字符串文字。对于已经是字符串的值,这意味着它期望一个带有JSON引号的字符串(而你的输入显然不是)。

这在文档中有解释:

"string"选项表示字段以JSON形式存储在JSON编码的字符串中。它仅适用于字符串、浮点数、整数或布尔类型的字段。在与JavaScript程序通信时,有时会使用这种额外的编码级别:

Int64String int64 `json:",string"`

playground中可以查看更多详细信息。

此外,正如@Adrian指出的那样,string:是一个无意义的标签(至少对于JSON的(解)编组而言是如此)。你可能想要使用json:而不是string:(尽管某些库可能使用名为string:的标签... 🤷

英文:

As the error says, your use of ,string is invalid for your JSON input. Remove it:

    Name string `json:"name,omitempty"`

,string can be valid in a JSON tag, and it indicates that the number should be marshaled as a string literal. In the case of a value which is already a string, that means it expects a JSON-quoted string (which your input apparently is not).

This is explained in the docs:

> The "string" option signals that a field is stored as JSON inside a JSON-encoded string. It applies only to fields of string, floating point, integer, or boolean types. This extra level of encoding is sometimes used when communicating with JavaScript programs:
>
> Int64String int64 json:",string"

See in the playground for more details.

<hr>

Also, as @Adrian has pointed out, string: is a meaningless tag (for the purpose of JSON (un)marshaling, anyway). You probably want json: instead of string: (although some library may use a tag called string:... 🤷

huangapple
  • 本文由 发表于 2021年6月3日 23:11:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/67824066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定