如何使用 Jackson 处理 YAML
1. 依赖项
让我们添加 Jackson YAML 数据格式的依赖:
<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId><version>2.13.0</version>
</dependency>
我们总可以在 Maven 中央仓库找到此依赖的最新版本。
我们的 Java 对象使用了 LocalDate,所以我们也需要添加 JSR-310 数据类型的依赖:
<dependency><groupId>com.fasterxml.jackson.datatype</groupId><artifactId>jackson-datatype-jsr310</artifactId><version>2.13.0</version>
</dependency>
我们可以在 Maven 中央仓库查找它的最新版本。
2. 数据和对象结构
有了依赖问题解决之后,我们现在来看一下输入文件以及我们将要用到的 Java 类。
首先,我们来看一下将要读取的文件:
orderNo: A001
date: 2019-04-17
customerName: Customer, Joe
orderLines:- item: No. 9 Sprocketsquantity: 12unitPrice: 1.23- item: Widget (10mm)quantity: 4unitPrice: 3.45
然后,我们定义 Order 类:
public class Order {private String orderNo;private LocalDate date;private String customerName;private List<OrderLine> orderLines;// Constructors, Getters, Setters and toString
}
最后,我们来创建我们的 OrderLine 类:
public class OrderLine {private String item;private int quantity;private BigDecimal unitPrice;// Constructors, Getters, Setters and toString
}
3. 读取 YAML
我们将使用 Jackson 的 ObjectMapper 将 YAML 文件读取到 Order 对象中,所以现在我们来设置一下:
mapper = new ObjectMapper(new YAMLFactory());
我们需要使用 findAndRegisterModules 方法,以便 Jackson 能够正确处理我们的 Date:
mapper.findAndRegisterModules();
一旦我们配置好了 ObjectMapper,我们只需使用 readValue:
Order order = mapper.readValue(new File("src/main/resources/orderInput.yaml"), Order.class);
我们会发现 Order 对象已经从文件中被填充,包括 OrderLine 列表。
4. 编写 YAML
我们还将使用 ObjectMapper 将 Order 写入文件。但在开始之前,让我们为其添加一些配置:
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
添加这一行可以让 Jackson 将日期写成字符串形式,而不是单独的数字部分。
默认情况下,我们的文件将以三个破折号开始。这在 YAML 格式中是完全有效的,但我们可以通过在 YAMLFactory 上禁用该功能来关闭此功能:
mapper = new ObjectMapper(new YAMLFactory().disable(Feature.WRITE_DOC_START_MARKER));
有了这些额外的设置,我们来创建一个 Order:
List<OrderLine> lines = new ArrayList<>();
lines.add(new OrderLine("Copper Wire (200ft)", 1, new BigDecimal(50.67).setScale(2, RoundingMode.HALF_UP)));
lines.add(new OrderLine("Washers (1/4\")", 24, new BigDecimal(.15).setScale(2, RoundingMode.HALF_UP)));
Order order = new Order("B-9910", LocalDate.parse("2019-04-18", DateTimeFormatter.ISO_DATE),"Customer, Jane", lines);
让我们使用 writeValue 来编写我们的订单:
mapper.writeValue(new File("src/main/resources/orderOutput.yaml"), order);
当我们查看 orderOutput.yaml 时,它应该类似于:
orderNo: "B-9910"
date: "2019-04-18"
customerName: "Customer, Jane"
orderLines:
- item: "Copper Wire (200ft)"quantity: 1unitPrice: 50.67
- item: "Washers (1/4\")"quantity: 24unitPrice: 0.15