小王学习录
- Json格式
- 示例 1:简单的 JSON 对象
- 示例 2:JSON 对象嵌套
- 示例 3:JSON 数组
- 示例 4:混合使用对象和数组
- 使用Gson将java对象转换成json字符串
- 哪些数据类型的对象可以使用Gson转换为json字符串
- 如何使用Gson将java对象转换成json字符串
- 代码及运行结果展示
- 格式化json字符串
- 代码及运行结果展示
- 从json字符串中截取字段
- 将json字符串解析为json对象
- 获取特定字段的值
- 将JsonElement(第二步获取到的值)转换为所需的数据类型
- 代码及运行结果展示
- Game over!!!
Json格式
关于Json格式,在UDP协议的博文中介绍自定义应用层协议时简单提到过,这里做一下详细解释。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。其格式遵循以下规则:
数据由键值对(key-value pairs)构成,键(key)是字符串,值(value)可以是以下几种数据类型之一:
值可以是数字(整数或浮点数)。
值可以是字符串(在双引号 " 中)。
值可以是布尔值(true 或 false)。
值可以是 null。
值可以是对象(即另一个 JSON 对象,键值对用花括号 {} 包裹)。
值可以是数组(即一组有序的值,用方括号 [] 包裹)。
数据以键值对的形式成组出现,每对之间用逗号 , 分隔。
整个数据结构由花括号 {} 包裹。
以下是一些具体的 JSON 格式例子:
示例 1:简单的 JSON 对象
{"name": "John Doe","age": 30,"isEmployed": true,"city": "New York"
}
在这个例子中,我们有一个 JSON 对象,包含四个键值对:
“name” 键对应的值是字符串 “John Doe”。
“age” 键对应的值是数字 30。
“isEmployed” 键对应的值是布尔值 true。
“city” 键对应的值是字符串 “New York”。
示例 2:JSON 对象嵌套
{"person": {"name": "Jane Smith","contact": {"phone": "+1-555-1234","email": "jane.smith@example.com"}},"company": {"name": "Acme Inc.","address": {"street": "1 Main St","city": "San Francisco","country": "USA"}}
}
这个例子展示了 JSON 对象的嵌套。外层对象有两个键值对:
“person” 键对应的值是一个内嵌的 JSON 对象,描述一个人的信息。
“company” 键对应的值也是一个内嵌的 JSON 对象,描述一家公司的信息。
示例 3:JSON 数组
{"employees": [{"firstName": "Bill","lastName": "Gates"},{"firstName": "George","lastName": "Bush"},{"firstName": "Thomas","lastName": "Carter"}]
}
在这个例子中,JSON 对象有一个名为 “employees” 的键,其对应的值是一个数组。数组内包含三个元素,每个元素都是一个独立的 JSON 对象,分别描述了员工的姓名。
示例 4:混合使用对象和数组
{"menu": {"id": "file","value": "File","popup": {"menuitem": [{"value": "New", "onclick": "CreateNewDoc()"},{"value": "Open", "onclick": "OpenDoc()"},{"value": "Close", "onclick": "CloseDoc()"}]}}
}
这个例子展示了如何在一个 JSON 对象中同时使用嵌套的对象和数组。“menu” 键对应的值是一个对象,其中 “popup” 键对应的值又是一个对象,而这个对象的 “menuitem” 键对应的值则是一个数组,数组中的每个元素都是一个描述菜单项的 JSON 对象。
以上就是 JSON 格式的例子,它们都严格遵循 JSON 的语法规范,展示了如何用 JSON 表示各种复杂的数据结构。
使用Gson将java对象转换成json字符串
首先需要导入依赖
<dependencies><!-- Gson dependency --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.9.0</version> <!-- 或者您想使用的最新版本号 --></dependency>
</dependencies>
哪些数据类型的对象可以使用Gson转换为json字符串
new Gson().toJson() 方法可以将满足以下数据类型条件的对象转换为 JSON 字符串:
- Java 基本类型及其包装类:
boolean / Boolean
byte / Byte
short / Short
int / Integer
long / Long
float / Float
double / Double
char / Character
String
- 数组:
基本类型数组,如 int[]、String[]
对象数组,如 MyClass[]
- 集合:
List,如 ArrayList
Set,如 HashSet
Map<K, V>,如HashMap<String, MyClass>。注意,键(Key)必须是可序列化的类型,通常为字符串或数值。
- 自定义类:
POJO(Plain Old Java Object):包含属性(成员变量)和 getter/setter 方法的普通 Java
类。Gson 会将此类对象的属性转换为 JSON 对象的键值对。
- 属性可以是上述基本类型、数组、集合或其它自定义类。
- 属性需有对应的getter 方法(用于序列化)和 setter 方法(用于反序列化)。遵循 JavaBeans 规范时,默认情况下,Gson 能够识别名为 getProperty() 和 setProperty() 的方法。
- 可以使用 @Expose、@SerializedName 等 Gson注解来控制哪些属性参与序列化与反序列化,以及属性在 JSON 中的键名。
枚举类型(enum):枚举常量会被转换为字符串,通常为常量名(默认)或通过 @SerializedName 注解指定的名称。
- 特殊类型:
(1) Date 类型:Gson 默认会将 Date 对象转换为自 1970-01-01T00:00:00Z(Unix 纪元)以来的毫秒数。可以通过GsonBuilder 设置自定义的日期格式处理器。
(2) null 值:在 JSON 中表示为 null。总的来说,Gson能够处理大部分常见的 Java 数据类型,包括基本类型、容器类型(数组、集合)、自定义类以及一些特殊类型(如 Date)。只要对象的结构和数据类型符合 JSON 的规范,就可以使用 new Gson().toJson() 方法将其转换为 JSON 字符串。对于不满足默认序列化规则的复杂情况,Gson 提供了一系列注解和自定义类型适配器(TypeAdapter)机制来定制序列化和反序列化行为。
如何使用Gson将java对象转换成json字符串
只需一行代码就可以解决
System.out.println(new Gson().toJson(response));
下面对这行代码做详细解释:
- new Gson():
创建了一个 Gson 类的实例。Gson 是 Google 提供的一个用来处理 JSON (JavaScript Object
Notation) 数据的库,主要用于对象与 JSON 字符串之间的相互转换。
- .toJson(response):
调用了 Gson 实例上的 toJson() 方法,传入一个名为 response 的对象作为参数。 toJson()
方法负责将传入的对象序列化成 JSON 格式的字符串。这意味着它会遍历 response 对象的属性,并遵循 JSON的语法规则将其转换为一个文本字符串。如果有嵌套的对象、数组或其他复杂结构,这些也会被递归地转换为相应的 JSON 表示形式。
- System.out.println():
System.out.println() 是 Java 中的标准输出方法,用于将指定的字符串内容输出到控制台(Console),并在输出后换行。 在此上下文中,它接收由Gson().toJson(response) 返回的 JSON 字符串作为参数,并将其打印到控制台。这一步骤使得开发者能够直观地查看 response 对象经过 JSON 序列化后的文本表现,便于调试、记录日志或进行其他形式的数据交互。
4, 综上所述,这段代码的完整功能是:使用 Gson 库将一个名为 response 的对象序列化为 JSON 字符串,然后通过 System.out.println() 将这个 JSON 字符串输出到控制台,方便开发者查看和验证 response 对象的 JSON 表现形式。这样的操作常见于调试过程中,用于检查网络请求的响应数据、中间计算结果或其他需要以 JSON 形式展示的数据结构。
代码及运行结果展示
public class Student {private int age = 0;private String name = "";private int classname = 0;public Student(int age, String name, int classname) {this.age = age;this.name = name;this.classname = classname;}
}
import com.google.gson.Gson;
public class Main {public static void main(String[] args) {Student student = new Student(18, "wang", 100);System.out.println(new Gson().toJson(student));}
}
运行结果:
可以看到,student对象已经被转换成json格式的字符串。
但是有个问题,就是这个字符串并没有以json的格式进行输出
格式化json字符串
格式化字符串也只需要一行代码就可以解决
主要使用到的是GsonBuilder()的setPrettyPrinting()
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(student));
这段代码使用 Gson 库将一个名为 student 的对象转换为格式化的 JSON 字符串,并将其输出到控制台。下面逐行解释:
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(student));
new GsonBuilder()
: 创建一个 GsonBuilder 实例。GsonBuilder 是 Gson 库提供的一个用于定制 Gson 实例的构造器类。通过它,您可以设置各种序列化和反序列化选项,如日期格式、字段过滤规则、是否启用/禁用特定功能等。
.setPrettyPrinting()
: 调用 GsonBuilder 实例的 setPrettyPrinting() 方法。这个方法告诉 Gson 在序列化时启用美观(pretty)打印模式,即将生成的 JSON 字符串格式化为易于阅读的形式,包含适当的缩进和换行。这对于调试和日志输出非常有用。
.create()
: 调用 GsonBuilder 实例的 create() 方法。这个方法基于之前设置的各项选项创建一个新的 Gson 实例。Gson 是 Gson 库的核心类,提供了序列化(toJson)和反序列化(fromJson)的功能。
.toJson(student)
: 调用新创建的 Gson 实例的 toJson() 方法,传入参数 student。这个方法负责将传入的对象(在这里是 student)转换为 JSON 字符串。Gson 会根据 student 类型的结构和属性,将其序列化为符合 JSON 格式的文本。
System.out.println(...)
: 最后,将 toJson() 方法返回的格式化 JSON 字符串传递给 System.out.println()
,这是一个标准的 Java 输出函数,将字符串内容打印到控制台,并在末尾添加一个换行符。
综上所述,这段代码的作用是:使用 Gson 库的 GsonBuilder 创建一个开启了美观打印模式的 Gson 实例,然后使用这个实例将 student 对象序列化为格式化的 JSON 字符串,并最终将该 JSON 字符串输出到控制台。这样做的目的是以易于阅读的格式显示 student 对象的 JSON 表示。
代码及运行结果展示
可以看到,student最终以格式化后的json字符串输出
从json字符串中截取字段
需求: 从以上json字符串中截取出特定字段和其值
需要三步:
- 将json字符串解析为json对象
- 获取特定字段的值
- 将JsonElement(第二步获取到的值)转换为所需的数据类型
将json字符串解析为json对象
String s = new GsonBuilder().setPrettyPrinting().create().toJson(student);JsonObject jsonObject = new Gson().fromJson(s, JsonObject.class);
获取特定字段的值
这里需要确保jsonObject不为空,以及key值在json字符串中存在
JsonElement age = jsonObject.get("age");
将JsonElement(第二步获取到的值)转换为所需的数据类型
针对不同类型的value,做不同处理:
if (age != null && !age.isJsonNull()) {if (age.isJsonPrimitive() && age.getAsJsonPrimitive().isString()) {// 处理字符串值的情况String value = age.getAsString();System.out.println(value);} else if(age.isJsonPrimitive() && age.getAsJsonPrimitive().isNumber()){//处理数字的情况int value = age.getAsInt();System.out.println(value);}// 处理其他类型值的情况,比如、布尔值或 JSON 对象} else {// 处理字段不存在或值为 null 的情况}
如果字段的值是一个数字,可以调用 getAsInt()、getAsLong()、getAsFloat() 或 getAsDouble() 方法将其转换为相应的数值类型。
if (fieldValue.isJsonPrimitive() && fieldValue.getAsJsonPrimitive().isNumber()) {int intValue = fieldValue.getAsInt();// 处理整数值的情况
}
如果字段的值是一个布尔值,可以调用 getAsBoolean() 方法将其转换为布尔类型。
if (fieldValue.isJsonPrimitive() && fieldValue.getAsJsonPrimitive().isBoolean()) {boolean booleanValue = fieldValue.getAsBoolean();// 处理布尔值的情况
}
如果字段的值是一个 JSON 对象,可以调用 getAsJsonObject() 方法将其转换为一个新的 JSON 对象,然后对其进行进一步处理。
if (fieldValue.isJsonObject()) {JsonObject nestedObject = fieldValue.getAsJsonObject();// 处理嵌套 JSON 对象的情况
}
这些方法可以根据字段值的类型进行适当的转换和处理,确保的代码在不同类型的字段值情况下都能正常运行。