16.4 编写 REST 客户端

作为客户端,编写与 REST 资源交互的代码可能会比较乏味,并且所编写的代码都是样板式的。例如,假设我们需要借助 Facebook 的 Graph API,编写方法来获取某人的 Facebook 基本信息。不过,获取基本信息的代码会有点复杂,如下面的程序清单所示。

程序清单 16.6 使用 Apache HTTP Client 获取 Facebook 中的个人基本信息
public Profile fetchFacebookProfile(String id) {
try {
HttpClient client = HttpClients.createDefault();
HttpGet request = new HttpGet("http://graph.facebook.com/" + id);
request.setHeader("Accept", "application/json");
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
ObjectMapper mapper = new ObjectMapper();
return mapper.readValue(entity.getContent(), Profile.class);
} catch (IOException e) {
throw new RuntimeException(e);
}
}

你可以看到,在使用 REST 资源的时候涉及很多代码。这里我甚至还偷懒使用了 Jakarta Commons HTTP Client 发起请求并使用 Jackson JSON processor 解析响应。

仔细看一下 fetchFacebookProfile() 方法,你可能会发现方法中只有少量代码与获取 Facebook 个人信息直接相关。如果你要编写另一个方法来使用其他的 REST 资源,很可能会有很多代码是与 fetchFacebookProfile() 相同的。

另外,还有一些地方可能会抛出的 IOException 异常。因为 IOException 是检查型异常,所以要么捕获它,要么抛出它。在本示例中,我选择捕获它并在它的位置重新抛出一个非检查型异常 RuntimeException。

鉴于在资源使用上有如此之多的样板代码,你可能会觉得最好的方式是封装通用代码并参数化可变的部分。这正是 Spring 的 RestTemplate 所做的事情。就像 JdbcTemplate 处理了 JDBC 数据访问时的丑陋部分,RestTemplate 让我们在使用 RESTful 资源时免于编写那些乏味的代码。

稍后,我们将会看到如何借助 RestTemplate 重写 fetchFacebookProfile() 方法,这会戏剧性的简化该方法并消除掉样板式代码。但首先,让我们整体了解一下 RestTemplate 提供的所有 REST 操作。