注:本文侧重于web后端(Java)对json 的运用
1.意义与运用场景
之前我一直觉得 json 仅仅只是一个传输中的文本格式,我们后端可能不太需要重视这种格式。因为我们接收到 json 数据后,肯定会用springboot等框架帮助从而转换为对象去接收,从而运用里面的数据。但是我最近在做一个任务时,发现在复杂情景运用下,可能我们不得不自己去手动解析出json里的数据,从而手动转换为对象给我们使用。例如我们在使用策略模式用多个策略类实现同一个接口时,这个接口中其中一个方法的其中一个参数就可能要是json,因为不同的策略类接收的这个参数格式不同,所以就不太方便在接口中的一个参数写一个类去接收这个json。(当然,实际上如果你不嫌麻烦的话可以一个一个去定义,但是那样就是一个出力不讨好的事,而且未来再扩充策略类的时候就麻烦了)所以,在实际开发中,我们要提前写好参数文档,与前端和产品沟通好,就能用json大大省事了
2.json简介
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript的一个子集,但是JSON是独立于语言的文本格式,尽管它的名字中有JavaScript,但它也可以被许多其他编程语言使用。
JSON的主要特点
- 文本格式:JSON是一种纯文本格式,可以被人类阅读和编写,也可以被机器轻松解析。
- 数据交换:JSON广泛用于数据交换,特别是在Web应用程序中,它作为客户端和服务器之间传输数据的格式。
- 键值对:JSON数据格式基于键值对,其中值可以是各种类型,包括字符串、数字、布尔值、数组、对象(另一个JSON)或null。
- 数组:JSON中的数组表示为值的有序列表,列表中的每个元素都可以是任何值。
- 结构化:JSON支持复杂的数据结构,如嵌套的对象和数组。
- 语言无关性:尽管JSON起源于JavaScript,但它可以被任何编程语言处理,包括Python、Java、C#、Ruby等。
- 解析和生成:大多数现代编程语言都提供了解析JSON和生成JSON的库。
json格式示例
{
"name": "John",
"age": 30,
"is_student": false
}
3.Gson运用与demo
那么我们在Java中一般有两种库来帮助我们手动处理Json,一个是fastJson,另一个是Gson。本文选择Gson进行讲解
在pom文件里导入Gson依赖
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.9</version> <!-- 请检查最新版本 -->
</dependency>
3.1 快速入门
序列化:把一个对象序列化成Json
import com.google.gson.Gson;
public class GsonExample {
public static void main(String[] args) {
Person person = new Person("John", 30);
Gson gson = new Gson();
String json = gson.toJson(person);
System.out.println(json);
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// Getters and setters
}
反序列化:把一个 Json 反序列化成一个对象
import com.google.gson.Gson;
public class GsonExample {
public static void main(String[] args) {
String json = "{\"name\":\"John\",\"age\":30}";
Gson gson = new Gson();
Person person = gson.fromJson(json, Person.class);
System.out.println(person.getName() + " " + person.getAge());
}
}
class Person {
private String name;
private int age;
// Constructor, Getters and Setters
}
那么这里所说的都是已提供有对象的情况下,实际开发中这种我们一般用不到,因为框架会出手(当然,框架可能之后也有出不了手的情况,比如对枚举的处理这种,不过不是本文重点,以后有机会再讨论)
3.2 通过已规定的接口文档直接解析Json
我们通过一个demo来学习这种方法
假设我们已经跟产品和前端定义好了arg的模样,如下图
{
"type": "cluster",
"data": [{
"columnName": "特点",
"maxMinSim": 0.6,
"minMinSim": 0.5,
"step": 0.05
},
{
"columnName": "标题",
"maxMinSim": 0.6,
"minMinSim": 0.5,
"step": 0.05
}
]
}
那么我们该如何解析呢,可以看出我们的fromJson的第二个参数就是JsonObject.class
JsonObject jsonObject = new Gson().fromJson(taskArgs, JsonObject.class);
JsonArray asJsonArray = jsonObject.get("data").getAsJsonArray();
for (int i = 0; i < asJsonArray.size(); i++) {
JsonObject dataJsonObject = asJsonArray.get(i).getAsJsonObject();
log.info(dataJsonObject.toString());
// 获取参数
String columnName = dataJsonObject.get("columnName").getAsString();
float minMinSim = dataJsonObject.get("minMinSim").getAsFloat();
float maxMinSim = dataJsonObject.get("maxMinSim").getAsFloat();
float step = dataJsonObject.get("step").getAsFloat();
}
此处我们可以看到我们对我们的arg层层剖析,通过get我们可以得到不同的对象,可以是数组,也可以是一个Object对象,也能是String,如下图有各个可以返回的类型,优点非常自由,缺点是无法自动校验类型,一定要看清楚了再去写
4.Json构造
有时候我们需要自己构造 json ,比如当我们对在后端要调用远程接口时,他的body就是json类型,此时我们就需要自己构造json了
先导入依赖
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20210307</version> <!-- 请检查是否有更新的版本 -->
</dependency>
使用方法也很简单,见下
JSONObject requestJson = new JSONObject();
requestJson.put("min_sim", minSim);
requestJson.put("k", 50);
requestJson.put("mask_len", 512);
requestJson.put("data", dataJson);
如果要json套娃,跟上面一样,不多bb了