Spring Cloud入门教程(番外篇一):RestTempl
2017-08-03 本文已影响3343人
CD826
RestTemplate是Spring提供的用于访问Rest服务的客户端,RestTemplate提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
1. 使用GET
1.1 获取JSON字符串
我们可以使用getForEntity()
方法:
RestTemplate restTemplate = new RestTemplate();
String fooResourceUrl = "http://localhost:8080/spring-rest/foos";
ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "/1", String.class);
assertThat(response.getStatusCode(), equalTo(HttpStatus.OK));
需要说明的是,通过getForEntity()
我们可以获取到完整的HTTP response
,因此我们可以通过检测状态码来判断请求是否真正执行成功。我们也可以通过getBody()
方法获取返回的具体内容,如:
ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(response.getBody());
JsonNode name = root.path("name");
assertThat(name.asText(), notNullValue());
1.2 获取POJO对象
我们也可以直接将请求直接映射为一个POJO对象,如:
public class User implements Serializable {
private long id;
private String name;
// 这里省略了getters和setters
}
获取User
对象:
User user = restTemplate.getForObject(userResourceUrl + "/1", User.class);
assertThat(user.getName(), notNullValue());
assertThat(user.getId(), is(1L));
2. 获取Headers
代码如下:
HttpHeaders httpHeaders = restTemplate.headForHeaders(fooResourceUrl);
assertTrue(httpHeaders.getContentType().includes(MediaType.APPLICATION_JSON));
3. 使用POST
RestTemplate
提供了三个API用来创建资源,它们分别是postForLocation()
、 postForObject()
和postForEntity()
。postForLocation()
返回新创建资源的URI,postForObject()
则返回新创建的资源本身。
3.1 postForObject
方法
ClientHttpRequestFactory requestFactory = getClientHttpRequestFactory();
RestTemplate restTemplate = new RestTemplate(requestFactory);
HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));
Foo foo = restTemplate.postForObject(fooResourceUrl, request, Foo.class);
assertThat(foo, notNullValue());
assertThat(foo.getName(), is("bar"));
3.2 postForLocation
方法
HttpEntity<Foo> request = new HttpEntity<>(new Foo("bar"));
URI location = restTemplate.postForLocation(fooResourceUrl, request);
assertThat(location, notNullValue());
3.3 exchange
方法
RestTemplate
还提供了一个更加通用的方法:exchange
,下面我们来看看如何使用该方法完成一个POST
请求::
RestTemplate restTemplate = new RestTemplate();
HttpEntity<User> request = new HttpEntity<>(new User("CD826"));
ResponseEntity<User> response = restTemplate.exchange(userResourceUrl, HttpMethod.POST, request, User.class);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
User user = response.getBody();
assertThat(user, notNullValue());
assertThat(user.getName(), is("CD826"));
4. 获取允许执行操作列表
optionsForAllow
方法可以让我们获取给定URI中允许执行的操作列表:
Set<HttpMethod> optionsForAllow = restTemplate.optionsForAllow(fooResourceUrl);
HttpMethod[] supportedMethods = {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE};
assertTrue(optionsForAllow.containsAll(Arrays.asList(supportedMethods)));
5. 使用PUT
5.1 简单的PUT
我们先看一个简单的PUT
示例,这里需要注意的时该请求并不会有任何返回:
User updatedInstance = new User("newName");
updatedInstance.setId(createResponse.getBody().getId());
String resourceUrl = userResourceUrl + '/' + createResponse.getBody().getId();
HttpEntity<User> requestUpdate = new HttpEntity<>(updatedInstance, headers);
template.exchange(resourceUrl, HttpMethod.PUT, requestUpdate, Void.class);
5.2 带回调的PUT
我们先定义一个回调函数:
RequestCallback requestCallback(final User updatedInstance) {
return clientHttpRequest -> {
ObjectMapper mapper = new ObjectMapper();
mapper.writeValue(clientHttpRequest.getBody(), updatedInstance);
clientHttpRequest.getHeaders().add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
clientHttpRequest.getHeaders().add(HttpHeaders.AUTHORIZATION, "Basic " + getBase64EncodedLogPass());
};
}
然后,通过POST
先创建需要更新的资源:
ResponseEntity<User> response = restTemplate.exchange(userResourceUrl, HttpMethod.POST, request, User.class);
assertThat(response.getStatusCode(), is(HttpStatus.CREATED));
最后,我们使用PUT
进行更新:
User updatedInstance = new User("newName");
updatedInstance.setId(response.getBody().getId());
String resourceUrl = userResourceUrl + '/' + response.getBody().getId();
restTemplate.execute(resourceUrl, HttpMethod.PUT,
requestCallback(updatedInstance),
clientHttpResponse -> null);
6. 使用DELETE
示例如下:
String entityUrl = fooResourceUrl + "/" + existingResource.getId();
restTemplate.delete(entityUrl);