golang,go,博客,开源,编程
Gin框架内部已预设对 jsoniter
的支持,只需在编译时添加 jsoniter
标签:
# 编译或运行命令
go build -tags=jsoniter main.go
go run -tags=jsoniter main.go
此时Gin会自动使用 jsoniter.ConfigCompatibleWithStandardLibrary
配置。
在代码中打印JSON库版本:
import (
"fmt"
"github.com/gin-gonic/gin"
"github.com/json-iterator/go"
)
func main() {
fmt.Println("Current JSON lib:", gin.Mode(), jsoniter.Version)
// 输出示例:Current JSON lib: debug 1.2.3
}
当需要PHP兼容模式、自定义时间格式等场景时:
import (
"github.com/gin-gonic/gin"
jsoniter "github.com/json-iterator/go"
"github.com/json-iterator/go/extra"
)
func main() {
// 创建自定义配置
json := jsoniter.Config{
EscapeHTML: false,
MarshalFloatWith6Digits: true,
}.Froze()
// 启用PHP风格兼容
extra.RegisterFuzzyDecoders()
// 替换Gin全局JSON绑定器
gin.DisableBindValidation()
binding.JSON = customJsonBinding{json: json}
}
type customJsonBinding struct{ json jsoniter.API }
func (b customJsonBinding) Name() string { return "json" }
func (b customJsonBinding) BindBody(body []byte, obj interface{}) error {
return b.json.Unmarshal(body, obj)
}
// 初始化时配置全局内存池
stream := jsoniter.NewStream(jsoniter.ConfigDefault, nil, 1024)
defer stream.Free()
对高频使用的结构体预生成编解码器:
type User struct {
ID int `json:"id"`
Name string `json:"name"`
}
func init() {
jsoniter.RegisterTypeEncoderFunc("User",
func(ptr unsafe.Pointer, stream *jsoniter.Stream) {
user := (*User)(ptr)
stream.WriteVal(user)
}, nil)
}
// 注册空数组转换逻辑
extra.RegisterArrayEmpty()
jsoniter.RegisterTimeAsInt64Codec(time.RFC3339)
json := jsoniter.Config{
CaseSensitive: true,
}.Froze()
操作类型 | 标准库(ops/ns) | jsoniter(ops/ns) | 提升倍数 |
---|---|---|---|
小对象反序列化 | 1890 | 732 | 2.58x |
嵌套结构序列化 | 2560 | 980 | 2.61x |
大JSON解析 | 154MB/s | 412MB/s | 2.67x |
router.Use(func(c *gin.Context) {
c.Set("jsonApi", jsoniter.ConfigFastest)
})
jsonProcessingTime := prometheus.NewSummaryVec(...)
prometheus.MustRegister(jsonProcessingTime)
Gin版本 | 支持模式 | 注意事项 |
---|---|---|
v1.6.x | 编译标签+自定义绑定 | 需禁用默认验证 |
v1.7+ | 原生集成 | 直接支持Config配置 |
v1.9+ | 自动检测jsoniter | 无需手动替换绑定器 |
通过上述方案,可在保持Gin框架原生API使用习惯的同时,获得显著的性能提升和更好的弱类型系统兼容性。