“嗨,阿米戈!”

“嗨,艾莉!”

“既然您已经了解了 JSON,那么今天我们就来详细谈谈它。”

“好的,一般用在什么地方?”

“它通常是这样工作的。某人(客户端)从 Java 程序(服务器)请求数据。该程序创建 Java 对象并用数据库中的信息填充它们。然后将它们转换为请求者(客户端)可以使用的格式) 可以理解,例如 JSON,并将它们发回。”

“让我告诉你如何在 Java 中使用 JSON。本质上,我们只需要做两件事:将 Java 对象序列化为 JSON 格式,以及将 Java 对象从 JSON 格式反序列化。”

“换句话说,JSON 是一种将消息/数据从一个程序发送到另一个程序的标准。有很多这样的标准。但如果程序是用 JavaScript 编写的,它通常会尝试使用 JSON。”

“我准备好了。”

“太好了,那我们开始吧。”

序列化为 JSON - 1

“如您所知,Java 具有内置的标准序列化工具。但它们不支持 JSON。因此,如果您需要将对象序列化为 JSON,您可以使用一种流行的框架(库),它知道如何做这个。”

“这些不同的框架有什么区别?”

“它们的复杂程度通常不同:有些框架只能做最基本的事情,但它们又小又简单。还有一些大型复杂框架可以做更多的事情。”

“Jackson 是最流行的框架之一。我们将以它为例来了解如何使用 JSON。”

“首先,您需要下载此框架并将其添加到您的项目中。您需要直接在 IntelliJ IDEA 中执行此操作。您可以使用此链接下载该框架

“完毕。”

“太好了,那我们继续吧。”

“将 Java 对象转换为 JSON 与序列化它一样简单。为此,有一个特殊的 ObjectMapper 类 (com.fasterxml.jackson.databind.ObjectMapper)。”

“让我给你看一个工作示例,然后我们将对其进行分析:”

将对象转换为 JSON"
public static void main(String[] args) throws IOException
{
 // Create an object to be serialized into JSON
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 // Write the result of the serialization to a StringWriter
 StringWriter writer = new StringWriter();

 // This is the Jackson object that performs the serialization
 ObjectMapper mapper = new ObjectMapper();

 // And here's the serialization itself: the first argument is where, and the second is what
 mapper.writeValue(writer, cat);

 // Convert everything written to the StringWriter into a String
 String result = writer.toString();
 System.out.println(result);
}
对象转换为 JSON 的 Cat 类
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;
Cat(){}
}
序列化结果和屏幕输出:
{"name":"Missy", "age":5, "weight":4}

“这是它的工作原理:”

“在第 4-7 行中,我们创建了一个Cat对象并用数据填充它。”

“在第 10 行,我们创建了一个 Writer 对象,我们将在其中写入该对象的 JSON 字符串表示形式。”

“在第 13 行,我们创建了一个将执行所有序列化的ObjectMapper对象。”

“在第 16 行,我们将cat对象的 JSON 表示写入writer。”

“在第 19-20 行,我们将结果显示在屏幕上。”

“一切看起来都很简单。不比 Java 中的本机序列化更难。”

“反序列化会是什么样子?”

“几乎一样,只是更短:”

从 JSON 转换对象
public static void main(String[] args) throws IOException
{
 String jsonString = "{ \"name\":\"Missy\", \"age\":5, \"weight\":4}";
 StringReader reader = new StringReader(jsonString);

 ObjectMapper mapper = new ObjectMapper();

 Cat cat = mapper.readValue(reader, Cat.class);
}
其对象从 JSON 格式反序列化的类
@JsonAutoDetect
class Cat
{
 public String name;
 public int age;
 public int weight;

 Cat() { }
}

“这更容易。我们采用ObjectMapper并向其传递一个字符串或一个带有 JSON 的 StringReader,以及要反序列化的对象的类。然后我们调用readValue方法,作为输出,我们得到一个现成的 Java 对象所有的数据。”

“嗯,这与 Java 中的反序列化完全一样。”

“差不多。对序列化为 JSON 或从 JSON 反序列化的对象有几个要求:”

1) 字段必须可见:它们必须是公开的或具有 getter 和 setter”

2) 必须有一个默认构造函数(一个没有参数的)”

“我明白了。这并不奇怪。但是 Java 序列化了所有内容,甚至是私有字段。”

“嗯,那是 Java。它可以访问隐藏数据。你无法躲避自己。”

“这里还有第三个方面。我希望你注意到 Cat 类上的 @JsonAutoDetect 注释?”

“是啊。我正想问问那是什么。”

“这是一个注解:Jackson 框架的内部管理信息。通过使用正确的注解,您可以非常灵活地控制序列化为 JSON 的结果。”

“酷!有什么注解?”

“这里有一些例子:”

注解 描述
@JsonAutoDetect 放在课前。
将类标记为准备好序列化为 JSON。
@Json忽略 放置在属性之前。
该属性在序列化期间将被忽略。
@JsonProperty 放置在属性或 getter 或 setter 之前。允许您在序列化期间指定不同的字段名称。
@JsonWriteNullProperties 放在课前。
不会忽略为空的对象字段。
@JsonPropertyOrder 放在课前。
允许您在序列化期间指定字段顺序。

“真有意思!还有吗?”

“有很多。但我们现在不会介绍它们。现在让我们稍微修改一下我们的第一个例子:”

将对象转换为 JSON
public static void main(String[] args) throws IOException
{
 Cat cat = new Cat();
 cat.name = "Missy";
 cat.age = 5;
 cat.weight = 4;

 StringWriter writer = new StringWriter();

 ObjectMapper mapper = new ObjectMapper();

 mapper.writeValue(writer, cat);

 String result = writer.toString();
 System.out.println(result);
}
对象转换为 JSON 的类
@JsonAutoDetect
class Cat
{
 @JsonProperty("alias")
 public String name;
 public int age;
 @JsonIgnore
 public int weight;

 Cat() {
 }
}
序列化结果和屏幕输出:
{"age":5, "alias":"Missy"}

“代码保持不变,但我更改了注释:我为名称字段指定了另一个名称:别名。我还将权重字段标记为忽略,这导致 JSON 对象发生了变化。”

“你可以像这样定制一切,这很好。我想我肯定会觉得这很有用。”

“反序列化会理解如何使用它吗?当从 JSON 反序列化为 Java 对象时,别名字段的值将写入 Cat 对象的名称字段?”

“是的,反序列化会正常工作。这很聪明。”

“那有什么不高兴的。”

“谢谢你上了这堂有趣的课,艾莉。”