“嗨,阿米戈!”
“嗨,艾莉!”
“既然您已经了解了 JSON,那么今天我们就来详细谈谈它。”
“好的,一般用在什么地方?”
“它通常是这样工作的。某人(客户端)从 Java 程序(服务器)请求数据。该程序创建 Java 对象并用数据库中的信息填充它们。然后将它们转换为请求者(客户端)可以使用的格式) 可以理解,例如 JSON,并将它们发回。”
“让我告诉你如何在 Java 中使用 JSON。本质上,我们只需要做两件事:将 Java 对象序列化为 JSON 格式,以及将 Java 对象从 JSON 格式反序列化。”
“换句话说,JSON 是一种将消息/数据从一个程序发送到另一个程序的标准。有很多这样的标准。但如果程序是用 JavaScript 编写的,它通常会尝试使用 JSON。”
“我准备好了。”
“太好了,那我们开始吧。”
“如您所知,Java 具有内置的标准序列化工具。但它们不支持 JSON。因此,如果您需要将对象序列化为 JSON,您可以使用一种流行的框架(库),它知道如何做这个。”
“这些不同的框架有什么区别?”
“它们的复杂程度通常不同:有些框架只能做最基本的事情,但它们又小又简单。还有一些大型复杂框架可以做更多的事情。”
“Jackson 是最流行的框架之一。我们将以它为例来了解如何使用 JSON。”
“首先,您需要下载此框架并将其添加到您的项目中。您需要直接在 IntelliJ IDEA 中执行此操作。您可以使用此链接下载该框架。 ”
“完毕。”
“太好了,那我们继续吧。”
“将 Java 对象转换为 JSON 与序列化它一样简单。为此,有一个特殊的 ObjectMapper 类 (com.fasterxml.jackson.databind.ObjectMapper)。”
“让我给你看一个工作示例,然后我们将对其进行分析:”
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);
}
@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 中的本机序列化更难。”
“反序列化会是什么样子?”
“几乎一样,只是更短:”
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);
}
@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 | 放在课前。 允许您在序列化期间指定字段顺序。 |
“真有意思!还有吗?”
“有很多。但我们现在不会介绍它们。现在让我们稍微修改一下我们的第一个例子:”
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);
}
@JsonAutoDetect
class Cat
{
@JsonProperty("alias")
public String name;
public int age;
@JsonIgnore
public int weight;
Cat() {
}
}
{"age":5, "alias":"Missy"}
“代码保持不变,但我更改了注释:我为名称字段指定了另一个名称:别名。我还将权重字段标记为忽略,这导致 JSON 对象发生了变化。”
“你可以像这样定制一切,这很好。我想我肯定会觉得这很有用。”
“反序列化会理解如何使用它吗?当从 JSON 反序列化为 Java 对象时,别名字段的值将写入 Cat 对象的名称字段?”
“是的,反序列化会正常工作。这很聪明。”
“那有什么不高兴的。”
“谢谢你上了这堂有趣的课,艾莉。”
GO TO FULL VERSION