码这么多字只为搞懂如何在Python和Java中使用JSON

目录

1 JSON是什么?

1.1 JSON是众多编程语言共同的“简谱”

1.2 JSON是一种高度结构化的文本

2 如何在Python中使用JSON

2.1 内置库json的编码与解码

2.1.1 编码1:将字典编码为JSON字符串

2.1.2 编码2:将自定义类的对象编码为JSON字符串

2.1.3 解码1:将JSON字符串解码为字典

2.1.4 解码2:将JSON字符串解码为自定义类的对象

2.2 requests库处理json的方法

2.3 提取json中数据信息的方法

3 如何在Java中使用JSON

3.1 Gson库和FastJson库的资源下载

3.2 用Gson处理JSON的方法

3.2.1 编码1:将Map对象编码为JSON字符串

3.2.2 编码2:将自定义类的对象编码为JSON字符串

3.2.3 解码1:将JSON字符串解码为Map对象

3.2.4 解码2:将JSON字符串解码为自定义类的对象

3.3 用FastJson处理JSON的方法

3.2.1 编码1:将Map对象编码为JSON字符串

3.2.2 编码2:将自定义类的对象编码为JSON字符串

3.2.3 解码1:将JSON字符串解码为Map对象

3.2.4 解码2:将JSON字符串解码为自定义类的对象


1 JSON是什么?

1.1 JSON是众多编程语言共同的“简谱”

JSON的全称是JavaScript Object Notation,中文翻译是JS对象简谱,是一种轻量级的数据交换格式。JavaScript是多用于Web前端开发的编程语言,支持面向对象的编程(OOP)。JSON从字面上看就是存储JS对象的一种简便、轻量的格式。

提到“简谱”,我们很容易想到音乐中的数字简谱,即使像我这种不懂音乐的人,也会觉得简谱看上去要比各种音符组成的五线谱更容易阅读一些。

JSON不仅能做JS对象的“简谱”, 还能做很多编程语言的“简谱”,而且是它们共同的“简谱”。不同的编程语言的语法是不一样的,因此不同语言编写的程序之间往往“语言不通”,比如:Java看不懂Python对象,Python也看不懂Java对象。为了不同的编程语言能够沟通,比较好的方法是把对象表达为一种简单易读的统一格式。

JSON用键值对的形式存储对象的属性名属性值,每一个对象都放在一个大括号里。比如我用JSON给自己写一个对象,一个可爱型的女生,具有善良、聪明、开朗等个性,还养了一只2岁的泰迪犬,那么我的对象就有四个属性:性别、类型、个性和狗狗;狗狗也是一个对象,有品种和年龄两个属性。

{
    "gender":"female",
    "kind":"cute",
    "character":["goodness"," intelligent","lively"],
    "puppy":{ 
              "breed":"teddy",
              "age":2
            }
    
}

当Java或者Python程序员就这点好,可以在程序的世界里随意写对象。好吧,言归正传,JSON表面上看是一个带有大括号、方括号和冒号的某种数据集合,但实际上是一个文本文件。这也是JSON实现跨平台、跨语言交换数据的重要基础。

1.2 JSON是一种高度结构化的文本

先想象一个场景,一个广东人跟一个上海人交流,他们互相听不懂对方的方言,但是两人把要说的内容用汉字写下来,立马就明白了对方的意思,这就是汉字的超方言性(笔者的专业是语言学)。

文本就具有类似于汉字的作用。不同的编程语言具有不同的数据结构类型体系,这就造成了互相沟通的障碍。但是所有的编程语言都会支持文本这一最基本的处理信息的类型。对于Python和Java来说,文本类型实际上就是字符串类型

JSON中数据的组织方式是高度结构化的,结构化的第一个表现是层级性,上面写的那个对象中,对象里面嵌套着对象;在层级性的基础上,同一层级的数据要有对应性有序性,键值对的格式保证了每一层数据间的对应关系;属性的值也有可能是存储多值的数据集合,其中的数据要排列有序。

我们可以在CSDN主页的XHR请求中观察JSON的层次结构,操作步骤以Google浏览器为例。

第一步:右键“检查” — 点击“Network” — 点击“XHR”;

 第二步:重新加载页面 — 在左侧Name栏打开一个请求 — 点开右侧的preview — 观察层级结构

 我们看到的那个能够一层层展开的结构,很像Python的字典或者Java的Map。但事实上,是XHR采用JSON格式传输数据。

2 如何在Python中使用JSON

2.1 内置库json的编码与解码

json是python的内置库,定义了 json.dumps(dict)json.loads(json_str) 两个方法,前者用于将Python数据结构类型编码为json字符串,后者用于将json字符串解码为Python数据结构类型。

2.1.1 编码1:将字典编码为JSON字符串

我们在1.1中用json写好的那个“对象”与Python字典从外表上看一模一样,先将其写成字典(变量名spouse,就是配偶、对象的意思,哈哈哈),然后编码,方法的参数是Python字典:

import json

# 写一个 字典 类型的“对象”
spouse = {
    "gender":"female",
    "kind":"cute",
    "character":["goodness"," intelligent","lively"],
    "puppy":{ 
              "breed":"teddy",
              "age":2
            }
}

# 将 字典 编码为 json字符串
spouse_json = json.dumps(spouse)


# 打印spouse和spouse_json
print(spouse)
print(spouse_json)

如果我们直接打印,会发现spouse和spouse_json在终端中显示出来的结果一模一样:

{'gender': 'female', 'kind': 'cute', 'character': ['goodness', ' intelligent', 'lively'], 'puppy': {'breed': 'teddy', 'age': 2}}
{"gender": "female", "kind": "cute", "character": ["goodness", " intelligent", "lively"], "puppy": {"breed": "teddy", "age": 2}}

如果我们分别打印二者的数据类型,会发现spouse是dict,spouse_json是str,对于Python来说,json就是一个高度结构化的字符串

print(type(spouse))  # <class 'dict'>
print(type(spouse_json))  # <class 'str'>

2.1.2 编码2:将自定义类的对象编码为JSON字符串

将自定义类的对象转化为JSON字符串要经过一个中间步骤,即先将对象转化为字典,然后再将字典传入 json.dumps(dict) 方法。为了简化代码,自定义类就写三个属性作为演示。

import json

# 先自定义一个类
class Spouse:
    def __init__(self, gender, kind, character):
        self.gender = gender
        self.kind = kind
        self.character = character

# 类 实例化为一个 对象
spouse = Spouse("female","cute",['goodness', ' intelligent', 'lively'])

# 将 对象 转换为 字典
spouse_dict = spouse.__dict__

# 将 字典 传入 json.dumps(dict)方法
spouse_json = json.dumps(spouse_dict)

print(spouse_json)
print(type(spouse_json))

打印结果如下,成功将Python自定义对象转换为JSON字符串

{"gender": "female", "kind": "cute", "character": ["goodness", " intelligent", "lively"]}
<class 'str'>  

2.1.3 解码1:将JSON字符串解码为字典

我们接着上面2.1.1的代码继续完成解码过程,将json_spouse传入json.loads()方法:

# 将 json字符串 解析为 字典
spouse_dict = json.loads(spouse_json)

print(spouse_dict)
print(type(spouse_dict))

打印效果如下,成功将JSON字符串解码为字典类型的数据

{'gender': 'female', 'kind': 'cute', 'character': ['goodness', ' intelligent', 'lively'], 'puppy': {'breed': 'teddy', 'age': 2}}
<class 'dict'>

2.1.4 解码2:将JSON字符串解码为自定义类的对象

和编码过程一样,解码也要经过一个中间步骤,先将JSON字符串转化为字典,再将字典转化成对象。我们接着2.1.2的代码完成解码过程。

# 将 json字符串 转化成 字典
spouse_dict = json.loads(spouse_json)

# 实例化一个对象,并将spouse_dict中的值传入
args = []
for v in spouse_dict.values():
    args.append(v) 
spouse2 = Spouse(args[0], args[1], args[2])

# 将 字典 转换成 对象
spouse2.__dict__ = spouse_dict

print(spouse2)
print(spouse2.gender, spouse2.kind, spouse2.character)

打印结果如下,成功将JSON转成自定义的Python对象,并取出三个属性的值

<__main__.Spouse object at 0x000002DB18BE1128>
female cute ['goodness', ' intelligent', 'lively']

2.2 requests库处理json的方法

requests库是一个第三方库,使用前需要安装,笔者习惯用清华镜像,速度比较快:

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests

调用requests中的方法请求网页会返回一个response对象,再通过repsonse.json()的方法将其解码为Python字典。我们就拿1.2提到的CSDN主页中的一个XHR请求来演示。

还是1.2中得到XHR请求信息,然后按照下图的箭头点击Header,Request URL就是我们要用requests库请求的网址:

import requests

url = "https://silkroad.csdn.net/api/v2/assemble/list/channel/search_hot_word?channel_name=pc_hot_word&size=10&user_name=weixin_45370422&platform=pc&imei=10_36634027780-1586843824396-539212"

# 向url发起请求,返回一个response对象
res = requests.get(url)

# 将 respose对象 转换为 python字典
res_json = res.json()
print(res_json)
print(type(res_json))

打印结果如下,已经将在浏览器中看到的能层层展开的内容转换成python字典

{'code': 200, 'data': {'ext': {}, 'size': 10, 'items': [{'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'Google I/O 开发者大会', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-1.nonecase","hotword":"Google I/O 开发者大会"}', 'dist_request_id': '1622602100980_27895', 'index': '1', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-1.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-1.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 1, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '领红包+快速涨粉!CSDN 测评赛开启', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-2.nonecase","hotword":"领红包+快速涨粉!CSDN 测评赛开启"}', 'dist_request_id': '1622602100980_27895', 'index': '2', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-2.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-2.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 2, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'CTO写低级Bug', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-3.nonecase","hotword":"CTO写低级Bug"}', 'dist_request_id': '1622602100980_27895', 'index': '3', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-3.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-3.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 3, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '高质量自学网站', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-4.nonecase","hotword":"高质量自学网站"}', 'dist_request_id': '1622602100980_27895', 'index': '4', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-4.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-4.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 4, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '为什么程序员不写文档?', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-5.nonecase","hotword":"为什么程序员不写文档?"}', 'dist_request_id': '1622602100980_27895', 'index': '5', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-5.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-5.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 5, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'C++编程入门', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-6.nonecase","hotword":"C++编程入门"}', 'dist_request_id': '1622602100980_27895', 'index': '6', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-6.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-6.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 6, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'python工程师', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-7.nonecase","hotword":"python工程师"}', 'dist_request_id': '1622602100980_27895', 'index': '7', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-7.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-7.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 7, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'python制作表情包', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-8.nonecase","hotword":"python制作表情包"}', 'dist_request_id': '1622602100980_27895', 'index': '8', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-8.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-8.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 8, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '如何用Python追到女朋友', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-9.nonecase","hotword":"如何用Python追到女朋友"}', 'dist_request_id': '1622602100980_27895', 'index': '9', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-9.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-9.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 9, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'mysql', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-10.nonecase","hotword":"mysql"}', 'dist_request_id': '1622602100980_27895', 'index': '10', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-10.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-10.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 10, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}]}, 'message': 'success'}
<class 'dict'>

当然了,我们也可以迂回一下,先把response对象转换成字符串,然后调再json库的解码方法,效果是一样的:

import requests
import json

url = "https://silkroad.csdn.net/api/v2/assemble/list/channel/search_hot_word?channel_name=pc_hot_word&size=10&user_name=weixin_45370422&platform=pc&imei=10_36634027780-1586843824396-539212"

# 向url发起请求,返回一个response对象
res = requests.get(url)

# 将response对象转成字符串,再解码为python字典
res_json = json.loads(res.text)
print(res_json)
print(type(res_json))

打印结果是:

{'code': 200, 'data': {'ext': {}, 'size': 10, 'items': [{'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'Google I/O 开发者大会', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-1.nonecase","hotword":"Google I/O 开发者大会"}', 'dist_request_id': '1622602100980_27895', 'index': '1', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-1.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-1.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 1, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '领红包+快速涨粉!CSDN 测评赛开启', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-2.nonecase","hotword":"领红包+快速涨粉!CSDN 测评赛开启"}', 'dist_request_id': '1622602100980_27895', 'index': '2', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-2.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-2.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 2, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'CTO写低级Bug', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-3.nonecase","hotword":"CTO写低级Bug"}', 'dist_request_id': '1622602100980_27895', 'index': '3', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-3.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-3.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 3, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '高质量自学网站', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-4.nonecase","hotword":"高质量自学网站"}', 'dist_request_id': '1622602100980_27895', 'index': '4', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-4.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-4.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 4, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '为什么程序员不写文档?', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-5.nonecase","hotword":"为什么程序员不写文档?"}', 'dist_request_id': '1622602100980_27895', 'index': '5', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-5.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-5.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 5, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'C++编程入门', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-6.nonecase","hotword":"C++编程入门"}', 'dist_request_id': '1622602100980_27895', 'index': '6', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-6.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-6.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 6, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'python工程师', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-7.nonecase","hotword":"python工程师"}', 'dist_request_id': '1622602100980_27895', 'index': '7', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-7.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-7.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 7, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'python制作表情包', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-8.nonecase","hotword":"python制作表情包"}', 'dist_request_id': '1622602100980_27895', 'index': '8', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-8.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-8.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 8, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': '如何用Python追到女朋友', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-9.nonecase","hotword":"如何用Python追到女朋友"}', 'dist_request_id': '1622602100980_27895', 'index': '9', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-9.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-9.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 9, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}, {'ext': None, 'resourceId': '', 'mediaAssetInfo': None, 'productId': 'mysql', 'reportData': {'eventClick': True, 'data': {'mod': 'popu_895', 'extra': '{"utm_medium":"distribute.pc_search_hot_word.none-task-hot_word-alirecmd-10.nonecase","hotword":"mysql"}', 'dist_request_id': '1622602100980_27895', 'index': '10', 'strategy': 'alirecmd'}, 'urlParams': {'utm_medium': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-10.nonecase', 'depth_1-utm_source': 'distribute.pc_search_hot_word.none-task-hot_word-alirecmd-10.nonecase'}, 'eventView': True}, 'recommendType': 'ali', 'index': 10, 'style': 'word_1', 'strategyId': 'alirecmd', 'productType': 'hot_word'}]}, 'message': 'success'}
<class 'dict'>

2.3 提取json中数据信息的方法

json中值得提取的信息一般就是对象的属性值。虽然json是一个文本,整体上是一个文本类型的数据,然而,这个文本通过特定的格式实现了高度的结构化,而且json中的数据类型与Python数据类型具有对应关系。如下表所示:

python数据类型json数据类型json格式示例
字典(dict)对象(object)

{属性名 : 属性值}

列表(list)、元组(tuple)数组(array)·[元素1, 元素2, 元素3, ......]
字符串(str)字符串(string)'字符串'   "字符串"
整数(int)、浮点数(float)数字(number)666
布尔值(True, False)布尔值(true, false)true  false
空值(None)空值(null)null

正因为有这样的对应关系,我们先将json字符串解码为Python字典后,就可以用处理Python数据类型的方法从里面提取数据信息了。比如我们上面写的json对象中的数据都能找到相应的Python数据类型。

3 如何在Java中使用JSON

3.1 Gson库和FastJson库的资源下载

Java目前没有像Python那样内置了处理JSON的类库,因此只能借助第三方库完成JSON的处理。这里推荐使用Google开发的Gson库和阿里开发的FastJson库,可以在各自的GitHub上下载,我们也将提供当前最新版本的资源供读者免费下载,链接在下面。

打包好的两个jar包资源:JSON-jar-new.zip-Java文档类资源-CSDN下载

Gson的GitHub地址:GitHub - google/gson: A Java serialization/deserialization library to convert Java Objects into JSON and back

FastJson的GitHub地址:Home · alibaba/fastjson Wiki · GitHub

 至于导包的方法,网上很容易检索到,这里就不赘述了。这两篇博文还是讲的比较详细的:

IDEA:IDEA导入jar包_hwt1070359898的博客-CSDN博客_idea导入jar包 

Eclipse:Eclipse引入jar包的三种方式_小蓝的博客-CSDN博客_eclipse 导入jar包

我们以1.1写的那个对象为例,首先创建一个“对象”类,即下面的Spouse.java,为了简化代码,节省篇幅,我们在全参构造方法里定义属性值。特别需要注意的一点是,阿里的FastJson是通过类的getter方法获取属性值的,所以必须要写上getter方法。

package com.demo2;

import java.util.Arrays;

public class Spouse {
    // “对象”类的三个属性
    private String gender;
    private String kind;
    private String[] character;

    // Spouse类的全参构造方法的
    public Spouse(String gender, String kind, String[] character) {
        this.gender = gender;
        this.kind = kind;
        this.character = character;
    }

    // toString()方法:方便打印
    @Override
    public String toString() {
        return "Spouse{" +
                "gender='" + gender + '\'' +
                ", kind='" + kind + '\'' +
                ", character=" + Arrays.toString(character) +
                '}';
    }
    
    // FastJson通过 getter 方法获取属性值
    public String getGender() {
        return gender;
    }

    public String getKind() {
        return kind;
    }

    public String[] getCharacter() {
        return character;
    }
}

3.2 用Gson处理JSON的方法

3.2.1 编码1:将Map对象编码为JSON字符串

正如Python能够将字典类型的数据直接写入JSON,Java通过Map类型生成一个JSON。用Gson实现这一功能的方法是,先创建一个map对象,然后将其传入toJson(object)方法。

package com.demo2;

import com.google.gson.Gson;

import java.util.HashMap;
import java.util.Map;

public class Demo {
    public static void main(String[] args) {
        // 创建Map对象,加入键值对数据
        Map map = new HashMap();
        map.put("gender", "female");
        map.put("kind", "cute");
        map.put("character", new String[]{"goodness", " intelligent", "lively"});

        // 将 map 传入 toJson(object) 方法
        String json = new Gson().toJson(map);

        System.out.println(json);
        System.out.println(json.getClass());
    }
}

 打印的结果如下,成功生成一个JSON字符串:

{"character":["goodness"," intelligent","lively"],"gender":"female","kind":"cute"}
class java.lang.String

3.2.2 编码2:将自定义类的对象编码为JSON字符串

编码的方法是向toJson(object)方法传入自定义类的实例化对象。

import com.google.gson.Gson;

public class Demo {
    public static void main(String[] args) {
        // 1  创建 JSON 对象(如果只用一次,也可以写成匿名对象)
        Gson gson = new Gson();

        // 2  实例化Spouse类,得到一个对象
        Spouse spouse = new Spouse("female", "cute", new String[]{"goodness", " intelligent", "lively"});
        
        // 3  调用Gson的 toJson(object) 方法
        String json = gson.toJson(spouse);

        System.out.println(json);
        System.out.println(json.getClass());

打印结果如下,可以看到对象被成功编码成了JSON格式的字符串

{"gender":"female","kind":"cute","character":["goodness"," intelligent","lively"]}
class java.lang.String

顺便提一下,如果所有的类都只用一次,那么上述代码可以进一步简化:

import com.google.gson.Gson;

public class Demo {
    public static void main(String[] args) {
        // 1  一行代码全部搞定
        String json = new Gson().toJson(new Spouse("female", "cute", new String[]{"goodness", " intelligent", "lively"}));

3.2.3 解码1:将JSON字符串解码为Map对象

调用fromJson(json, class)方法,第一个参数为要解码的json字符串,第二个参数传入Map类。

package com.demo2;

import com.google.gson.Gson;

import java.util.List;
import java.util.Map;

public class Demo {
    public static void main(String[] args) {
        //  调用Gson对象的 fromJson(json, class) 方法 将json 解码为 Spouse对象
        String json = "{\"gender\":\"female\",\"kind\":\"cute\",\"character\":[\"goodness\",\" intelligent\",\"lively\"]}";

        // 可以将 JSON字符串 解码为 Map 对象,这样就能用Map的方法解析JSON
        Map map = new Gson().fromJson(json, Map.class);
        String gender = (String) map.get("gender");
        System.out.println(gender);
        
        // 可以将JSON中的数组解析为ArrayList
        List character = (List) map.get("character");
        System.out.println(character);
    }
}

输出结果如下:

female
[goodness,  intelligent, lively]

3.2.4 解码2:将JSON字符串解码为自定义类的对象

调用fromJson(json, class)方法,第一个参数为要解码的json字符串,第二个参数为要解码成的Java类。

package com.demo2;

import com.google.gson.Gson;

public class Demo {
    public static void main(String[] args) {
        //  调用Gson对象的 fromJson(json, class) 方法 将json 解码为 Spouse对象
        String json = "{\"gender\":\"female\",\"kind\":\"cute\",\"character\":[\"goodness\",\" intelligent\",\"lively\"]}";
        Spouse spouse = new Gson().fromJson(json, Spouse.class);

        System.out.println(spouse);
    }
}

输出结果如下,成功调用了Spouse类的toString()方法,打印出各属性的值:

Spouse{gender='female', kind='cute', character=[goodness,  intelligent, lively]}

3.3 用FastJson处理JSON的方法

3.3.1 编码1:将Map对象编码为JSON字符串

提供有两种生成JSON的方法,第一种类似于3.2.3的方法,先创建map对象,然后将map作为参数传入JSON.toJsonString(object)方法。

第二种方法是实例化FastJson提供的JSONObject类,用这个类的对象生成JSON。这个类能够调用Map类的方法,其原因是它实现了Map接口,观察这段源码:

 代码示例如下:

package com.demo2;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class Demo {
    public static void main(String[] args) {
        /**
         * 方法一:实例化一个map对象
         */
        Map map = new HashMap();
        map.put("gender", "female");
        map.put("kind", "cute");
        map.put("character", new String[]{"goodness", " intelligent", "lively"});
        // 将 map对象 传入 JSON.toJsonString(object) 方法
        String json = JSON.toJSONString(map);

        System.out.println(json);
        System.out.println(json.getClass());
        
        System.out.println();

        /**
         * 方法二:实例化一个JSONObjcet的对象,
         */
        JSONObject jsonObject = new JSONObject();
        // 调用 put(key, value) 方法
        jsonObject.put("gender", "female");
        jsonObject.put("kind", "cute");
        jsonObject.put("character", new String[]{"goodness", " intelligent", "lively"});

        System.out.println(jsonObject);
        System.out.println(jsonObject.getClass());
    }
}

打印结果如下:

{"character":["goodness"," intelligent","lively"],"gender":"female","kind":"cute"}
class java.lang.String

{"character":["goodness"," intelligent","lively"],"gender":"female","kind":"cute"}
class com.alibaba.fastjson.JSONObject

两种方法相比,方法二略微简便一点。另外我们也看到,第二种方法返回的数据类型是FastJson自己定义的JSONObject。 

3.3.2 编码2:将自定义类的对象编码为JSON字符串

将自定义类的对象传入JSON.toJsonString(object)方法,就得到了对象的JSON字符串。

package com.demo2;

import com.alibaba.fastjson.JSON;

import java.util.List;

public class Demo {
    public static void main(String[] args) {
        Book book = new Book("1002","唐诗","床前");
        Spouse spouse = new Spouse("female", "cute", new String[]{"goodness", "intelligent", "lively"});
        // 将 对象 编码 为JSON字符串
        String json = JSON.toJSONString(spouse);

        System.out.println(json);
        System.out.println(json.getClass());

 打印结果如下

{"character":["goodness","intelligent","lively"],"gender":"female","kind":"cute"}
class java.lang.String

3.3.3 解码1:将JSON字符串解码为Map对象

方法是将JSON字符串传入JSON.parseObject(json, class)方法的一个参数,第二个参数是Map类。

package com.demo2;

import com.alibaba.fastjson.JSON;

import java.util.Map;

public class Demo7 {
    public static void main(String[] args) {
        // 解码为 HashMap
        String json = "{\"character\":[\"goodness\",\" intelligent\",\"lively\"],\"gender\":\"female\",\"kind\":\"cute\"}";
        Map map = JSON.parseObject(json, Map.class);
        System.out.println(map);
        System.out.println(map.getClass());
    }
}

打印结果如下:

{character=["goodness"," intelligent","lively"], gender=female, kind=cute}
class java.util.HashMap

3.3.4 解码2:将JSON字符串解码为自定义类的对象

介绍两种解码的方法:JSON.parseObject(json, class) 和 JSON.parseArray(json, class) ,分别解析JSON对象和JSON里面的数组,第一个参数是JSON字符串,第二个参数是要解析成哪个类。

package com.demo2;

import com.alibaba.fastjson.JSON;

import java.util.List;

public class Demo4 {
    public static void main(String[] args) {
        // 将 json字符串 解码为 对象,{"character":["goodness","intelligent","lively"],"gender":"female","kind":"cute"}
        String json = "{\"character\":[\"goodness\",\"intelligent\",\"lively\"],\"gender\":\"female\",\"kind\":\"cute\"}";
        Spouse spouse = JSON.parseObject(json,Spouse.class);
        System.out.println(spouse);
        System.out.println(spouse.getClass());

        // 解析 json字符串 的数组,解析为ArrayList
        List<String> stringList = JSON.parseArray("[\"goodness\",\"intelligent\",\"lively\"]", String.class);
        System.out.println(stringList);
        System.out.println(stringList.getClass());
    }
}

打印结果如下,注意观察解码后的数据类型:

Spouse{gender='female', kind='cute', character=[goodness, intelligent, lively]}
class com.demo2.Spouse
[goodness, intelligent, lively]
class java.util.ArrayList

  • 27
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 62
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 62
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文程公子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值