JSON的使用场景及注意事项介绍
上篇我们讲解了JSON的诞生原因是因为XML整合到HTML中各个浏览器实现的细节不尽相同,所以道格拉斯·克罗克福特(Douglas Crockford) 和 奇普·莫宁斯达(Chip Morningstar)一起从JS的数据类型中提取了一个子集,作为新的数据交换格式,因为主流的浏览器使用了通用的JavaScript引擎组件,所以在解析这种新数据格式时就不存在兼容性问题,于是他们将这种数据格式命名为 “JavaScript Object Notation”,缩写为 JSON,由此JSON便诞生了!
今天我们来学习一下JSON的结构形式、数据类型、使用场景以及注意事项吧!
一、JSON格式
上面我们知道JSON是从JavaScript的数据类型中提取出来的子集,那JSON有几种结构形式呢?又有哪些数据类型呢?他们又分别对应着JavaScript中的哪些数据类型呢?
1.JSON的2种结构形式
1、键值对形式
上期我们举了一个JSON的实例,就是键值对形式的,如下:
{
"person": {
"name": "pig",
"age": "18",
"sex": "man",
"hometown": {
"province": "江西省",
"city": "抚州市",
"county": "崇仁县"
}
}
}
这种结构的JSON数据规则是:一个无序的“‘名称/值’对”集合。一个对象以 {左括号 开始, }右括号 结束。每个“名称”后跟一个 :冒号 ;“‘名称/值’ 对”之间使用 ,逗号 分隔,。
2、数组形式
因为大多数时候大家用的JSON可能都是上面那种key-value形式,所以很多人在讲解JSON的时候总是会忽略数组形式,这一点是需要注意的。
那JSON的数组形式是怎么样的呢?猪哥也举一个实例吧!
["pig", 18, "man", "江西省抚州市崇仁县"]
数组形式的JSON数据就是值(value)的有序集合。一个数组以 [左中括号 开始, ]右中括号 结束。值之间使用 ,逗号 分隔。
2.JOSN的6种数据类型
上面两种JSON形式内部都是包含value的,那JSON的value到底有哪些类型,而且上期我们说JSON其实就是从Js数据格式中提取了一个子集,那具体有哪几种数据类型呢?
- string:字符串,必须要用双引号引起来。
- number:数值,与JavaScript的number一致,整数(不使用小数点或指数计数法)最多为 15 位。小数的最大位数是 17。
- object:JavaScript的对象形式,{ key:value }表示方式,可嵌套。
- array:数组,JavaScript的Array表示方式[ value ],可嵌套。
- true/false:布尔类型,JavaScript的boolean类型。
- null:空值,JavaScript的null。
以上数据形式图片来源JSON官方文档:http://www.json.org/json-zh.html
二、JSON使用场景
介绍完JSON的数据格式,那我们来看看JSON在企业中使用的比较多的场景。
1.接口返回数据
JSON用的最多的地方莫过于Web了,现在的数据接口基本上都是返回的JSON,具体细化的场景有:
- Ajxa异步访问数据
- RPC远程调用
- 前后端分离后端返回的数据
- 开放API,如百度、高德等一些开放接口
- 企业间合作接口
这种API接口一般都会提供一个接口文档,说明接口的入参、出参等,
一般的接口返回数据都会封装成JSON格式,比如类似下面这种
{
"code": 1,
"msg": "success",
"data": {
"name": "pig",
"age": "18",
"sex": "man",
"hometown": {
"province": "江西省",
"city": "抚州市",
"county": "崇仁县"
}
}
}
2.序列化
程序在运行时所有的变量都是保存在内存当中的,如果出现程序重启或者机器宕机的情况,那这些数据就丢失了。一般情况运行时变量并不是那么重要丢了就丢了,但有些内存中的数据是需要保存起来供下次程序或者其他程序使用。
保存内存中的数据要么保存在数据库,要么保存直接到文件中,而将内存中的数据变成可保存或可传输的数据的过程叫做序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
正常的序列化是将编程语言中的对象直接转成可保存或可传输的,这样会保存对象的类型信息,而JSON序列化则不会保留对象类型!
为了让大家更直观的感受区别,猪哥用代码做一个测试,大家一目了然
- Python对象直接序列化会保存class信息,下次使用loads加载到内存时直接变成Python对象。
- JSON对象序列化只保存属性数据,不保留class信息,下次使用loads加载到内存可以直接转成dict对象,当然也可以转为Person对象,但是需要写辅助方法。
对于JSON序列化不能保存class信息的特点,那JSON序列化还有什么用?答案是当然游有用,对于不同编程语言序列化读取有用,比如:我用Python爬取数据然后转成对象,现在我需要将它序列化磁盘,然后使用Java语言读取这份数据,这个时候由于跨语言数据类型不同,所以就需要用到JSON序列化。
存在即合理,两种序列化可根据需求自行选择!
3.生成Token
首先声明Token的形式多种多样,有JSON、字符串、数字等等,只要能满足需求即可,没有规定用哪种形式。
JSON格式的Token最有代表性的莫过于JWT(JSON Web Tokens)。
随着技术的发展,分布式web应用的普及,通过Session管理用户登录状态成本越来越高,因此慢慢发展成为Token的方式做登录身份校验,然后通过Token去取Redis中的缓存的用户信息,随着之后JWT的出现,校验方式更加简单便捷化,无需通过Redis缓存,而是直接根据Token取出保存的用户信息,以及对Token可用性校验,单点登录更为简单。
猪哥也曾经使用JWT做过app的登录系统,大概的流程就是:
- 用户输入用户名密码
- app请求登录中心验证用户名密码
- 如果验证通过则生成一个Token,其中Token中包含:用户的uid、Token过期时间、过期延期时间等,然后返回给app
- app获得Token,保存在cookie中,下次请求其他服务则带上
- 其他服务获取到Token之后调用登录中心接口验证
- 验证通过则响应
JWT登录认证有哪些优势:
- 性能好:服务器不需要保存大量的session
- 单点登录(登录一个应用,同一个企业的其他应用都可以访问):使用JWT做一个登录中心基本搞定,很容易实现。
- 兼容性好:支持移动设备,支持跨程序调用,Cookie 是不允许垮域访问的,而 Token 则不存在这个问题。
- 安全性好:因为有签名,所以JWT可以防止被篡改。
更多JWT相关知识自行在网上学习,本文不过多介绍!
4.配置文件
说实话JSON作为配置文件使用场景并不多,最具代表性的就是npm的package.json包管理配置文件了,下面就是一个npm的package.json配置文件内容。
{
"name": "server", //项目名称
"version": "0.0.0",
"private": true,
"main": "server.js", //项目入口地址,即执行npm后会执行的项目
"scripts": {
"start": "node ./bin/www" ///scripts指定了运行脚本命令的npm命令行缩写
},
"dependencies": {
"cookie-parser": "~1.4.3", //指定项目开发所需的模块
"debug": "~2.6.9",
"express": "~4.16.0",
"http-errors": "~1.6.2",
"jade": "~1.11.0",
"morgan": "~1.9.0"
}
}
但其实JSON并不合适做配置文件,因为它不能写注释、作为配置文件的可读性差等原因。
配置文件的格式有很多种如:toml、yaml、xml、ini等,目前很多地方开始使用yaml作为配置文件。
三、JSON在Python中的使用
最后我们来看看Python中操作JSON的方法有哪些,在Python中操作JSON时需要引入json
标准库。
import json
1.类型转换
1、Python类型转JSON:json.dump()
# 1、Python的dict类型转JSON
person_dict = {'name': 'pig', 'age': 18, 'sex': 'man', 'hometown': '江西抚州'}
# indent参数为缩进空格数
person_dict_json = json.dumps(person_dict, indent=4)
print(person_dict_json, '\n')
# 2、Python的列表类型转JSON
person_list = ['pig', 18, 'man', '江西抚州']
person_list_json = json.dumps(person_list)
print(person_list_json, '\n')
# 3、Python的对象类型转JSON
person_obj = Person('pig', 18, 'man', '江西抚州')
# 中间的匿名函数是获得对象所有属性的字典形式
person_obj_json = json.dumps(person_obj, default=lambda obj: obj.__dict__, indent=4)
print(person_obj_json, '\n')
执行结果:
2、JSON转Python类型:json.loads()
# 4、JSON转Python的dict类型
person_json = '{ "name": "pig","age": 18, "sex": "man", "hometown": "江西抚州"}'
person_json_dict = json.loads(person_json)
print(type(person_json_dict), '\n')
# 5、JSON转Python的列表类型
person_json2 = '["pig", 18, "man", "江西抚州"]'
person_json_list = json.loads(person_json2)
print(type(person_json_list), '\n')
# 6、JSON转Python的自定义对象类型
person_json = '{ "name": "pig","age": 18, "sex": "man", "hometown": "江西抚州"}'
# object_hook参数是将dict对象转成自定义对象
person_json_obj = json.loads(person_json, object_hook=lambda d: Person(d['name'], d['age'], d['sex'], d['hometown']))
print(type(person_json_obj), '\n')
执行结果如下:
2.对应的数据类型
上面我们演示了Python类型与JSON的相互转换,最开始的时候我们讲过JSON有6种数据类型,那这6种数据类型分别对应Python中的哪些数据类型呢?
3.需要注意的点
- JSON的键名和字符串都必须使用双引号引起来,而Python中单引号也可以表示为字符串,所以这是个比较容易犯的错误!
- Python类型与JSON相互转换的时候到底是用
load/dump
还是用loads\dumps
?他们之间有什么区别?什么时候该加s
什么时候不该加s
?这个我们可以通过查看源码找到答案:不加s
的方法入参多了一个fp
表示filepath,最后多了一个写入文件的操作。所以我们在记忆的时候可以这样记忆:加s
表示转成字符串(str),不加s
表示转成文件。 - Python自定义对象与JSON相互转换的时候需要辅助方法来指明属性与键名的对应关系,如果不指定一个方法则会抛出异常!
- 相信有些看的仔细的同学会好奇上面猪哥使用json.dumps方法将Python类型转JSON的时候,如果出现中文,则会出现:\u6c5f\u897f\u629a\u5dde这种东西,这是为什么呢?原因是:Python 3中的json在做dumps操作时,会将中文转换成unicode编码,并以16进制方式存储,而并不是UTF-8格式!
四、总结
今天我们学习了JSON的2种形式,切记JSON还有[...]
这种形式的。
学习了JSON的6种数据类型他们分别对于Python中的哪些类型。
了解了JSON的一些使用场景以及实际的例子。
还学习了在Python中如何使用JSON以及需要注意的事项。
结合上期的JSON的诞生与发展介绍,我们JSON相关的知识基本就介绍的差不多,后面会出一些爬虫实际案例来教大家如何解析返回JSON数据。
一个JSON知识点却分两篇长文(近万字)来讲,其重要性不言而喻。因为不管你是做爬虫、还是做数据分析、web、甚至前端、测试、运维,JSON都是你必须要掌握的一个知识点!
JSON的使用场景及注意事项介绍的更多相关文章
- 转: .NET MVC3 几种返回 JSON 对象的方式和注意事项
.NET MVC3 几种返回 JSON 对象的方式和注意事项 转自:http://blog.csdn.net/xxj_jing/article/details/7382589 引言在用 .NET MV ...
- XML 和 JSON 的使用场景
我们都知道 JSON 和 XML 设计的初衷里都包含一点是对人类友好, 所以两者在这方面属于竞争关系. 而在 UI 描述上, 我觉得 XML 是比 JSON 要优异很多. 我们先来看一组简单的数据排版 ...
- Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍
大家好,又见面了. 到这里呢,已经是本SpringData JPA系列文档的第三篇了,先来回顾下前面两篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring ...
- 客户端相关知识学习(一)之混合开发,为什么要在App中使用H5页面以及应用场景、注意事项
混合开发 随着移动互联网的高速发展,常规的开发速度已经渐渐不能满足市场需求.原生H5混合开发应运而生,目前,市场上许多主流应用都有用到混合开发,例如支付宝.美团等.下面,结合我本人的开发经验,简单谈一 ...
- 面试官:ThreadLocal的应用场景和注意事项有哪些?
前言 ThreadLocal主要有如下2个作用 保证线程安全 在线程级别传递变量 保证线程安全 最近一个小伙伴把项目中封装的日期工具类用在多线程环境下居然出了问题,来看看怎么回事吧 日期转换的一个工具 ...
- 谈谈ThreadLocal的应用场景和注意事项?
特点 ThreadLocal和Sychronized都用于解决多线程间的并发访问,但它们实现的本质方法不同:sychronized利用锁使同一个代码块或变量在某时刻只能被一个线程访问,而ThreadL ...
- tcp_tw_reuse、tcp_tw_recycle 使用场景及注意事项
linux TIME_WAIT 相关参数: net.ipv4.tcp_tw_reuse = 表示开启重用.允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭 net.i ...
- Cocos2d-x场景变化相关功能介绍
现场由导演级交换机Director实现.之间的相关的功能,如下面: runWithScene(Scene* scene).该函数能够执行场景.仅仅能在启动第一个场景时候调用该函数.假设已经有一个场景执 ...
- 微信小程序节点查询方法:wx.createSelectorQuery()的使用场景与注意事项
小程序由于内置于微信,这使得它有了得天独厚的宣传和使用优势,本着学习的心态,我在官网上看了一遍开发文档,大致得出小程序框架的设计模式与使用注意事项(重点来了,其实开发文档某些方面叙述的并不仔细,甚至存 ...
随机推荐
- Linux常用命令及示例(全)
NO 分类 PS1 命令名 用法及参数 功能注解1 显示目录信息 # ls ls -a 列出当前目录下的所有文件,包括以.头的隐含文件 # ls ls -l或ll 列出当前目录下文件的详细信息 # l ...
- 数据结构(四十五)选择排序(1.直接选择排序(O(n²))2.堆排序(O(nlogn)))
一.选择排序的定义 选择排序的基本思想是:每次从待排序的数据元素集合中选取最小(或最大)的数据元素放到数据元素集合的最前(或最后),数据元素集合不断缩小,当数据元素集合为空时排序过程结束.常用的选择排 ...
- (二)Kinect关节识别
基础:添加KinectManager 组件 1)局部关节获取(参考插件场景KinectOverlayDemo1) 要获取局部某一关节及其位置,添加脚本JointOverlayer即可,通过Tracke ...
- jquery获取dom属性方法
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 神舟+win10+ubuntu16.04+256GSSD+1THHD双系统安装加openssl踩坑之旅
上海最近搞活动调休,要搞深度学习,win上还是不方便,准备弄个ubuntu.于是有以下回忆文字. 在机器上装了个双系统.花了两天.再也不想玩了. 准备用ubuntu来做深度学习的. 本文写于2019年 ...
- Windows 10 与 kali 双系统安装
一.教程中用到的工具如下: 1.kali 2019镜像, 2.U盘 现在最低也有8G吧 3.软碟通 ,U盘刻录工具 4.win 10系统要留出一个空的硬盘,哪个盘的空间比较大可以压缩出大概100G的空 ...
- C语言1作业5
问题 答案 这个作业属于那个课程 C语言程序设计1 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-2 我在这个课程的目的是 学习并掌握C ...
- 学习笔记03http协议
1.浏览器就是一个sokect客户端,使用http协议与服务器进行交流.http请求:请求头:(请求方法)sp(url)sp http/1.x <cr><lf>(通用头类型名) ...
- CSPS模拟 91
T1 sz最多根号种 T2 没计算内存,水过了..CSPS这样的话要爆零的qaq T3 感谢miku带我重学ST表%%%%%
- KETTLE常见问题和优化
1.创建MySQL空资源库报错问题:因为boolean类型的问题,Mysql中的boolean类型实际上保存为TINYINT,需要手动的修改生成资源库的sql脚本,将其中的插入用户ENABLED的值由 ...