jackson JSON解析错误:无法反序列化START_ARRAY标记之外的``示例

q5lcpyga  于 7个月前  发布在  其他
关注(0)|答案(3)|浏览(82)

我是Sping Boot 和API的新手,我正在做一个项目,我需要从公共API获取数据并将其存储到本地数据库,尽管我的Sping Boot 应用程序与MySQL数据库连接。当从API获取数据时,我的编译器抛出一个异常,说:
提取类型[class com.currencyExchangeRates.models.CurrencyDTO]和内容类型[application/json; int n = int n];嵌套异常为org.springframework.http.converter.HttpMessageNotReadableException:JSON解析错误:无法将START_ARRAY内标识之外的com.currencyExchangeRates.models.CurrencyDTO示例化;嵌套异常为com.fasterxml.Jackson.databind.exc.MismatchedInputException:无法在[Source:(PushbackInputStream);行:1,列:第1页]
我的总体想法是从公共API获取数据,将其存储在本地数据库中,然后根据我的项目需求使用这些数据。
我试过Google和Stack Overflow的几乎所有解决方案,但我没有任何想法。
我正在尝试获取的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();
    }
to94eoyn

to94eoyn1#

另外,你分享的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;
}

和你的等级

@Data
@NoArgsConstructor
public class Rates {

    private String currency;
    private String code;
    private Double mid;
}

它能为我实现。你做错的是Dto示例变量应该根据Json中的name,或者你应该使用**@JsonProperty(“nameInTheJson”)**。
如果你想让它与你的JSON兼容,你可以使用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());
        }
ppcbkaq5

ppcbkaq52#

首先,你的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以返回正确的响应。

uelo1irk

uelo1irk3#

如果有人使用nextjs,调用API,也许你会错过
JSON.stringify,因此spring Boot 无法解析
在nextjs中调用API

const resPut = await fetch(`${API_URL}/products/${productId}`, {
        method: "PUT",
        headers: {
          Authorization: `Bearer ${token}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify(req.body),  //   // forget convert json -> json invalid - cannot parse json array
      });

相关问题