16.4.3 检索资源

getForObject() 方法是检索资源的合适选择。我们请求一个资源并按照所选择的 Java 类型接收该资源。作为 getForObject() 能够做什么的一个简单示例,让我们看一下 fetchFacebookProfile() 的另一个实现:

public Profile fetchFacebookProfile(String id) {
  RestTemplate rest = new RestTemplate();
  return rest.getForObject("http://graph.facebook.com/{spitter}",
    Profile.class, id);
}

在程序清单 11.5 中,fetchFacebookProfile() 涉及十多行代码。通过使用 RestTemplate,现在减少到了几行(如果我不是为了适应本书页面的边界,可能会更少)。

fetchFacebookProfile() 首先构建了一个 RestTemplate 的实例(另一种可行的方式是注入实例)。接下来,它调用了 getForObject() 来得到 Facebook 个人信息。为了做到这一点,它要求结果是 Profile 对象。在接收到 Profile 对象后,该方法将其返回给调用者。

注意,在这个新版本的 fetchFacebookProfile() 中,我们没有使用字符串连接来构建 URL,而是利用了 RestTemplate 可以接受参数化 URL 这一功能。URL 中的 {id} 占位符最终将会用方法的 id 参数来填充。getForObject() 方法的最后一个参数是大小可变的参数列表,每个参数都会按出现顺序插入到指定 URL 的占位符中。

另外一种替代方案是将 id 参数放到 Map 中,并以 id 作为 key,然后将这个 Map 作为最后一个参数传递给 getForObject():

public Profile fetchFacebookProfile(String id) {
  Map<String, String> urlVariable = new HashMap<String, String>();
  urlVariable.put("id", id);
  RestTemplate rest = new RestTemplate();
  return rest.getForObject("http://graph.facebook.com/{spitter}",
    Profile.class, urlVariable);
}

这里没有任何形式的 JSON 解析和对象映射。在表面之下,getForObject() 为我们将响应体转换为对象。它实现这些需要依赖表 16.1 中所列的 HTTP 消息转换器,与带有 @ResponseBody 注解的 Spring MVC 处理方法所使用的一样。

这个方法也没有任何异常处理。这不是因为 getForObject() 不能抛出异常,而是因为它抛出的异常都是非检查型的。如果在 getForObject() 中有错误,将抛出非检查型 RestClientException 异常(或者它的一些子类)。如果愿意的话,你可以捕获它 —— 但编译器不会强制你捕获它。

Last updated