Golang中的JSON使用技巧

news/2024/11/8 17:36:06/

我们使用Golang开发后台时,经常会和JSON打交道,使用JSON主要是使用官方的encoding/json库,这里介绍一些和json库相关的使用技巧

关于性能

传说中老有人说官方库性能不算很好,有更好的选择,但我们基本的场景都感觉不到,如果真的项目进展到需要做性能优化的时候,再考虑其他库不迟。

多用Encoder和Decoder

我们一般会使用json.Unmarshall和json.Marshall作为主要的结构体解析和串行方法外,但在后端代码中,我更愿意用json.NewEncoder和json.NewDecoder从reader里读取。这样我就不需要使用ioutil.ReadAll来把body全部读取出来了,直接从http.Request的Body里读取。写的时候也可以直接写入到ResponseWriter就好了。

http.HandleFunc("/check", func(w http.ResponseWriter, r *http.Request) {w.Header().Add("Access-Control-Allow-Origin", origin)json.NewEncoder(w).Encode(map[string]interface{}{"success":  true,"identity": "baijiafan_test_daemon",})
})

注意默认值

因为主要是json和结构体之间的相互转换,所以golang的一个问题是要小心默认值,比如一个bool类型的值,即便实际没有传这个值,也会被赋值为false,所以有很多人喜欢用*bool这样的指针,这时候,如果并没有传这个值,Unmarshall的时候会直接设置为null,就可以进一步通过指针来判断到底是没传还是传的false。

我个人更喜欢调整定义,比如需求说这个接口增加一个是否拦截(Deny)的参数,那我们最好定义Allow而不是Deny,或者定义为NotDeny,这时候,默认的false就是默认不允许,进一步开发就不会出问题,但是如果你定义成Deny或者NotAllow,那默认false是不是就变成放行了?这时候就容易出问题。

老是有null怎么办?

活用tag里面的omitempty,这时,false,0,"", null这些值串行的时候就都会被隐藏,要不然默认情况下,传一堆null给前端,通常会被骂。

本来就是JSON内容的[]byte怎么放进大的对象里?

我们一般没办法把byte数组原封不动的串行进json字符串,比如有时,我在结构体里会有Response属性,我希望把第三方调用的结果直接放到这个属性里,这时直接放[]byte会把字符串给base64化,如果确实需要bytes作为一个子节点,要用json.RawMessage类型

func TestJson1(t *testing.T) {var str = `{"value": "1"}`var temp struct {Value []byte}temp.Value = []byte(str)bts, err := json.Marshal(temp)fmt.Println(string(bts), err)
}
输出:
{"Value":"ewoJCSJ2YWx1ZSI6ICIxIgoJfQ=="}func TestJson1(t *testing.T) {var str = `{"value": "1"}`var temp struct {Value json.RawMessage}temp.Value = []byte(str)bts, err := json.Marshal(temp)fmt.Println(string(bts), err)
}
输出
{"Value":{"value":"1"}} //成功!

前端的数字当字符串传了怎么办?

如果要从一个字符串属性中读取数字,可以使用string tag

Int64String int64 `json:",string"`

这个tag就是专门处理这种数字放进string的问题的

{"no": "3"
}

如果再BT点,我们有多个调用方客户,他们也许会传"3",也可能是3怎么办?这时可以用json.Number,例子:

func TestJson(t *testing.T) {var str = `{"value": "1"}`var temp struct {Value json.Number `json:"value"`}err := json.Unmarshal([]byte(str), &temp)fmt.Println(temp, err)i, e := temp.Value.Int64()fmt.Println(i, e)f, e := temp.Value.Float64()fmt.Println(f, e)
}
输出:
{1} <nil>
1 <nil>
1 <nil>

这个写法当str是下面形态时,一样有效

{"value": 1
}

此时,json.Number同样会获得到结果,json.Number也可以用来指代一些既可能是Int又可能是float的数据,这时我们可以使用Int64()来尝试获得int数据。

interface怎么Unmarshall

当结构体里有interface的时候比较麻烦,我们不得不在目标结构体中实现UnmarshalJson和MarshalJson两个函数用于自定义转化过程,一般我们还需要定义一个临时类型来做中间转换,或者直接使用struct定义的,类似下面例子中的temp

type Detail interface {
}Type DetailA struct {
}Type DetailB struct {
}type Result struct {Type intDetail Detail
}func(r *Result)UnmarshalJson(data []byte)error{var temp struct {Type intDetail json.RawMessage}json.Unmarshall(data,&temp)r.Type = temp.Type//先拿出Type,再根据Type做Detail的Unmarshall//Detail此时就需要根据定义选择真正的struct进行Unmarshallswitch temp.Type {case 1:var dA DetailAjson.Unmarshall(temp.Detail,&dA)r.Detail = dA....... //其他情况}
}

http://www.ppmy.cn/news/40539.html

相关文章

Pandas 秘籍:1~5

原文&#xff1a;Pandas Cookbook 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 一、Pandas 基础 在本章中&#xff0c;我们将介绍以下内容&#xff1a; 剖析数据帧的结构访问主要的数据帧组件了解数据类型选择单列数据作为序列调用序列方法与运算符一起使用序列将…

思科ASA防火墙: 接口配置名称 安全等级 acl防控列表

环境&#xff1a;上图环境 win10 内 ip&#xff1a;192.168.1.1 /24 网关 &#xff1a; 192.168.1.254 win10 外 ip&#xff1a; 172.12.12.1 /24 网关 &#xff1a;172.12.12.254 asa e0/0接口 &#xff1a; 192.168.1.254 e0/1 接口 &#xff1a; 172…

TCP并发服务器模型

文章目录1. 循环服务器2. 并发服务器2.1 多进程并发服务器2.2 多线程并发服务器3. 基于TCP的文件传输服务(目前只有下载)1.tftp下载模型2.TFTP通信过程总结3.tftp下载协议分析1. 循环服务器 一次只能处理一个客户端&#xff0c;等这个客户端退出后&#xff0c;才能处理下一个客…

Linux嵌入式学习之Ubuntu入门(四)Makefile

系列文章目录 一、Linux嵌入式学习之Ubuntu入门&#xff08;一&#xff09;基本命令、软件安装及文件结构 二、Linux嵌入式学习之Ubuntu入门&#xff08;二&#xff09;磁盘文件介绍及分区、格式化等 三、Linux嵌入式学习之Ubuntu入门&#xff08;三&#xff09;用户、用户组…

Spring Cloud快速入门

文章目录Spring Cloud快速入门一、基础概念1、微服务架构2、微服务技术栈3、什么是Spring Cloud?4、Spring Cloud和Spring Boot的联系&#xff1f;5、比较成熟的互联网架构二、Rest环境搭建1、搭建提供者1.1、创建一个父工程1.2、创建一个springcloud-api模块1.3、创建一个spr…

亚马逊云科技基于自身的技术优势,率先提出“云原生数据战略”

随着云计算技术的不断普及发展&#xff0c;制造企业希望通过更低的成本&#xff0c;运用云计算技术实现业务上云&#xff0c;借助数字化优势&#xff0c;进行新型智能制造转型升级&#xff0c;提高整体竞争实力。 2023年3月16日&#xff0c;由天津经济技术开发区发起&#xff…

Amazon SageMaker测评分享,效果超出预期

一、前言随着科技的进步和社会的发展&#xff0c;人工智能得到了愈加广泛的重视&#xff0c;特别是最近大火的Chatgpt&#xff0c;充分展现了研发通用人工智能助手广阔的研究和应用前景。让越来越多的组织和企业跟风加入到人工智能领域的研究中&#xff0c;但机器学习的实施是一…

2023年第十四届蓝桥杯Java_大学B组真题

Java_B组试题 A: 阶乘求和试题 B: 幸运数字试题 C: 数组分割试题 D: 矩形总面积试题 E: 蜗牛试题 F: 合并区域试题 G: 买二赠一试题 H: 合并石子试题 I: 最大开支试题 J: 魔法阵【考生须知】 考试开始后&#xff0c;选手首先下载题目&#xff0c;并使用考场现场公布的解压密码解…