7.1.1 请求 GET 资源

假设想从 Taco Cloud API 获取一个 Ingredient 数据。假设 API 没有启用 HATEOAS,需要使用 getForObject() 来获取 Ingredient。例如,下面的代码使用 RestTemplate 获取一个 Ingredient 对象的 ID:

public Ingredient getIngredientById(String ingredientId) {
    return rest.getForObject("http://localhost:8080/ingredients/{id}",
                             Ingredient.class, ingredientId);
}

这里使用的是 getForObject() 变量,它接受一个字符串 URL 并为 URL 变量使用一个变量列表。传递给 getForObject() 的 ingredientId 参数用于填充给定 URL 中的 {id} 占位符。虽然在本例中只有一个 URL 变量,但重要的是要知道变量参数是按给定的顺序分配给占位符的。

getForObject() 的第二个参数是响应应该绑定的类型。在这种情况下,应该将响应数据(可能是 JSON 格式)反序列化为将要返回的 Ingredient 对象。

或者,可以使用映射来指定 URL 变量:

public Ingredient getIngredientById(String ingredientId) {
    Map<String, String> urlVariables = new HashMap<>();
    urlVariables.put("id", ingredientId);
    return rest.getForObject("http://localhost:8080/ingredient/{id}",
                            Ingredient.class, urlVariables);
}

在这个例子中,ingredientId 的值被映射到 id 键上,当发出请求时,{id} 占位符被键为 id 的映射条目替换。

使用 URI 参数稍微复杂一些,需要在调用 getForObject() 之前构造一个 URI 对象,它类似于其他两中形式:

public Ingredient getIngredientById(String ingredientId) {
    Map<String,String> urlVariables = new HashMap<>();
    urlVariables.put("id", ingredientId);
    URI url = UriComponentsBuilder
        .fromHttpUrl("http://localhost:8080/ingredients/{id}")
        .build(urlVariables);
    return rest.getForObject(url, Ingredient.class);
}

这里的 URI 对象是根据字符串规范定义的,其占位符是根据映射中的条目填充的,这与前面的 getForObject() 形式非常相似。getForObject() 方法是获取资源的一种有效方法。但是,如果客户端需要的不仅仅是有效负载,可能需要考虑使用 getForEntity()。

getForEntity() 的工作方式与 getForObject() 非常相似,但它返回的不是表示响应有效负载的域对象,而是包装该域对象的 ResponseEntity 对象。ResponseEntity 允许访问附加的响应细节,比如响应头。

例如,假设除了 Ingredient 数据之外,还希望检查响应中的 Date 头信息,有了 getForEntity(),事情就简单多了:

public Ingredient getIngredientById(String ingredientId) {
    ResponseEntity<Ingredient> responseEntity =
        rest.getForEntity("http://localhost:8080/ingredients/{id}",
                          Ingredient.class, ingredientId);
    
    log.info("Fetched time: " +
             responseEntity.getHeaders().getDate());
    
    return responseEntity.getBody();
}

getForEntity() 方法使用与 getForObject() 相同的重载参数,因此可以将 URL 变量作为变量列表参数,或者使用 URI 对象调用 getForEntity()。

最后更新于