Reading JSON From a URL in Java – 在Java中从一个URL中读取JSON

最后修改: 2022年 8月 19日

1. Introduction

1.绪论

In this quick tutorial, we’re going to create methods able to read JSON data from any URL. We’ll start with core Java classes. Then, we’ll use a few libraries to make our code simpler.

在这个快速教程中,我们将创建能够从任何URL读取JSON数据的方法。我们将从核心Java类开始。然后,我们将使用一些库来使我们的代码更简单。

2. Using Core Java Classes

2.使用核心Java类

One of the simplest ways to read data from a URL in Java is using the URL class. To use it, we open an input stream to a URL, create an input stream reader, then read all characters. We’ll append these characters to a StringBuilder and then return it as a String:

在Java中从URL中读取数据的最简单方法之一是使用URL类。为了使用它,我们打开一个URL的输入流,创建一个输入流阅读器,然后读取所有字符。我们将把这些字符追加到一个StringBuilder中,然后以String的形式返回。

public static String stream(URL url) {
    try (InputStream input = url.openStream()) {
        InputStreamReader isr = new InputStreamReader(input);
        BufferedReader reader = new BufferedReader(isr);
        StringBuilder json = new StringBuilder();
        int c;
        while ((c = reader.read()) != -1) {
            json.append((char) c);
        }
        return json.toString();
    }
}

Consequently, the code includes a lot of boilerplate. Moreover, it would also require even more code if we wanted to convert our JSON into a map or a POJO. Even using the new Java 11 HttpClient, it’s a lot of code for a simple GET request. Also, it doesn’t help with converting the response from strings to POJO. So, let’s explore simpler ways to do this.

因此,代码中包含了大量的模板。此外,如果我们想将我们的JSON转换为地图或POJO,它还需要更多的代码。即使使用新的Java 11 HttpClient,对于一个简单的GET请求来说也是大量的代码。而且,它对将响应从字符串转换为POJO没有帮助。因此,让我们探索更简单的方法来完成这个任务。

3. Using commons-io and org.json

3.使用commons-io和org.json

A very popular library is Apache Commons IO. We’ll use IOUtils to read a URL and get a String back. Then, to convert it to a JSONObject, we’ll use the JSON-Java (org.json) library. This is a reference implementation for Java from json.org. Let’s combine them in a new method:

一个非常流行的库是Apache Commons IO我们将使用IOUtils来读取一个URL并获得一个String。然后,为了将其转换为JSONObject,我们将使用JSON-Java(org.json)库。这是一个来自json.org的Java参考实现。让我们在一个新的方法中结合它们。

public static JSONObject getJson(URL url) {
    String json = IOUtils.toString(url, Charset.forName("UTF-8"));
    return new JSONObject(json);
}

With JSONObject, we can call get() for any properties and get an Object. There are similarly named methods for specific types. For example:

通过JSONObject,我们可以为任何属性调用get()并获得一个Object。对于特定的类型也有类似的命名方法。比如说。

jsonObject.getString("stringProperty");

4. Less Code With Jackson and the ObjectMapper

4.用杰克逊和ObjectMapper减少代码

There are many solutions for converting JSON into POJO and vice-versa. But, Jackson is widely used in projects like Jersey and other JAX-RS implementations. Let’s add the dependency we need to our pom.xml:

有许多解决方案可以将JSON转换为POJO,反之亦然。但是,Jackson被广泛用于Jersey和其他JAX-RS实现等项目中。让我们把我们需要的依赖性添加到我们的pom.xml

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.3</version>
</dependency>

With this, not only can we effortlessly read JSON from a URL, but we can also convert it to a POJO at the same time.

有了它,我们不仅可以毫不费力地从一个URL中读取JSON,而且还可以同时将其转换为POJO。

4.1. Deserializing to a Generic Object

4.1.反序列化为一个通用对象

Most of the action in Jackson comes from the ObjectMapper. The most common scenario for ObjectMapper is to give it a String input and get an object back. Luckily, ObjectMapper can also read input straight from an internet URL:

Jackson中的大部分操作都来自ObjectMapperObjectMapper最常见的情况是给它一个String输入并得到一个对象的返回。幸运的是,ObjectMapper也可以直接从互联网的URL中读取输入

public static JsonNode get(URL url) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readTree(url);
}

With readTree(), we get a JsonNode, which is a tree-like structure. We read properties with its get() method:

通过readTree(),我们得到一个JsonNode,它是一个树状结构。我们用它的get()方法读取属性。

json.get("propertyName");

Therefore, we don’t need to map our response to a specific class if we don’t want to.

因此,如果我们不想的话,我们不需要将我们的响应映射到一个特定的类。

4.2. Deserializing to a Custom Class

4.2.反序列化到一个自定义类

But, for more complex objects, it’s helpful to create a class that represents the JSON structure we expect. We can use generics to create a version of our method capable of mapping the response to any class we want with readValue():

但是,对于更复杂的对象,创建一个代表我们期望的JSON结构的类是很有帮助的。我们可以使用generics来创建我们的方法的一个版本,能够将响应映射到我们想要的任何类,并使用readValue()

public static <T> T get(URL url, Class<T> type) {
    ObjectMapper mapper = new ObjectMapper();
    return mapper.readValue(url, type);
}

Then, as long as our object’s properties and structure match, we’ll get a new instance filled with values from the JSON response.

然后,只要我们的对象的属性和结构匹配,我们就会得到一个新的实例,其中充满了来自JSON响应的值。

5. Conclusion

5.总结

In this article, we learned how to make requests to a URL and get a JSON string back. Then, we used a few libraries to simplify our code. In the end, we read a JSON response while mapping it to a POJO in a couple of lines.

在这篇文章中,我们学习了如何向一个URL发出请求并获得一个JSON字符串。然后,我们使用了一些库来简化我们的代码。最后,我们读取了一个JSON响应,同时在几行中把它映射到一个POJO。

And as always, the source code is available over on GitHub.

一如既往,源代码可在GitHub上获得。