JSON 解析错误:无法反序列化 START_ARRAY 令牌中的实例
Posted
技术标签:
【中文标题】JSON 解析错误:无法反序列化 START_ARRAY 令牌中的实例【英文标题】:JSON parse error: Cannot deserialize instance of `` out of START_ARRAY token 【发布时间】:2020-04-03 08:44:54 【问题描述】:我是 Spring Boot 和 API 的新手,我正在开发一个项目,我需要从公共 API 获取数据并将其存储到本地数据库,尽管我的 Spring Boot 应用程序与 mysql 数据库连接。从 API 获取数据时,我的编译器抛出异常:
Error while extracting response for type [class com.currencyExchangeRates.models.CurrencyDTO] and content type [application/json;charset=utf-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of `com.currencyExchangeRates.models.CurrencyDTO` out of START_ARRAY token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `com.currencyExchangeRates.models.CurrencyDTO` out of START_ARRAY token
at [Source: (PushbackInputStream); line: 1, column: 1]
我的总体思路是从公共 API 获取数据,将其存储在本地数据库中,然后根据我的项目要求使用这些数据。
我已经尝试了几乎所有来自 google 和 *** 的解决方案,但我没有任何想法。
我正在尝试获取的 JSON 格式:
[
"table":"A",
"no":"237/A/NBP/2019",
"effectiveDate":"2019-12-09",
"rates":[
"currency":"bat (Tajlandia)",
"code":"THB",
"mid":0.1277
,
"currency":"dolar amerykański",
"code":"USD",
"mid":3.8704
]
]
这里,我的 CurrencyDTO 类:
public class CurrencyDTO
private String table;
private String num;
private String date;
private Rates rates;
// Getters and Setters, No-arg/arg constractor
Rates.java
public class Rates
private String currency;
private Map<String, Double> price;
// Getters and Setters, No-arg/arg constractor
我调用 API 的一段代码:
try
RestTemplate restTemplate = new RestTemplate();
CurrencyDTO forObject =
restTemplate.getForObject("http://api.nbp.pl/api/exchangerates/tables/a/", CurrencyDTO.class);
forObject.getRates().getPrice().forEach((key, value) ->
Currency currency = new Currency(key, value);
this.currencyRepository.save(currency);
);
catch (RestClientException ex)
System.out.println(ex.getMessage());
控制器类:
@GetMapping("/currency")
public List<Currency> findAll()
return currencyService.getAllCurrencies();
【问题讨论】:
【参考方案1】:此外,您共享的 json 是 CurrencyDTO 数组。假设你的 Json 是,
"table":"A",
"no":"237/A/NBP/2019",
"effectiveDate":"2019-12-09",
"rates":[
"currency":"bat (Tajlandia)",
"code":"THB",
"mid":0.1277
,
"currency":"dolar amerykański",
"code":"USD",
"mid":3.8704
]
将您的 CurrencyDTO 更改为,
@Data
@NoArgsConstructor
public class CurrencyDTO
private String table;
private String no;
private String effectiveDate;
private List<Rates> rates;
和你的 Rates 类,
@Data
@NoArgsConstructor
public class Rates
private String currency;
private String code;
private Double mid;
它能够为我反序列化。 您做错的是 Dto 实例变量应该根据 Json 中的名称,或者您应该使用 @JsonProperty("nameInTheJson")。
如果你想让它与你的 JSON 兼容,你可以使用 Array of CurrencyDTO 您将能够反序列化,您可以将对象用作,
try
RestTemplate restTemplate = new RestTemplate();
CurrencyDTO[] forObject =
restTemplate.getForEntity("http://api.nbp.pl/api/exchangerates/tables/a/", CurrencyDTO[].class).getBody();
for (CurrencyDTO currencyDTO1 : forObject)
for (Rates rate : currencyDTO1.getRates())
Currency currency = new Currency(rate.getCode(), rate.getMid());
//you code to put the object inside the db
this.currencyRepository.save(currency);
catch (Exception ex)
System.out.println(ex.getMessage());
【讨论】:
【参考方案2】:首先,您的 JSON 是 CurrencyDTO 数组,而不仅仅是评论中提到的 CurrencyDTO,现在如果它影响代码的其他部分并且您只想按原样反序列化它,那么您可以执行以下操作:
CurrencyDTO[] forObject = new ObjectMapper.readValue(restTemplate.getForEntity("http://api.nbp.pl/api/exchangerates/tables/a/", CurrencyDTO[].class).getBody() , new TypeReference<List<CurrencyDTO>>() ).get(0);
另外,我强烈建议这是你应该做的最糟糕的方式。最好更新您的 API 以返回正确的响应。
【讨论】:
以上是关于JSON 解析错误:无法反序列化 START_ARRAY 令牌中的实例的主要内容,如果未能解决你的问题,请参考以下文章
JSON 解析错误:无法反序列化 START_ARRAY 令牌中的实例
JSON 解析错误:无法从 START_OBJECT 令牌中反序列化 java.util.ArrayList 的实例
反序列化 Json 出现错误“无法反序列化当前 JSON 数组”