首页 > 解决方案 > 从外部api调用json数据输入mysql数据库-Java Spring Boot Web app

问题描述

我已经设置了一个“StockPrice”实体、服务和存储库,允许将数据添加到 mysql 表中。该表具有以下列格式:col1 ... col2

我正在尝试从要放入此表的 api 中获取数据,问题是我要获取的数据是 json 数据(参数比 mysql 表中的少一些)。所以我在处理上述数据时遇到了麻烦。

在我的服务类中,我定义了以下内容:

...

@Service
public class StockPriceService {
  ...
  @PostConstruct
  public void populateStockPriceFromAPI() {

    
    ResponseEntity<List<StockPrice>> response = restTemplate.exchange(
      "https://cloud.iexapis.com/stable/stock/AAPL/chart/date/20210224?token=" + apiKey +"&chartIEXOnly=true",
      HttpMethod.GET,
      null,
      new ParameterizedTypeReference<List<StockPrice>>(){});
    List<StockPrice> result = response.getBody();

    
    
              // Save the list into a database
              if(Objects.nonNull(result)) result.stream().filter(Objects::nonNull).forEach(element -> stockPriceRepository.saveAndFlush(element));

      
    }
}

该api请求返回苹果2021年2月24日的盘中股价;并且是 json 格式:

[{'date': '2021-02-24', 'minute': '09:30', 'label': '09:30 AM', 'high': 125.34, 'low': 124.52, 'open': 124.71, 'close': 125.21, 'average': 125.034, 'volume': 22151, 'notional': 2769618.735, 'numberOfTrades': 225}, {'date': '2021-02-24', 'minute': '09:31', 'label': '09:31 AM', 'high': 125.3, 'low': 124.23, 'open': 125.175, 'close': 124.695, 'average': 125.043, 'volume': 20496, 'notional': 2562891.48, 'numberOfTrades': 110},...]

即它缺少 6 个字段 - 'Ticker'、'relative_strength'、'ma30'、'ma7'、'ma365'、'id'。id 是自动递增的,所以这应该不是问题。

当我运行时,我收到以下错误:


java.lang.ClassCastException: class java.lang.StackTraceElement cannot be cast to class java.lang.String (java.lang.StackTraceElement and java.lang.String are in module java.base of loader 'bootstrap')
    at java.base/java.io.ObjectInputStream.readTypeString(ObjectInputStream.java:1792) ~[na:na]
    at java.base/java.io.ObjectStreamClass.readNonProxy(ObjectStreamClass.java:835) ~[na:na]
    at java.base/java.io.ObjectInputStream.readClassDescriptor(ObjectInputStream.java:991) ~[na:na]
    at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2017) ~[na:na]
    at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1895) ~[na:na]
    at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2202) ~[na:na]
    at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1712) ~[na:na]
    at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2540) ~[na:na]
    at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2434) ~[na:na]
    at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2235) ~[na:na]
    at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1712) ~[na:na]
    at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:519) ~[na:na]
    at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:477) ~[na:na]
    at org.apache.catalina.session.StandardSession.doReadObject(StandardSession.java:1587) ~[tomcat-embed-core-9.0.37.jar:9.0.37]

显然 ObjectInput 失败了,但我不确定是不是因为 api 数据中的字段与我的表中的字段不同,或者它完全误解了 json 数据,因为它正在返回[na:na]。如果有人可以就如何解决这个问题给我一些建议,将不胜感激:)

标签: javamysqlspringspring-boot

解决方案


通常,当您使用 Api 发出请求时,您需要创建一个响应类并在映射到实体后,因此:

使用响应 api 的变量创建 StockPriceResponse,之后,在服务中,您可以使用 toEntity() 方法进行映射并初始化 api 不返回的变量。

我明白你的问题了吗?

例子:

public void toEntity(PreRR entity, PreRResponse obj) {
    
    entity.setDescription(obj.getDescription());
    entity.setExecutionDate(obj.getExecutionDate());
    entity.setElement(obj.getElement());
    entity.setCoccole(obj.getCoccole());
    //Variable that is not recived by api
    entity.setMario("PROVA MARIO"));
}

推荐阅读