如何解决Jackson反序列化MismatchedInputException异常?
问题分析及解决方案
错误核心原因
存在两个致命问题导致反序列化失败:
- 数据类型不匹配:API返回的是单个JSON对象(以
{开头),但你强行用Forecast[]数组类型接收,Jackson无法将单个对象转换为数组,直接抛出MismatchedInputException。 - POJO与JSON结构完全脱节:你定义的
Forecast类字段(number/name等)和返回的JSON结构(外层properties包含updated/units等字段)完全对应不上,即使解决数组问题,也无法正确映射数据。
步骤1:重构POJO匹配JSON结构
根据返回的JSON层级,创建对应的Java类:
1.1 顶层响应类(对应外层JSON对象)
@JsonIgnoreProperties(ignoreUnknown = true) public class ForecastResponse { private Properties properties; // Getter & Setter public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } }
1.2 Properties类(对应properties字段)
@JsonIgnoreProperties(ignoreUnknown = true) public class Properties { private String updated; private String units; private String forecastGenerator; private String generatedAt; private String updateTime; private String validTimes; private Elevation elevation; // Getters & Setters public String getUpdated() { return updated; } public void setUpdated(String updated) { this.updated = updated; } public String getUnits() { return units; } public void setUnits(String units) { this.units = units; } public String getForecastGenerator() { return forecastGenerator; } public void setForecastGenerator(String forecastGenerator) { this.forecastGenerator = forecastGenerator; } public String getGeneratedAt() { return generatedAt; } public void setGeneratedAt(String generatedAt) { this.generatedAt = generatedAt; } public String getUpdateTime() { return updateTime; } public void setUpdateTime(String updateTime) { this.updateTime = updateTime; } public String getValidTimes() { return validTimes; } public void setValidTimes(String validTimes) { this.validTimes = validTimes; } public Elevation getElevation() { return elevation; } public void setElevation(Elevation elevation) { this.elevation = elevation; } }
1.3 Elevation类(对应elevation子字段)
@JsonIgnoreProperties(ignoreUnknown = true) public class Elevation { private String unitCode; private double value; // Getters & Setters public String getUnitCode() { return unitCode; } public void setUnitCode(String unitCode) { this.unitCode = unitCode; } public double getValue() { return value; } public void setValue(double value) { this.value = value; } }
步骤2:修正Controller接收逻辑
把RestTemplate的返回类型改为ForecastResponse,不再使用数组:
@Controller @RequestMapping("/test") public class ConsumeController { RestTemplate restTemplate = new RestTemplate(); @RequestMapping("/show") public ModelAndView showForecast() { ModelAndView mv = new ModelAndView(); mv.setViewName("show"); // 改为接收单个ForecastResponse对象 ResponseEntity<ForecastResponse> responseEntity = restTemplate.getForEntity("https://api.golde.gov", ForecastResponse.class); ForecastResponse responseBody = responseEntity.getBody(); // 将响应对象传入视图 mv.addObject("forecastData", responseBody); System.out.println("data: " + responseBody); return mv; } }
步骤3:调整JSP展示逻辑
根据新的数据结构修改EL表达式,示例如下:
<p>Forecast Details:</p> <div> <p>Last Updated: ${forecastData.properties.updated}</p> <p>Units: ${forecastData.properties.units}</p> <p>Elevation: ${forecastData.properties.elevation.value} ${forecastData.properties.elevation.unitCode}</p> <!-- 其他字段可按需添加 --> </div>
额外说明
@JsonIgnoreProperties(ignoreUnknown = true):确保API返回未定义的额外字段时,Jackson不会抛出反序列化错误。- 如果你原本期望API返回Forecast数组,需要确认API的正确端点——当前调用的
https://api.golde.gov返回的是单个对象,并非数组。
内容的提问来源于stack exchange,提问作者Khanh Luong Van
相关产品推荐
相关产品推荐

