Jackson反序列化JSON数组至List<TempTimestamp>时遇类型不匹配异常
问题分析
你遇到的异常本质是JSON结构与Java类不匹配:你的data字段是嵌套数组结构(每个子数组包含日期字符串和温度数值),但Jackson默认只能将JSON对象(键值对形式)映射到POJO类,无法直接识别数组到对象的映射关系,因此抛出MismatchedInputException。
解决方案
下面提供两种直接可行的解决方式:
方式一:通过构造器注解指定数组映射关系
直接在TempTimestamp的构造器上添加@JsonCreator和@JsonProperty注解,告诉Jackson数组中每个位置的元素对应类的哪个属性:
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; public class TempTimestamp { public String date; public double temperature; @JsonCreator public TempTimestamp(@JsonProperty(0) String date, @JsonProperty(1) double temperature) { this.date = date; this.temperature = temperature; } }
之后就可以正常用Jackson解析了,推荐直接解析整个JSON(无需先转JSONArray,避免字符串转换开销):
ObjectMapper mapper = new ObjectMapper(); // 假设你已经获取到完整的JSON字符串 WeatherData weatherData = mapper.readValue(jsonString, WeatherData.class); List<TempTimestamp> dataList = weatherData.getData(); // 如果你坚持用现有JSONArray的方式,也可以直接解析: ArrayList<TempTimestamp> list = mapper.readValue(array.toString(), new TypeReference<ArrayList<TempTimestamp>>(){});
补充:可以定义一个包含data字段的顶层类来简化解析:
public class WeatherData { private List<TempTimestamp> data; public List<TempTimestamp> getData() { return data; } public void setData(List<TempTimestamp> data) { this.data = data; } }
方式二:自定义反序列化器
如果需要更灵活的解析逻辑(比如处理异常值、格式转换),可以编写自定义反序列化器:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; public class TempTimestampDeserializer extends JsonDeserializer<TempTimestamp> { @Override public TempTimestamp deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { JsonNode node = p.readValueAsTree(); String date = node.get(0).asText(); double temperature = node.get(1).asDouble(); return new TempTimestamp(date, temperature); } }
然后在TempTimestamp类上标注使用该反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = TempTimestampDeserializer.class) public class TempTimestamp { public String date; public double temperature; public TempTimestamp(String date, double temperature) { this.date = date; this.temperature = temperature; } }
之后的解析逻辑和方式一完全一致。
额外提示
- 尽量避免混合使用
org.json的JSONArray和Jackson的ObjectMapper,直接用Jackson解析整个JSON字符串会更高效且减少潜在问题。 - 如果你的日期格式有特殊要求,可以给
date字段添加@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")注解,确保日期字符串正确解析。
内容的提问来源于stack exchange,提问作者MADL
相关产品推荐
相关产品推荐

