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.用Jackson和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中的大部分操作都来自ObjectMapper。ObjectMapper最常见的情况是给它一个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上获得。