程序员都应该了解的一种数据格式之 JSON
作者 | 猪哥
责编 | maozz
JSON的诞生原因是因为XML整合到HTML中各个浏览器实现的细节不尽相同,所以道格拉斯·克罗克福特(Douglas Crockford) 和 奇普·莫宁斯达(Chip Morningstar)一起从JS的数据类型中提取了一个子集,作为新的数据交换格式,因为主流的浏览器使用了通用的JavaScript引擎组件,所以在解析这种新数据格式时就不存在兼容性问题,于是他们将这种数据格式命名为 “JavaScript Object Notation”,缩写为 JSON,由此JSON便诞生了!
今天我们来学习一下JSON的结构形式、数据类型、使用场景以及注意事项吧!
JSON格式
上面我们知道JSON是从JavaScript的数据类型中提取出来的子集,那JSON有几种结构形式呢?又有哪些数据类型呢?他们又分别对应着JavaScript中的哪些数据类型呢?
JSON的2种结构形式,键值对形式和数组形式。
举了一个JSON的实例,就是键值对形式的,如下:
{
\”person\”: {
\”name\”: \”pig\”,
\”age\”: \”18\”,
\”sex\”: \”man\”,
\”hometown\”: {
\”province\”: \”江西省\”,
\”city\”: \”抚州市\”,
\”county\”: \”崇仁县\”
}
}
}
这种结构的JSON数据规则是:一个无序的“‘名称/值’对”集合。一个对象以 {左括号 开始, }右括号 结束。每个“名称”后跟一个 :冒号 ;“‘名称/值’ 对”之间使用 ,逗号 分隔。
因为大多数的时候大家用的JSON可能都是上面那种key-value形式,所以很多人在讲解JSON的时候总是会忽略数组形式,这一点是需要注意的。
那JSON的数组形式是怎么样的呢?举一个实例吧!
[\”pig\”, 18, \”man\”, \”江西省抚州市崇仁县\”]
数组形式的JSON数据就是值(value)的有序集合。一个数组以 [左中括号 开始, ]右中括号 结束。值之间使用 ,逗号 分隔。
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类型。
-
:空值,JavaScript的。
以上数据形式图片来源JSON官方文档:http://www.json.org/json-zh.html
JSON使用场景
介绍完JSON的数据格式,那我们来看看JSON在企业中使用的比较多的场景。
接口返回数据和序列化。JSON用的最多的地方莫过于Web了,现在的数据接口基本上都是返回的JSON,具体细化的场景有:
-
Ajxa异步访问数据
-
RPC远程调用
-
前后端分离后端返回的数据
-
开放API,如百度、高德等一些开放接口
-
企业间合作接口
这种API接口一般都会提供一个接口文档,说明接口的入参、出参等,
一般的接口返回数据都会封装成JSON格式,比如类似下面这种
{
\”code\”: 1,
\”msg\”: \”success\”,
\”data\”: {
\”name\”: \”pig\”,
\”age\”: \”18\”,
\”sex\”: \”man\”,
\”hometown\”: {
\”province\”: \”江西省\”,
\”city\”: \”抚州市\”,
\”county\”: \”崇仁县\”
}
}
}
程序在运行时所有的变量都是保存在内存当中的,如果出现程序重启或者机器宕机的情况,那这些数据就丢失了。一般情况运行时变量并不是那么重要丢了就丢了,但有些内存中的数据是需要保存起来供下次程序或者其他程序使用。
保存内存中的数据要么保存在数据库,要么保存直接到文件中,而将内存中的数据变成可保存或可传输的数据的过程叫做序列化,在Python中叫pickling,在其他语言中也被称之为serialization,marshalling,flattening等等,都是一个意思。
正常的序列化是将编程语言中的对象直接转成可保存或可传输的,这样会保存对象的类型信息,而JSON序列化则不会保留对象类型!
为了让大家更直观的感受区别,猪哥用代码做一个测试,大家一目了然
-
Python对象直接序列化会保存class信息,下次使用loads加载到内存时直接变成Python对象。
-
JSON对象序列化只保存属性数据,不保留class信息,下次使用loads加载到内存可以直接转成dict对象,当然也可以转为Person对象,但是需要写辅助方法。
对于JSON序列化不能保存class信息的特点,那JSON序列化还有什么用?答案是当然有用,对于不同编程语言序列化读取有用,比如:我用Python爬取数据然后转成对象,现在我需要将它序列化磁盘,然后使用Java语言读取这份数据,这个时候由于跨语言数据类型不同,所以就需要用到JSON序列化。
存在即合理,两种序列化可根据需求自行选择!
最后就是生成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相关知识自行在网上学习,本文不过多介绍!
说实话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
类型转换
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\’)
执行结果:
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\’)
执行结果如下:
对应的数据类型
上面我们演示了Python类型与JSON的相互转换,最开始的时候我们讲过JSON有6种数据类型,那这6种数据类型分别对应Python中的哪些数据类型呢?
需要注意的点
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知识点却分两篇长文(近万字)来讲,其重要性不言而喻。因为不管你是做爬虫、还是做数据分析、web、甚至前端、测试、运维,JSON都是你必须要掌握的一个知识点
本文为作者投稿,版权归作者个人所有。
Form-Generator – Element UI 表单设计与代码生成器
Element UI 目前在中后台项目中应用广泛,是十分流行的 Vue 组件框架。而表单元素,作为最常用的用户输入组件,在设计开发过程中几乎都要涉及,且往往大同小异。能不能减少重复的代码编写工作呢?能不能甚至不写代码,点几下鼠标就能生成想要的表单呢?Form-Generator,这个基于 Element UI 框架 Form 元素的表单设计与代码生成器,就能解放你的双手。
ElementUI框架
Form-Generator,是 JakHuang 在 Github 和码云上开源的表单设计与代码生成器,项目代码位于 https://github.com/JakHuang/form-generator,国内镜像位于 https://gitee.com/mrhj/form-generator。
Form-Generator 基于 Element UI 组件库的 Form 表单组件,开发了一个表单设计器,可以在设计器中,点选不同的输入组件构建表单,设计器则会自动生成对应的 Vue 代码,可以项目中使用。也可以把设计好的表单以 JSON 的格式导出,方便存储传输,使用时利用配套的解析器把 JSON 解析为设计好的表单即可使用。
form-generator使用
Form-Generator 需要 Node.js 10+,可以使用 NPM 进行安装:
也可以自行下载项目代码进行构建:
然后安装依赖,使用 YARN
或 NPM 安装依赖
在本地运行表单设计器,运行
也可以构建之后进行部署
Form-Generator 项目配套有 JSON 解析器,可以把 JSON 转化为真实的表单代码,可以使用 NPM 安装:
另外,form-generator 还有配套的 VSCode 插件 Form Generator Plugin,使用 VSCode 的开发者们可以进行安装,帮助完成基本的表单代码搭建任务。
fms-form-generator库
Form-Generator 的主要界面是一个表单设计器:
表单设计器
可以看到,界面的左侧摆放了不同的输入组件,包括单行文本、计数器、下拉选择、日期范围和按钮等,基本满足了一般项目对于表单的所有需求。
表单设计器的组件选择
界面中间是设计得到的表单,点击左侧的组件,便可在表单中添加。同时,表单中还提供了组件的复制和删除功能,可以自由进行编辑。
界面的右侧是组件属性和表单属性,可以对当前选中的组件的各项属性进行修改,如字段名、标题、标签宽度、默认值、尺寸等,进行所需组件的定制;也可以对表单属性进行修改,包括表单模型、校验模型、标签对齐等,实现表单层级的配置。
组件属性编辑
在完成了表单的设计之后,就可以点击界面上部的运行按钮,在这里我们可以选择生成类型,包括页面和弹窗两种,其中弹窗类型会把表单嵌入到对话框组件中。
生成类型
完成类型选择后,我们就能得到生成的 Vue 代码,包括 Vue 模板、JS 和 CSS 代码:
Vue模板代码
JS代码
可以看到,生成的代码可读性高,质量较好,可以直接引入到项目中进行使用。代码生成器也提供了一个美观的编辑器界面,可以直接对生成的代码进行编辑,并在右侧重新渲染修改的表单。
除了直接生成代码外,form-generator 还提供了把表单导出为 JSON 格式的功能,便于进行存储和传输。Form-generator 设计了一种具有特定格式的 JSON 格式用于 Element UI 表单的表示,可以在代码生成器中直接导出 JSON 文件,使用时再利用配套的 form-gen-parser 进行解析,重新生成表单代码。
form-generator的JSON表示
表单的JSON表示以fields列表存储各表单项,各表单项一般包括:
- __config__:包括如标签、宽度等配置属性
- __slot__:表单项的插槽
- __vModel__:绑定的数据模型
- style、disabled等原生属性
以此 JSON 文件,便可还原表单,得到生成的 Vue 代码。我们还可以以此为模板,添加变量,只需修改 JSON 数据就进行相似表单的自动化批量生成。
表单的JSON表示
Form-Generator 作为 Element UI 的表单设计和代码生成器,简化了表单的设计和代码编写工作,使得表单的设计工作也能够“所见即所得”,在一些前端设计定制化要求不高的场景下,使用起来十分方便,既使得设计人员能够获得期望的表单设计,也减轻了代码开发人员的在前端设计方面的额外工作,一举两得。
Form-Generator 的实现需要对于 Vue 和 ElementUI 十分熟悉,尤其在表单的 JSON 表示的生成和解析方面的工作,颇具技巧;同时,该项目本身也是一个优秀的前端应用,感兴趣的开发者可以进行代码的阅读学习,参与开源贡献。
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。