【发布时间】:2019-11-01 20:23:02
【问题描述】:
我正在尝试读取 YAML 文件并将结果存储在 POJO 列表中。
我无法修改 YAML 文件。我使用 Jackson 2.10.0,但我对任何其他版本持开放态度。我正在尝试用 Jackson 解析以下脚本:
vehicles-notype.yaml
Vehicles 基本上是一个对象列表,这些对象具有一些共同属性和一些特定于车辆类型的属性。
---
vehicles:
- car:
make: "Mercedes-Benz"
model: "S500"
topSpeed: 250.0
seatingCapacity: 5
- truck:
make: "Isuzu"
model: "NQR"
payloadCapacity: 7500.0
所需的输出
阅读文件后,我想,如果我反省列表,我想得到:
... App.java:48): -> start()
... App.java:56): class net.jgp.labs.jackson.yaml.lab411_pojos.Car
... App.java:56): class net.jgp.labs.jackson.yaml.lab411_pojos.Truck
Car 和 Truck POJO 非常明显:
汽车
package net.jgp.labs.jackson.yaml.lab411_pojos;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Car extends Vehicle {
private int seatingCapacity;
private double topSpeed;
@JsonCreator
public Car(
@JsonProperty("make") String make,
@JsonProperty("model") String model,
@JsonProperty("seating") int seatingCapacity,
@JsonProperty("topSpeed") double topSpeed) {
super(make, model);
this.seatingCapacity = seatingCapacity;
this.topSpeed = topSpeed;
}
public int getSeatingCapacity() {
return seatingCapacity;
}
public void setSeatingCapacity(int seatingCapacity) {
this.seatingCapacity = seatingCapacity;
}
public double getTopSpeed() {
return topSpeed;
}
public void setTopSpeed(double topSpeed) {
this.topSpeed = topSpeed;
}
public String getType() {
return "car";
}
}
卡车
package net.jgp.labs.jackson.yaml.lab411_pojos;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
public class Truck extends Vehicle {
private double payloadCapacity;
@JsonCreator
public Truck(
@JsonProperty("make") String make,
@JsonProperty("model") String model,
@JsonProperty("payload") double payloadCapacity) {
super(make, model);
this.payloadCapacity = payloadCapacity;
}
public double getPayloadCapacity() {
return payloadCapacity;
}
public void setPayloadCapacity(double payloadCapacity) {
this.payloadCapacity = payloadCapacity;
}
@Override
public String getType() {
return "truck";
}
}
舰队
Fleet POJO 也很明显。
package net.jgp.labs.jackson.yaml.lab411_pojos;
import java.util.List;
public class Fleet {
private List<Vehicle> vehicles;
public void setVehicles(List<Vehicle> vehicles) {
this.vehicles= vehicles;
}
public List<Vehicle> getVehicles() {
return vehicles;
}
}
车辆
Vehicle 有点棘手,因为我正在尝试使用@JsonTypeInfo 和@JsonSubTypes。你可以看到注释代码,这让我慢慢发疯:
package net.jgp.labs.jackson.yaml.lab411_pojos;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonSubTypes.Type;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use = JsonTypeInfo.Id.CLASS,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY
// ,
// property = "className"
)
@JsonSubTypes({
@Type(value = Car.class, name = "car"),
@Type(value = Truck.class, name = "truck")
})
//@JsonSubTypes({
// @Type(value = Car.class, name = "car"),
// @Type(value = Truck.class, name = "truck")
//})
public abstract class Vehicle {
private String make;
private String model;
@JsonProperty("type")
abstract public String getType();
public void setType(String type) {};
protected Vehicle(String make, String model) {
this.make = make;
this.model = model;
}
public String getMake() {
return make;
}
public void setMake(String make) {
this.make = make;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
}
应用
最后是应用程序代码,这也很明显。
package net.jgp.labs.jackson.yaml.lab411_read_diff_objects;
import java.io.File;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import net.jgp.labs.jackson.yaml.lab411_pojos.Fleet;
import net.jgp.labs.jackson.yaml.lab411_pojos.Vehicle;
/**
* What does it do?
*
* @author jgp
*/
public class ReadListVehicleNoTypeApp {
private static final Logger log =
LoggerFactory.getLogger(ReadListVehicleNoTypeApp.class);
/**
* main() is your entry point to the application.
*
* @param args
*/
public static void main(String[] args) {
ReadListVehicleNoTypeApp app = new ReadListVehicleNoTypeApp();
try {
app.start();
} catch (JsonProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* The processing code.
*
* @throws IOException
*/
protected boolean start() throws IOException {
log.debug("-> start()");
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
Fleet fleet = mapper.readValue(new File("data/vehicles-notype.yaml"),
Fleet.class);
for (Vehicle v : fleet.getVehicles()) {
log.debug("{}", v.getClass());
}
return true;
}
}
我很确定@Json 属性系列可以发挥作用,但我正在慢慢失去它;-)。
【问题讨论】: