介绍
在本实验中,我们将学习如何使用 Jackson 的 ObjectMapper
类将对象映射为 JSON,以及将 JSON 映射为对象。我们将使用一个名为 DemoClass
的简单 Java 类,并学习各种读取和写入 JSON 数据的技术。
在本实验中,我们将学习如何使用 Jackson 的 ObjectMapper
类将对象映射为 JSON,以及将 JSON 映射为对象。我们将使用一个名为 DemoClass
的简单 Java 类,并学习各种读取和写入 JSON 数据的技术。
在 ~/project
目录下创建一个新项目,并创建一个新的 DemoClass
Java 类。将以下代码粘贴到 DemoClass.java
文件中。
import java.util.Date;
public class DemoClass {
private String field1;
private Double field2;
private Date dateField;
// 构造方法
DemoClass() {}
DemoClass(String field1, Double field2, Date dateField) {
this.field1 = field1;
this.field2 = field2;
this.dateField = dateField;
}
// getters 和 setters
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public Double getField2() {
return field2;
}
public void setField2(Double field2) {
this.field2 = field2;
}
public Date getDateField() {
return dateField;
}
public void setDateField(Date dateField) {
this.dateField = dateField;
}
}
使用以下命令编译 DemoClass
Java 类:
javac DemoClass.java
我们可以使用 ObjectMapper
类的 readValue()
方法将 JSON 文件中的数据读取到一个对象中。我们的 JSON 文件仅包含一个对象的属性-值对。
创建一个名为 demo.json
的新文件,并将以下 JSON 内容粘贴到其中。
{
"field1": "Sample-1",
"field2": 20.21,
"dateField": "2021-07-30T14:20:30.000Z"
}
使用以下代码读取 JSON 文件并将其映射到 DemoClass
对象。
import java.io.File;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperDemo {
public static void main(String[] args) {
try {
String filePath = "demo.json";
File file = new File(filePath);
ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DemoClass obj = objMapper.readValue(file, DemoClass.class);
System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());
} catch (Exception e) {
System.out.println(e);
}
}
}
输出结果为:
Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021
我们可以将 JSON 字符串中的数据读取到一个对象中。我们将使用 ObjectMapper
类的 readValue()
方法。我们还需要向该方法传递 类类型。
添加以下代码以从 JSON 字符串中读取数据。
String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";
ObjectMapper objMapper = new ObjectMapper();
DemoClass obj = objMapper.readValue(jsonString, DemoClass.class);
System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());
输出结果为:
Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021
从 URL 中读取对象也非常简单。我们需要将 URL 对象和类类型传递给 readValue()
方法。
添加以下代码以从 JSON URL 中读取并映射对象。
import java.net.URL;
import java.text.SimpleDateFormat;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ObjectMapperDemo {
public static void main(String[] args) {
try {
URL jsonFileUrl = new URL("file:demo.json");
ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DemoClass obj = objMapper.readValue(jsonFileUrl, DemoClass.class);
System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());
} catch (Exception e) {
System.out.println(e);
}
}
}
输出结果与步骤 2 相同。
假设一个字符串包含多个对象数据(以数组形式)的 JSON 格式。我们可以使用 ObjectMapper
类将这些数据读取到 DemoClass
类型的数组中。
添加以下代码以将 JSON 字符串数组中的数据读取到对象数组中。
String jsonString = " [{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}," +
" {\"field1\":\"Sample-2\",\"field2\":22.55,\"dateField\":\"2021-07-31T14:20:30.000Z\"}]";
ObjectMapper objMapper = new ObjectMapper();
DemoClass[] objectArr = objMapper.readValue(jsonString, DemoClass[].class);
for (DemoClass obj : objectArr) {
System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());
System.out.println();
}
输出结果为:
Field1: Sample-1
Field2: 20.21
DateField: Fri Jul 30 14:20:30 UTC 2021
Field1: Sample-2
Field2: 22.55
DateField: Sat Jul 31 14:20:30 UTC 2021
如果我们不希望将数据读取到固定大小的对象数组中,可以将对象读取到列表中。
添加以下代码以将 JSON 字符串数组中的数据读取到对象列表中。
String jsonString = " [{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}," +
" {\"field1\":\"Sample-2\",\"field2\":22.55,\"dateField\":\"2021-07-31T14:20:30.000Z\"}]";
ObjectMapper objMapper = new ObjectMapper();
ArrayList<DemoClass> objectList = objMapper.readValue(jsonString, new TypeReference<ArrayList<DemoClass>>(){});
for (DemoClass obj : objectList) {
System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());
System.out.println();
}
输出结果与步骤 5 相同。
我们也可以将 JSON 字符串中的数据读取到一个 Map 中。类的每个属性将成为键,属性值将成为值。
添加以下代码以将 JSON 字符串数组中的数据读取到 Map 中。
String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";
ObjectMapper objMapper = new ObjectMapper();
Map<String, Object> objectMap = objMapper.readValue(jsonString, new TypeReference<Map<String, Object>>() {});
for (Map.Entry<String, Object> entry : objectMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
输出结果为:
field1: Sample-1
field2: 20.21
dateField: 2021-07-30T14:20:30.000Z
JsonNode
类为我们提供了一种更灵活的方式来解析 JSON。我们可以使用 ObjectMapper
类的 readTree()
方法将 JSON 读取为 JsonNode
对象。
添加以下代码以将 JSON 读取为 JsonNode
对象。
String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"dateField\":\"2021-07-30T14:20:30.000Z\"}";
ObjectMapper objMapper = new ObjectMapper();
JsonNode node = objMapper.readTree(jsonString);
System.out.println("Field1: " + node.get("field1").asText());
System.out.println("Field2: " + node.get("field2").asDouble());
System.out.println("DateField: " + node.get("dateField").asText());
输出结果与步骤 2 相同。
我们可以配置 ObjectMapper
,使其能够处理意外的输入。
添加以下代码以配置 ObjectMapper
忽略任何新属性。
String jsonString = "{\"field1\":\"Sample-1\",\"field2\":20.21,\"field3\":\"Unknown\"}";
ObjectMapper objMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
DemoClass obj = objMapper.readValue(jsonString, DemoClass.class);
System.out.println("Field1: " + obj.getField1());
System.out.println("Field2: " + obj.getField2());
System.out.println("DateField: " + obj.getDateField());
输出结果与步骤 2 相同。
默认情况下,ObjectMapper
会将 java.util.date
映射为一个长整型值。这个长整型值表示自 1970 年 1 月 1 日以来经过的毫秒数。
添加以下代码以演示如何使用 SimpleDateFormat
定义日期格式来序列化 java.util.date
。
ObjectMapper objMapper = new ObjectMapper();
SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MM-yyyy");
objMapper.setDateFormat(dateFormat);
DemoClass obj = new DemoClass("Sample-1", 20.21, new Date());
String jsonString = objMapper.writeValueAsString(obj);
System.out.println(jsonString);
输出结果为:
{"field1":"Sample-1","field2":20.21,"dateField":"30-07-2021"}
在本实验中,我们学习了如何使用 Jackson 的 ObjectMapper
类将对象映射为 JSON 以及将 JSON 映射为对象。我们学习了如何将 JSON 文件读取为对象、从 JSON 字符串中读取数据并将其映射为对象,以及如何从 JSON 字符串数组中读取对象到对象列表或数组中。我们还学习了如何将 JSON 字符串读取为 JsonNode
对象,并配置 ObjectMapper
以忽略新属性或基本类型的空值。最后,我们学习了如何处理日期,并在序列化 java.util.date
时使用特定的日期格式。