《Spring in Action》第7章-使用REST服务

使用REST服务

RestTemplate

同JDBCTemplate一样,为了消除大量繁琐的样板代码,RestTemplate提供了很多方法,使得我们能够很方便的调用REST服务。这些方法大致可分为以下12组重载方法:

Method group Description

getForObject

Retrieves a representation via GET.

getForEntity

Retrieves a ResponseEntity (that is, status, headers, and body) by using GET.

headForHeaders

Retrieves all headers for a resource by using HEAD.

postForLocation

Creates a new resource by using POST and returns the Location header from the response.

postForObject

Creates a new resource by using POST and returns the representation from the response.

postForEntity

Creates a new resource by using POST and returns the representation from the response.

put

Creates or updates a resource by using PUT.

patchForObject

Updates a resource by using PATCH and returns the representation from the response. Note that the JDK HttpURLConnection does not support the PATCH, but Apache HttpComponents and others do.

delete

Deletes the resources at the specified URI by using DELETE.

optionsForAllow

Retrieves allowed HTTP methods for a resource by using ALLOW.

exchange

More generalized (and less opinionated) version of the preceding methods that provides extra flexibility when needed. It accepts a RequestEntity (including HTTP method, URL, headers, and body as input) and returns a ResponseEntity.

These methods allow the use of ParameterizedTypeReference instead of Class to specify a response type with generics.

execute

The most generalized way to perform a request, with full control over request preparation and response extraction through callback interfaces.

RestTemplate API

要使用RestTmeplate,我们应该创建它的一个实例,或者是注入该类的bean。

获取资源

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

第一个参数指定接口接口的URL,第二个参数指定返回值绑定的类型,第三个参数被绑定到URL中的{id}占位符。

URL参数我们也可以存放在Map中:

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

URL中的“{id}”占位符被params中key为“id”的值所替换。

使用URI参数相对来说要复杂一点:

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

我们还可以使用getForEntity方法,该方法返回ResponseBody,包含了出domain对象之外更多的信息。

替换资源

我们使用RestTemplate.put()来替换资源。与getForObjectgetForEntity用法几乎一样,只是该方法的第二个参数是替换的实体对象,如:

public Taco put(){
    Taoc taco = new Taco();
	taco.setName("tacoOne");
	...
    restTemplate.put("http://localhost:8080/rest/design/{id}",taco,12);//将id为12的记录替换为taco
    return taco;
}

删除资源

public void delete(String id){
	restTemplate.delete("http://localhost:8080/rest/design/",id);
}

delete方法只需要两个入参:URL和URL参数。

新建资源

如果我们想要得到创建之后的对象,我们可以使用:postForObject

public Taco create(Taco){
	return taco = restTemplate.postForObject("http://localhost:8080/rest/design",taco,Taco.class);
}

第二个参数为新增资源对象,第三个参数指定响应体的绑定的类型。

如果我们想要得到新增资源的地址,我们可以使用postForLocation

public URI create(Taco taco){
	return restTemplate.postForLocation("http://localhost:8080/rest/design",taco);
}

返回的URI源于响应体的Location Header。

如果两者都想要则使用postForEntity

public Taco create(Taco taco){
	ResponseEntity<Taco> entity = restTemplate.postForEntity("http://localhost:8080/rest/design",taco,Taco.class);
	URI uri = entity.getHeader().getLocation();
	return entity.getBody();
}

上面的例子使用的资源全都不含有超链接,若我们所使用的API返回的资源中含有链接,那么RestTemplate就发挥不了作用了。

使用Tranverson访问REST API

Tranverson同Spring Data HATEOAS协同工作,是使用Spring应用中hypermedia API的解决方案。

首先同RestTemplate一样,我们首选需要一个Tranverson实例,可以实例化一个或者注入Tranversonbean;

Tranverson tranverson = new Tranverson(URI.create("http://localhost:8080/api"),MediaTypes.HAL_JSON);

实例化一个Traverson对象,并指定Spring Data REST API的根路径为起始路径;同时指定我们使用的接口将返回JSON格式的数据,数据包含HAL风格的链接,这样Traverson才能正确解析响应结果。

我们请求API根目录的到的返回结果如下:
《Spring in Action》第7章-使用REST服务_第1张图片

访问接口

所以我们可以使用与链接对应的关系名称来访问接口:

tranverson.follow("ingredients");//请求http://localhost:8080/api/ingredients
tranverson.follow("tacos","recent");//请求http://localhost:8080/api/tacos/recent

获取响应结果

ParameterizedTypeReference<CollectionModel<Taco>> tacos = new ParameterizedTypeReference<CollectionModel<Taco>>() {};
CollectionModel<Taco> tacos = traverson.follow("tacos").toObject(tacos);

toObject方法的入参类型为ParameterizedTypeReference>,表示Traverson将会读入CollectionModel类型的数据。

因为Traverson发起的所有请求都是HTTP GET类型的,所以我们无法使用Traverson来新增、更新和删除资源。因此,一般情况下我们可能会结合Traverson和RestTemplate一起使用。

String ingredientsUrl = traverson.follow("ingredients").asLink().getHref();
restTemplate.postForObject(ingredientsUrl,ingredient,Ingredient.class);

asLink将会返回资源本身的链接(_links下的self)

《Spring in Action》第7章-使用REST服务_第2张图片

你可能感兴趣的:(spring)