当前位置:Java -> JBang:如何使用Java脚本从API导入数据
正值繁忙的会议季,我正在为即将到来的会议演讲做准备。
像往常一样,我去Neo4j Aura,启动一个免费的数据库,并使用APOC中的Cypher来从API导入数据,但是这个API需要一个头部,而在Aura中,用于添加请求头的APOC过程被安全性限制了。嗯,我需要新的途径。
我决定尝试JBang,这是一个用Java进行脚本编写的工具。我早就听说过它,但还没有尝试过。它很酷,所以我想分享一下我上手的过程。
Java开发者多年来一直在抱怨Java缺乏脚本语言。JBang解决了这个问题。我在InfoQ的一篇文章中找到了关于JBang的精彩概述(Scripting Java with a jBang)。
JBang提供了一种以脚本的方式运行Java代码的方法...[它]是一个启动脚本,用bash和powershell编写,可以发现或下载JVM,然后(下)载给定参数的Java脚本。JBang的实现是一个Java JAR存档,然后启动以执行进一步的命令。
JBang可以运行jsh或java文件;后者是一个带有main()方法的标准Java类。但是,与JShell不同,JBang允许在脚本顶部的注释中自动下载并设置类路径上的依赖项。JShell允许在启动时将JAR添加到类路径,但任何(递归的)依赖项都必须手动添加。
JBang似乎是使用全功能的Java项目或Linux脚本的一种更好的选择。在我们进入编写脚本之前,让我们对我们将要从中提取数据的数据API做更详细的配置!
首先,我们需要从下载页面安装JBang。我必须找到适合我的操作系统的下载,并选择安装类型。由于我使用SDKMan来管理我的Java版本,我也使用SDKMan安装JBang。
sdk install jbang
许多IDEs也有JBang的插件,包括IntelliJ。IntelliJ插件似乎具有几个不错的特性,包括导入建议。但是,我在尝试从现有项目或随机创建的脚本中使用它时遇到了麻烦,我必须创建一个使用JBang初始化的单独项目。也许我需要稍微调整一下,因为它可能会简化导入问题(稍后会讨论)。无论如何,我决定稍后再处理插件,现在暂时只使用命令行。
我想导入关于宠物旅行的数据,我知道我想要使用的Yelp Fusion API。这也是要求请求头的API,这正式我第一次接触JBang的原因。
Yelp API有一个非常有用的playground,在那里我可以在开始编写脚本之前测试一些请求。我还使用playground来验证语法,并获取Java中API调用的示例代码。
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://api.yelp.com/v3/businesses/search?location=" + location + "&categories=" + category + "&attributes=dogs_allowed&limit=50&sort_by=distance")
.get()
.addHeader("accept", "application/json")
.addHeader("Authorization", "Bearer " + yelpApiKey)
.build();
Response response = client.newCall(request).execute();
现在,我稍微调整了上面的代码,使用location
、category
和yelpApiKey
的占位变量,这样我以后可以传入任意值。playground代码示例会自动包含API令牌,因此我将上面的代码块复制/粘贴到我的JBang脚本中,然后需要回去添加依赖项。
这正是JBang稍微不方便的地方,一个IDE插件可能会派上用场。我必须前往Maven中央仓库,并搜索我需要的依赖项。这里没有自动导入,这是有道理的,因为我们没有像Maven或Spring那样的依赖管理器可以潜在地搜索适用的导入建议。
我还想要从Yelp提供的多个(众多)类别中提取宠物旅行数据。由于有很高的请求限制,但结果限制较小,我决定独立命中每个类别的终端点,以检索每个类别的最大结果。我还想为位置添加一个参数,以便我可以提取不同城市的数据。最后,我需要一个文件来输出结果,这样我在需要加载数据时就不必每次都请求API。我将以下变量添加到脚本中:
filename = "yelpApi.json";
String[] yelpCategories = {"active","arts","food","hotelstravel","nightlife","pets","restaurants","shopping"};
String location = "New%20York%20City";
最后但同样重要的是,我需要创建JSON对象来格式化并保存结果,然后将其写入JSON文件。
try {
JSONObject json = new JSONObject();
JSONArray jsonArray = new JSONArray();
String jsonData = "";
OkHttpClient client = new OkHttpClient().newBuilder().connectTimeout(20, TimeUnit.SECONDS).build();
for (String category : yelpCategories) {
<API call>
jsonData = response.body().string();
JSONObject obj = new JSONObject(jsonData);
JSONArray array = obj.getJSONArray("businesses");
JSONObject place = new JSONObject();
int n = array.length();
for (int i = 0; i < n; ++i) {
place = array.getJSONObject(i);
if (!place.isEmpty()) {
json.append(category, place);
}
}
}
FileWriter myWriter = new FileWriter(filename);
myWriter.write(json.toString(4));
myWriter.close();
System.out.println("Successfully wrote to Yelp file.");
} catch (IOException e) {
e.printStackTrace();
}
在这之后,我需要几个更多的导入语句。您可能会注意到我在请求中添加了连接超时。这是因为其中一个API的服务器有时会有些慢,我决定用相同的超时保护包装其他API调用,以防止脚本挂起或出现错误。
完整代码的完整版本在GitHub上可以找到。
要运行,我们可以使用`jbang
`加上脚本文件的名称。所以我们的命令将如下:
jbang travelPetDataImport.java
这将运行脚本并将结果输出到我们指定的文件。我们可以检查文件以确保数据被写入得如我们所期望。
我对JBang的功能和简单性感到非常印象深刻和高兴!它提供了一种直接的方式,使用我熟悉的Java语法来编写脚本,而且很容易上手。下次,我希望能够弄清楚IDE 插件,这样我就可以希望利用导入建议和其他可用的效率。
我期待未来更多地使用JBang!
推荐阅读: 百度面经(20)
本文链接: JBang:如何使用Java脚本从API导入数据