Json 反序列化并在启动时保存到 JPA



早上好, 我使用JSON格式的API,最新汇率数据。

我希望这些数据在应用程序开始时下载给我并保存在数据库中。我使用弹簧JPA。

问题是我不知道我应该如何写下来。

我有一个负责连接的类,它以字符串的形式返回输出。 另一个创建反序列化。

我还有两类模型可以用来下载数据。

我不想创建一个单独的类,程序将在其中单独提取每个值。我在想地图,但我不知道该怎么做。

一些代码:

型号 1

@Data
@AllArgsConstructor
@Entity
public class CurrencyData {
@Id
@GeneratedValue( strategy = GenerationType.AUTO )
private Long id;
@SerializedName("rates")
@Expose
@Embedded
private Rates rates;
@SerializedName("base")
@Expose
@Embedded
private String base;
@SerializedName("date")
@Expose
@Embedded
private String date;
}

型号 2

@Data
@AllArgsConstructor
@Embeddable
public class Rates {
protected Rates(){}
@SerializedName("CAD")
@Expose
private Double cAD;
@SerializedName("HKD")
}

具有字符串 api 输出的连接服务

private static final String REQUEST_CURRENCY = "https://api.exchangeratesapi.io/latest?base=USD";
public String connect() {
String output = null;
try {
System.out.println("URL String : " + REQUEST_CURRENCY);
URL url = new URL(REQUEST_CURRENCY);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
if (conn.getResponseCode() != 200) {
throw new TODO("TODO : ", e.getMessage());
} else {
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
output = response.toString();
}
} catch (Exception e) {
throw new OutputFromApiException("ConnectService CurrencyData-API: output is : ", e.getMessage());
}
return output;
}

Gson转换 - 反序列化

public CurrencyData gsonCurrency(String answer) {
Gson g = new Gson();
CurrencyData currencyData = null;
try {
currencyData = g.fromJson(answer, CurrencyData.class);
} catch (Exception e) {
throw new OutputFromApiException("HistoricalFlight API output is empty ", e.toString());
}

return currencyData;
}

存储 库

@Repository
public interface CurrencyRepository extends JpaRepository<CurrencyData, Long> {
}

。可能我必须在这里写点什么..

@Bean
CommandLineRunner runner(CurrencyRepository currencyRepository) {
return args -> {
currencyRepository.save();
};
}

如果您使用的是 Spring Boot,我认为您应该定义一个实现CommandLineRunner的主类,而不是将其定义为@Bean。它应该是这样的:

@SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringBootConsoleApplication.class, args);
}
@Autowired
CurrencyRepository currencyRepository;
@Autowired
ConnectService connectionService;
@Override
public void run(String... args) {
String output = connectionService.connect();
CurrencyData currencyData = connectionService.gsonCurrency(output);
currencyRepository.save(currencyData);
} 
}

此外,我假设您的jpa配置是正确的,并且您的CurrencyRepository按预期工作。如果您没有手动创建的数据库结构,则可以考虑将文件添加到application.properties

spring.jpa.hibernate.ddl-auto=update

这将为您提供 JPA 使用实体配置在每次引导时创建或更新正确的数据库结构。

编辑: 抱歉,我忘了提到您应该将要保留的实体传递到数据库中。我编辑了代码,因为我想gsonCurrency方法是ConnectionService中的一种方法。如果您想根据不同的基础货币获取不同的数据,也可以将参数传递给connectionService.connect()方法base,如下所示:

CurrencyData currencyDataUSD = connectionService.gsonCurrency(connectionService.connect("USD"));
CurrencyData currencyDataEUR = connectionService.gsonCurrency(connectionService.connect("EUR"));
// and go on if you like

您可以使用 Spring Boot and Rest 模板,以便可以轻松管理消息转换,而无需编写低级 HttpConnection。当应用程序在Spring Boot中启动时,有两种方法可以执行方法,CommandLineRunner和ApplicationRunner,这里我们使用第一种方法,如下所示:

@SpringBootApplication
public class Application {
private static final Logger log = LoggerFactory.getLogger(Application.class);
public static void main(String args[]) {
SpringApplication.run(Application.class);
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.build();
}
@Bean
public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
return args -> {
Quote quote = restTemplate.getForObject(
"https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
log.info(quote.toString());
};
}

}

来源: https://spring.io/guides/gs/consuming-rest/

最新更新