我正在尝试使用JSON。我有一些可以很好地序列化对象的代码,但是尝试反序列化时出现了MismatchedInputException异常,无法从START_ARRAY令牌中反序列化com.john.irrigator3.irrigation.WateringSchedule
实例
我猜杰克逊在我的WateringScheduleCollection中反序列化数组时遇到了麻烦,并且我尝试过更改要添加到数组中的方法的名称,没有创建任何参数构造函数,但是我遇到了麻烦。有人可以告诉我我要去哪里拧吗?
WaterScheduleCollection:
public class WateringScheduleCollection {
Map<String, WateringSchedule> schedules = new LinkedHashMap<>();
public void removeSchedule(String name) {
schedules.remove(name);
}
public void addSchedule(WateringSchedule wateringSchedule) {
schedules.put(wateringSchedule.getName(), wateringSchedule);
}
public Map<String, WateringSchedule> getSchedules() {
return schedules;
}
}
WateringSchedule:
public class WateringSchedule {
String name;
ArrayList<WateringRoutine> wateringRoutines;
SeasonLimits seasonLimits = null;
int sprinkleDuration = 30;
public WateringSchedule() {
wateringRoutines = new ArrayList<WateringRoutine>();
}
public WateringSchedule(List<WateringRoutine> wateringRoutines) {
this();
for (WateringRoutine wateringRoutine : wateringRoutines) {
addWateringRoutine(wateringRoutine);
}
}
public void addWateringRoutine(WateringRoutine wateringRoutine) {
wateringRoutines.add(wateringRoutine);
}
public ArrayList<WateringRoutine> getWateringRoutines() {
return wateringRoutines;
}
序列化可以很好地解决此问题:
public void writeFile(){
WateringRoutine wr1 = new WateringRoutine(0,1,10);
WateringRoutine wr2 = new WateringRoutine(1,2,100);
WateringRoutine wr3 = new WateringRoutine(2,3,1000);
SeasonLimits seasonLimits = new SeasonLimits(4, 1, 6, 7);
WateringSchedule wateringSchedule1 = new WateringSchedule();
wateringSchedule1.setName("wateringSchedule1");
wateringSchedule1.addWateringRoutine(wr1);
wateringSchedule1.addWateringRoutine(wr2);
WateringSchedule wateringSchedule2 = new WateringSchedule();
wateringSchedule2.setName("wateringSchedule2");
wateringSchedule2.addWateringRoutine(wr2);
wateringSchedule2.addWateringRoutine(wr3);
WateringSchedule wateringSchedule3 = new WateringSchedule();
wateringSchedule3.setName("wateringSchedule3");
wateringSchedule3.addWateringRoutine(wr1);
wateringSchedule3.addWateringRoutine(wr2);
wateringSchedule3.addWateringRoutine(wr3);
wateringSchedule3.setSeasonLimits(seasonLimits);
WateringScheduleCollection wateringScheduleCollection = new WateringScheduleCollection();
wateringScheduleCollection.addSchedule(wateringSchedule1);
wateringScheduleCollection.addSchedule(wateringSchedule2);
wateringScheduleCollection.addSchedule(wateringSchedule3);
ObjectMapper mapper = new ObjectMapper();
mapper.getSerializerProvider().setNullKeySerializer(new MyDtoNullKeySerializer());
mapper.enable(SerializationFeature.INDENT_OUTPUT);
String json = null;
try {
json = mapper.writeValueAsString(wateringScheduleCollection);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
System.out.println(json);
}
给出以下输出:
{
"schedules" : {
"wateringSchedule1" : {
"name" : "wateringSchedule1",
"wateringRoutines" : [ {
"secsWatering" : 1,
"hoursAllowedWithoutWater" : 10.0,
"scheduleSprinkle" : false,
"age" : 0
}, {
"secsWatering" : 2,
"hoursAllowedWithoutWater" : 100.0,
"scheduleSprinkle" : false,
"age" : 1
} ],
"seasonLimits" : null,
"sprinkleDuration" : 30
},
"wateringSchedule2" : {
"name" : "wateringSchedule2",
"wateringRoutines" : [ {
"secsWatering" : 2,
"hoursAllowedWithoutWater" : 100.0,
"scheduleSprinkle" : false,
"age" : 1
}, {
"secsWatering" : 3,
"hoursAllowedWithoutWater" : 1000.0,
"scheduleSprinkle" : false,
"age" : 2
} ],
"seasonLimits" : null,
"sprinkleDuration" : 30
},
"wateringSchedule3" : {
"name" : "wateringSchedule3",
"wateringRoutines" : [ {
"secsWatering" : 1,
"hoursAllowedWithoutWater" : 10.0,
"scheduleSprinkle" : false,
"age" : 0
}, {
"secsWatering" : 2,
"hoursAllowedWithoutWater" : 100.0,
"scheduleSprinkle" : false,
"age" : 1
}, {
"secsWatering" : 3,
"hoursAllowedWithoutWater" : 1000.0,
"scheduleSprinkle" : false,
"age" : 2
} ],
"seasonLimits" : {
"startOfSeason" : 1554098900367,
"endOfSeason" : 1559887700367,
"monthStart" : 4,
"dayStart" : 1,
"monthEnd" : 6,
"dayEnd" : 7
},
"sprinkleDuration" : 30
}
}
}
但尝试使用以下代码反序列化:
public void readFile() {
ObjectMapper objectMapper = new ObjectMapper();
try {
WateringScheduleCollection wsc = objectMapper.readValue(new File(testPath+fileName), WateringScheduleCollection.class);
System.out.println(wsc.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
导致:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.john.irrigator3.irrigation.WateringSchedule` out of START_ARRAY token
at [Source: (File); line: 3, column: 15] (through reference chain: com.john.irrigator3.irrigation.WateringScheduleCollection["schedules"]->java.util.LinkedHashMap["schedule"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
答案 0 :(得分:0)
我认为Jackson在选择Collection实现(LinkedHashMap
,ArrayList
)而不是接口(Map
,List
)时遇到问题。
通常,杰克逊会选择一些默认值(例如,我猜的是ArrayList
的{{1}})。
请参考此答案以指定预期的接口实现:
Jackson - How to specify a single implementation for interface-referenced deserialization?
答案 1 :(得分:0)
我刚刚发现我做错了什么。我正在将JSON写入文件,然后读取文件进行反序列化。好吧,那是我以为我在做的事情。原来,我正在写一个文件,而在读另一个文件。看到了这个愚蠢的错误之后,JSON就可以正常工作了,可以毫无问题地进行序列化和反序列化。
感谢您的回答,但我真正需要的是解决愚蠢问题的方法。