作者:admin,发布日期:2020-06-07
阅读:1325;评论:0

Snipaste_2020-06-07_21-23-38.png

什么是RestTemplate

从 3.0 版本开始,Spring 提供了 RestTemplate 作为用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。

简单的说,RestTemplate对日常常用的HTTP请求代码进行了封装,代码编写者可以直接通过这个类去请求互联网的上的http接口,来实现数据的交互或者另外一些操作。RestTemplate能大幅简化了提交表单数据的难度,并且附带了自动转换JSON数据的功能。

如何去使用RestTemplate

该类内部定义了多个方法,包含了常用的HTTP请求方式,并且封装了请求头和请求部分以及返回的内容,这里我们将逐一讲解。

首先我们会讲解一下方法内的参数的生成。

查看该类,我们可以发现此类实现了RestOperations接口,于是我们开始翻看RestOperations接口的源码。

public class RestTemplate extends InterceptingHttpAccessor implements RestOperations

可以发现其内部包含了我们常用的请求类型封装的方法,包括GET,PUT,DELETE,POST等。

public interface RestOperations

我们可以看到内部方法的参数有好多相同,那我们就来逐一解释这些参数应该怎么填写。

url

指代请求的网址,我们可以直接传入字符串类型,或者传入URL类。

responseType

查看源码,可以得知这是一个泛型的参数,代表了返回的body的数据类型,系统会自动将返回的数据映射到该类型的对象上。

Object... uriVariables

可变长的一个参数列表,指代URL后面的参数。

Map<String, ?> uriVariables

和上面一个相同,只不过传入的是一个Map,K是String,V为未知类型。

@Nullable Object request

需要请求的参数

HttpMethod method

指定请求的方式

@Nullable RequestCallback requestCallback

指定请求返回数据的处理对象

@Nullable ResponseExtractor<T> responseExtractor

指定请求的执行对象


了解参数的使用方式之后,我们来查看方法。

GET请求

<T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException;

<T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;

<T> T getForObject(URI url, Class<T> responseType) throws RestClientException;

<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
		throws RestClientException;

<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
		throws RestClientException;

<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException;

GET请求一共有6个方法,指代的不同的请求方式,getForObject直接返回处理好的对象,对象类型由responseType指定,而ResponseEntity则会返回一个ResponseEntity<T>,其中的T代表返回处理后对象的类型。与上一个方法不同的使用,ResponseEntity对返回的内容进行了封装,我们可以得到HTTP返回码和其他的内容。

HEAD请求

HttpHeaders headForHeaders(String url, Object... uriVariables) throws RestClientException;

HttpHeaders headForHeaders(String url, Map<String, ?> uriVariables) throws RestClientException;

HttpHeaders headForHeaders(URI url) throws RestClientException;

与上面GET请求基本上一致,只不过按照HTTP标准,HEAD请求只会请求首部。

POST请求

URI postForLocation(String url, @Nullable Object request, Object... uriVariables) throws RestClientException;

URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables)
		throws RestClientException;

URI postForLocation(URI url, @Nullable Object request) throws RestClientException;

<T> T postForObject(String url, @Nullable Object request, Class<T> responseType,
		Object... uriVariables) throws RestClientException;

<T> T postForObject(String url, @Nullable Object request, Class<T> responseType,
		Map<String, ?> uriVariables) throws RestClientException;

<T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException;

<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType,
		Object... uriVariables) throws RestClientException;

<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType,
		Map<String, ?> uriVariables) throws RestClientException;

<T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType)
		throws RestClientException;

与上面请求不同的是,POST可以携带参数,我们可以给request传入自己的对象,或者String用于传递JSON或者其他,或者Map,都是可以的。

PUT请求

void put(String url, @Nullable Object request, Object... uriVariables) throws RestClientException;

void put(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientException;

void put(URI url, @Nullable Object request) throws RestClientException;

PEACH请求

<T> T patchForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables)
		throws RestClientException;

<T> T patchForObject(String url, @Nullable Object request, Class<T> responseType,
		Map<String, ?> uriVariables) throws RestClientException;

<T> T patchForObject(URI url, @Nullable Object request, Class<T> responseType)
		throws RestClientException;

DELETE请求

void delete(String url, Object... uriVariables) throws RestClientException;

void delete(String url, Map<String, ?> uriVariables) throws RestClientException;

void delete(URI url) throws RestClientException;

SET请求

Set<HttpMethod> optionsForAllow(String url, Object... uriVariables) throws RestClientException;

Set<HttpMethod> optionsForAllow(String url, Map<String, ?> uriVariables) throws RestClientException;

Set<HttpMethod> optionsForAllow(URI url) throws RestClientException;

SET请求会返回HttpMethod对象,代表返回的HTTP代码。

exchange

<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
		Class<T> responseType, Object... uriVariables) throws RestClientException;

<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
		Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException;

<T> ResponseEntity<T> exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
		Class<T> responseType) throws RestClientException;

<T> ResponseEntity<T> exchange(String url,HttpMethod method, @Nullable HttpEntity<?> requestEntity,
		ParameterizedTypeReference<T> responseType, Object... uriVariables) throws RestClientException;

<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
		ParameterizedTypeReference<T> responseType, Map<String, ?> uriVariables) throws RestClientException;

<T> ResponseEntity<T> exchange(URI url, HttpMethod method, @Nullable HttpEntity<?> requestEntity,
		ParameterizedTypeReference<T> responseType) throws RestClientException;

<T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, Class<T> responseType)
		throws RestClientException;

<T> ResponseEntity<T> exchange(RequestEntity<?> requestEntity, ParameterizedTypeReference<T> responseType)
		throws RestClientException;

// General execution
<T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
		@Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables)
		throws RestClientException;

<T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback,
		@Nullable ResponseExtractor<T> responseExtractor, Map<String, ?> uriVariables)
		throws RestClientException;

<T> T execute(URI url, HttpMethod method, @Nullable RequestCallback requestCallback,
		@Nullable ResponseExtractor<T> responseExtractor) throws RestClientException;

与之前请求方法不同的是,这是上述请求方法的底层代码,上述的操作最终会执行exchange方法,进行请求,我们可以直接使用上面这些方法,来为请求设置请求头和POST的参数,以及返回对象的类型。

下面是requestEntity的构建方法

headers = new HttpHeaders();
headers.set("Authorization", String.format("token %s", token));

HttpEntity<String> requestEntity = new HttpEntity<>(null, headers);

该类构造方法的第一个参数是请求的body,第二个参数是请求头。泛型参数为请求参数的类型,我们可以使用自己的类,让其内部进行序列化,或者传入Map来实现。

使用示例代码

headers = new HttpHeaders();
headers.set("Authorization", String.format("token %s", token));

HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(null, headers);
ResponseEntity<String> result = restTemplate.exchange("https://api.github.com/user", HttpMethod.GET, requestEntity, String.class);

这段代码构建了一个HttpHeaders,然后把其传入构造函数中,构造出HttpEntity,最后使用exchange,发送请求,获取到ResponseEntity。

然后我们就可以使用

result.getBody()

来获得请求返回的内容,可以直接对其解析JSON或者其他操作。

当然,我们可以构建自己的类,这样就不用解析JSON,该类会自动对其解析序列化。

我们只需要将

ResponseEntity<String>

中的String改成自己的类名,同时将上述exchange最后一个参数改成自己的类名.class,那么getBody()返回的类型就会变成我们自己的类。


我们再来看一段代码,这里使用了上面的get方法去请求

        HttpHeaders headers = new HttpHeaders();
        headers.set("Accept", "application/json");

        Map<String, String> map = new HashMap<>();
        map.put("client_id", clientId);
        map.put("client_secret", clientSecret);
        map.put("code", code);

        HttpEntity<Map<String, String>> entity = new HttpEntity<>(map, headers);

        ResponseEntity<String> responseEntity = restTemplate.postForEntity("https://github.com/login/oauth/access_token", entity, String.class);

可以看到postForEntity的第二个参数可以直接传入HttpEntity,当然直接传入数据也是没有问题的,但是上述方法可以设置请求的头。

写在结尾

以上就是我们对RestTemplate能够发送的请求的一个详细介绍,有问题欢迎留言讨论。当然,看完这篇文章后建议学习一下常用的HTTP请求方式,这样才能更好的理解上面的代码。

评论区

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。