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

[Question] google/protobuf/timestamp.proto 转 json 问题 #2646

Closed
gaoyong06 opened this issue Feb 2, 2023 · 7 comments
Closed

[Question] google/protobuf/timestamp.proto 转 json 问题 #2646

gaoyong06 opened this issue Feb 2, 2023 · 7 comments
Labels
question Further information is requested

Comments

@gaoyong06
Copy link

大家有没有遇到过这个下面类似的问题

pb文件里面定义的是类似下面这样:

syntax = "proto3";
package user_service.v1;
import "google/protobuf/timestamp.proto";
.....

message test {
....
google.protobuf.Timestamp createdAt = 16;
google.protobuf.Timestamp updatedAt = 17;
}

最后http API 返回的结构是:
{
"createdAt": {
"seconds": 1675240331
},
"updatedAt": {
"seconds": 1675240331
}
}

期望返回的结构类似:
{
"createdAt": "2022-06-29T02:08:07.100Z",
"updatedAt": "2022-06-29T02:08:07.100Z"
}

@gaoyong06 gaoyong06 added the question Further information is requested label Feb 2, 2023
@shenqidebaozi
Copy link
Member

这个是 protojson 进行的序列化,建议查看 protojson 文档https://pkg.go.dev/google.golang.org/[email protected]/encoding/protojson

@gaoyong06
Copy link
Author

这个是 protojson 进行的序列化,建议查看 protojson 文档https://pkg.go.dev/google.golang.org/[email protected]/encoding/protojson

看了半天,懵懵懂懂,那个大佬有具体的解决办法,麻烦贴一下代码,学习一下

@shenqidebaozi
Copy link
Member

我的意思是这是 protojson 序列化的结果,没办法修改,可以考虑使用 string 之类的类型

@shenqidebaozi
Copy link
Member

另外 timestamp 本身就是时间戳的意思。

@gaoyong06
Copy link
Author

gaoyong06 commented Feb 4, 2023

这个问题,最后发现是因为,使用了下面这个文章的方法,对返回值做了包装导致
https://mp.weixin.qq.com/s/4ocdoAVXXKTvJ3U65YXltw

这个方式,有个实际的问题,就是“零值”问题,有"零值"在返回的json里面会不显示,原因是omitempty在json的序列化中会生效,导致默认值的数据返回并不完整

在下面这个文章里面也有讨论
#1281

更具体的原因是:
github.com\go-kratos\kratos\[email protected]\encoding\json\json.go 中下面这段代码

func (codec) Marshal(v interface{}) ([]byte, error) {
	switch m := v.(type) {
	case json.Marshaler:
		return m.MarshalJSON()
	case proto.Message:
		return MarshalOptions.Marshal(m)
	default:
		return json.Marshal(m)
	}
}

@shenqidebaozi
Copy link
Member

明白了

使用了非 proto 类型的结构体,导致无法使用 protojson 进行序列化,其实如果需要包装通用结构可以使用其他方式来实现,避免使用了错误的序列化

@shenqidebaozi
Copy link
Member

#1952 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants