当前位置:Java -> JBang:如何使用Java脚本从API导入数据

JBang:如何使用Java脚本从API导入数据

正值繁忙的会议季,我正在为即将到来的会议演讲做准备。

像往常一样,我去Neo4j Aura,启动一个免费的数据库,并使用APOC中的Cypher来从API导入数据,但是这个API需要一个头部,而在Aura中,用于添加请求头的APOC过程被安全性限制了。嗯,我需要新的途径。

我决定尝试JBang,这是一个用Java进行脚本编写的工具。我早就听说过它,但还没有尝试过。它很酷,所以我想分享一下我上手的过程。

JBang是什么?

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的插件,包括IntelliJIntelliJ插件似乎具有几个不错的特性,包括导入建议。但是,我在尝试从现有项目或随机创建的脚本中使用它时遇到了麻烦,我必须创建一个使用JBang初始化的单独项目。也许我需要稍微调整一下,因为它可能会简化导入问题(稍后会讨论)。无论如何,我决定稍后再处理插件,现在暂时只使用命令行。

API详情

我想导入关于宠物旅行的数据,我知道我想要使用的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();


现在,我稍微调整了上面的代码,使用locationcategoryyelpApiKey的占位变量,这样我以后可以传入任意值。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导入数据