小王学习录
- Json格式
-
- [示例 1:简单的 JSON 对象](#示例 1:简单的 JSON 对象)
- [示例 2:JSON 对象嵌套](#示例 2:JSON 对象嵌套)
- [示例 3:JSON 数组](#示例 3:JSON 数组)
- [示例 4:混合使用对象和数组](#示例 4:混合使用对象和数组)
- 使用Gson将java对象转换成json字符串
- 格式化json字符串
- 从json字符串中截取字段
- [Game over!!!](#Game over!!!)
Json格式
关于Json格式,在UDP协议的博文中介绍自定义应用层协议时简单提到过,这里做一下详细解释。
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。其格式遵循以下规则:
数据由键值对(key-value pairs)构成,键(key)是字符串,值(value)可以是以下几种数据类型之一:
值可以是数字(整数或浮点数)。
值可以是字符串(在双引号 " 中)。
值可以是布尔值(true 或 false)。
值可以是 null。
值可以是对象(即另一个 JSON 对象,键值对用花括号 {} 包裹)。
值可以是数组(即一组有序的值,用方括号 [] 包裹)。
数据以键值对的形式成组出现,每对之间用逗号 , 分隔。
整个数据结构由花括号 {} 包裹。
以下是一些具体的 JSON 格式例子:
示例 1:简单的 JSON 对象
java
{
"name": "John Doe",
"age": 30,
"isEmployed": true,
"city": "New York"
}
在这个例子中,我们有一个 JSON 对象,包含四个键值对:
"name" 键对应的值是字符串 "John Doe"。
"age" 键对应的值是数字 30。
"isEmployed" 键对应的值是布尔值 true。
"city" 键对应的值是字符串 "New York"。
示例 2:JSON 对象嵌套
java
{
"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 数组
java
{
"employees": [
{
"firstName": "Bill",
"lastName": "Gates"
},
{
"firstName": "George",
"lastName": "Bush"
},
{
"firstName": "Thomas",
"lastName": "Carter"
}
]
}
在这个例子中,JSON 对象有一个名为 "employees" 的键,其对应的值是一个数组。数组内包含三个元素,每个元素都是一个独立的 JSON 对象,分别描述了员工的姓名。
示例 4:混合使用对象和数组
java
{
"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字符串
首先需要导入依赖
java
<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字符串
只需一行代码就可以解决
java
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 形式展示的数据结构。
代码及运行结果展示
java
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;
}
}
java
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()
java
System.out.println(new GsonBuilder().setPrettyPrinting().create().toJson(student));
这段代码使用 Gson 库将一个名为 student 的对象转换为格式化的 JSON 字符串,并将其输出到控制台。下面逐行解释:
java
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对象
java
String s = new GsonBuilder().setPrettyPrinting().create().toJson(student);
JsonObject jsonObject = new Gson().fromJson(s, JsonObject.class);
获取特定字段的值
这里需要确保jsonObject不为空,以及key值在json字符串中存在
java
JsonElement age = jsonObject.get("age");
将JsonElement(第二步获取到的值)转换为所需的数据类型
针对不同类型的value,做不同处理:
age.isJsonNull:
判断key存在,但是value为空的情况
age.isJsonPrimitive():
用于检查 JSON 元素是否表示一个 JSON 基本类型。JSON 基本类型包括字符串、数字、布尔值和 null。当 age 是一个 JSON 基本类型时,age.isJsonPrimitive()
返回 true;否则,返回 false。age.isJsonPrimitive() 这一部分用于检查 age 字段的值是否为 JSON 基本类型。如果 age 字段的值是一个 JSON 基本类型,那么就可以进一步检查它的具体类型,比如字符串、数字等。
java
if (age != null && !age.isJsonNull()) {
//age.isJsonNull 判断key存在,但是value为空的情况
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);
} else if{
// 处理其他类型值的情况,比如、布尔值或 JSON 对象
} else if(value.isJsonArray){
// 处理json元素是json数组的情况
return value.getAsJsonArray();
} else if(!value.isJsonPrimitive()){
// 处理json元素还是json的问题
JsonObject jsonObject1 = value.getAsJsonObject();
return jsonObject1;
}
} else {
// 处理字段不存在或值为 null 的情况
}
如果字段的值是一个数字,可以调用 getAsInt()、getAsLong()、getAsFloat() 或 getAsDouble() 方法将其转换为相应的数值类型。
java
if (fieldValue.isJsonPrimitive() && fieldValue.getAsJsonPrimitive().isNumber()) {
int intValue = fieldValue.getAsInt();
// 处理整数值的情况
}
如果字段的值是一个布尔值,可以调用 getAsBoolean() 方法将其转换为布尔类型。
java
if (fieldValue.isJsonPrimitive() && fieldValue.getAsJsonPrimitive().isBoolean()) {
boolean booleanValue = fieldValue.getAsBoolean();
// 处理布尔值的情况
}
如果字段的值是一个 JSON 对象,可以调用 getAsJsonObject() 方法将其转换为一个新的 JSON 对象,然后对其进行进一步处理。
java
if (fieldValue.isJsonObject()) {
JsonObject nestedObject = fieldValue.getAsJsonObject();
// 处理嵌套 JSON 对象的情况
}
这些方法可以根据字段值的类型进行适当的转换和处理,确保的代码在不同类型的字段值情况下都能正常运行。