Spring Boot中反序列化PokéAPI JSON数组遇问题求助
Pokemon接口JSON反序列化错误排查
接口返回数据
[ { "location_area": { "name": "sinnoh-route-218-area", "url": "https://pokeapi.co/api/v2/location-area/168/" } }, { "location_area": { "name": "johto-route-34-area", "url": "https://pokeapi.co/api/v2/location-area/205/" } } ]
第一次尝试与错误
调用代码:
restTemplate.exchange("https://pokeapi.co/api/v2/pokemon/25/encounters", HttpMethod.GET, null, new ParameterizedTypeReference<LocationAreaEncounters>(){ })
抛出错误:
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `com.bankaya.pokemon.dto.LocationAreaEncounters` from Array value (token `JsonToken.START_ARRAY`) at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 1, column: 1]
实体类定义
@Data @AllArgsConstructor @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) public class LocationAreaEncounters { @JsonProperty("location_area") private List<Location_Area> locationArea; } @Data @AllArgsConstructor @NoArgsConstructor @JsonRootName("location_area") @JsonIgnoreProperties(ignoreUnknown = true) public class Location_Area { @JsonProperty("name") private String name; @JsonProperty("url") private String url; }
第二次尝试与结果
调用代码:
restTemplate.exchange("https://pokeapi.co/api/v2/pokemon/25/encounters", HttpMethod.GET, null, new ParameterizedTypeReference<List<Location_Area>>(){ })
结果:获取到正确数量的对象,但所有字段值为null:
"locationAreas": [ { "name": null, "url": null } ]
错误原因与解决方案
错误1:类型不匹配(第一次尝试)
接口返回的是JSON数组,但你用单个对象LocationAreaEncounters接收,Jackson无法将数组反序列化成单个对象,因此抛出类型不匹配错误。你的LocationAreaEncounters结构对应{"location_area": [...]}这种单个对象,和接口返回的数组结构完全不符。
错误2:字段映射不匹配(第二次尝试)
接口数组中的每个元素是一个包含location_area字段的对象,而你直接用List<Location_Area>接收,Jackson找不到name/url字段(因为它们被包裹在location_area里),因此字段值为null。
正确解决方案
- 新增中间实体类,对应数组中的每个元素:
@Data @AllArgsConstructor @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) public class EncounterEntry { @JsonProperty("location_area") private Location_Area locationArea; }
- 修改
Location_Area类,移除不必要的@JsonRootName(因为它不是根对象):
@Data @AllArgsConstructor @NoArgsConstructor @JsonIgnoreProperties(ignoreUnknown = true) public class Location_Area { private String name; private String url; }
- 正确调用方式,用
List<EncounterEntry>接收数组:
restTemplate.exchange("https://pokeapi.co/api/v2/pokemon/25/encounters", HttpMethod.GET, null, new ParameterizedTypeReference<List<EncounterEntry>>(){});
这样就能正确反序列化接口返回的JSON数据,获取到非null的name和url字段值。
内容的提问来源于stack exchange,提问作者Yerri
相关产品推荐
相关产品推荐

