RestTemplate是由Spring框架提供的一个可用于应用中调用rest服务的类它简化了与http服务的通信方式。
统一了RESTFul的标准,封装了http连接,只需要传入url及其返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更为优雅的调用RESTFul服务的方式。RestTemplate类的设计原则与许多其他Spring的模板类(例如JdbcTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
RestTemplate
RestOperations
:定义了RestTemplate对GET、POST、PUT、DELETE、OPTIONS方法的封装和适配,还有通用的exchange、execute方法。
HttpAccessor
:定义了ClientHttpRequestFactory
对象的get、set方法。
InterceptingHttpAccessor
:定义了一个接口ClientHttpRequestInterceptor
,用于做请求拦截。
RestTemplate源码
构造方法
public RestTemplate() {
this.messageConverters.add(new ByteArrayHttpMessageConverter());
this.messageConverters.add(new StringHttpMessageConverter());
this.messageConverters.add(new ResourceHttpMessageConverter(false));
if (!shouldIgnoreXml) {
try {
this.messageConverters.add(new SourceHttpMessageConverter<>());
}
catch (Error err) {
// Ignore when no TransformerFactory implementation is available
}
}
this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
if (romePresent) {
this.messageConverters.add(new AtomFeedHttpMessageConverter());
this.messageConverters.add(new RssChannelHttpMessageConverter());
}
if (!shouldIgnoreXml) {
if (jackson2XmlPresent) {
this.messageConverters.add(new MappingJackson2XmlHttpMessageConverter());
}
else if (jaxb2Present) {
this.messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
}
}
if (jackson2Present) {
this.messageConverters.add(new MappingJackson2HttpMessageConverter());
}
else if (gsonPresent) {
this.messageConverters.add(new GsonHttpMessageConverter());
}
else if (jsonbPresent) {
this.messageConverters.add(new JsonbHttpMessageConverter());
}
else if (kotlinSerializationJsonPresent) {
this.messageConverters.add(new KotlinSerializationJsonHttpMessageConverter());
}
if (jackson2SmilePresent) {
this.messageConverters.add(new MappingJackson2SmileHttpMessageConverter());
}
if (jackson2CborPresent) {
this.messageConverters.add(new MappingJackson2CborHttpMessageConverter());
}
this.uriTemplateHandler = initUriTemplateHandler();
}
public RestTemplate(ClientHttpRequestFactory requestFactory) {
this();
setRequestFactory(requestFactory);
}
public RestTemplate(List<HttpMessageConverter<?>> messageConverters) {
validateConverters(messageConverters);
this.messageConverters.addAll(messageConverters);
this.uriTemplateHandler = initUriTemplateHandler();
}
RestTemplate的构造过程:
1.添加了多个HttpMessageConverter
后续用于http请求响应的数据转换
2.初始化Uri模板的处理器,用于处理uri相关的东西
3.HttpAccessor
默认创建了一个ClientHttpRequestFactory
的成员实例(SimpleClientHttpRequestFactory,默认使用HttpURLConnection),用于创建请求对象。
RestTemplate类中常用的请求方法
官方支持:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
Get请求相关源码
@Override
@Nullable
public <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
@Override
@Nullable
public <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables);
}
@Override
@Nullable
public <T> T getForObject(URI url, Class<T> responseType) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
HttpMessageConverterExtractor<T> responseExtractor =
new HttpMessageConverterExtractor<>(responseType, getMessageConverters(), logger);
return execute(url, HttpMethod.GET, requestCallback, responseExtractor);
}
@Override
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables)
throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
return nonNull(execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));
}
@Override
public <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables)
throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
return nonNull(execute(url, HttpMethod.GET, requestCallback, responseExtractor, uriVariables));
}
@Override
public <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException {
RequestCallback requestCallback = acceptHeaderRequestCallback(responseType);
ResponseExtractor<ResponseEntity<T>> responseExtractor = responseEntityExtractor(responseType);
return nonNull(execute(url, HttpMethod.GET, requestCallback, responseExtractor));
}
getForObject
:返回值直接是响应体内容转为的 JSON 对象
getForEntity
:返回值的封装包含有响应头, 响应状态码的 ResponseEntity
对象
参数说明:
url
:请求路径
requestEntity
:HttpEntity对象,封装了请求头和请求体
responseType
:返回数据类型
uriVariables
:支持PathVariable类型的数据。
RestTemplate的核心组件
HttpMessageConverter:转换http请求响应过程中的消息数据
用于在 HTTP 请求和响应之间进行转换的策略接口。
需要对web接口的输入输出需要做自定义扩展或格式化时,都会考虑通过实现自定义的HttpMessageConverter来实现。
public interface HttpMessageConverter<T> {
//指示此转换器是否可以读取给定的类。
boolean canRead(Class<?> clazz, @Nullable MediaType mediaType);
//指示此转换器是否可以编写给定的类。
boolean canWrite(Class<?> clazz, @Nullable MediaType mediaType);
//返回此转换器支持的媒体类型列表。
List<MediaType> getSupportedMediaTypes();
//返回此转换器支持的给定类的媒体类型列表。
default List<MediaType> getSupportedMediaTypes(Class<?> clazz) {
return (canRead(clazz, null) || canWrite(clazz, null) ?
getSupportedMediaTypes() : Collections.emptyList());
}
//从给定的输入消息中读取给定类型的对象,并返回它。
T read(Class<? extends T> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException;
//将给定对象写入给定的输出消息。
void write(T t, @Nullable MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException;
}
1.AbstractJackson2HttpMessageConverter:Jackson 转换器
具体实现类:
MappingJackson2CborHttpMessageConverter
:读取和写入CBOR 数据格式。
MappingJackson2HttpMessageConverter
:ObjectMapper读写 JSON。
MappingJackson2SmileHttpMessageConverter
:读取和写入 Smile 数据格式(“二进制 JSON”)。
MappingJackson2XmlHttpMessageConverter
:读取和写入 XML 编码数据。
2.AbstractJsonHttpMessageConverter:JSON 转换器
具体实现类:
GsonHttpMessageConverter
:使用Google Gson 库读写 JSON。
JsonbHttpMessageConverter
:使用JSON Binding API 读写 JSON。
3.AbstractXmlHttpMessageConverter:XML 转换器
具体实现类:
Jaxb2CollectionHttpMessageConverter
:读取包含使用XmlRootElement和XmlType注释的类的集合。请注意,此转换器不支持写入。Jaxb2RootElementHttpMessageConverter
:读取使用XmlRootElement和XmlType注释的类,并编写使用XmlRootElement注释的类或其子类。MarshallingHttpMessageConverter
:读取使用XmlRootElement和XmlType注释的类,并编写使用XmlRootElement注释的类或其子类。
4.AbstractWireFeedHttpMessageConverter:Atom 和 RSS Feed 消息转换器
具体实现类:
AtomFeedHttpMessageConverter
:可以读写 Atom 提要。具体来说,这个转换器可以处理来自ROME 项目的Feed对象。RssChannelHttpMessageConverter
:可以读写 RSS 提要。具体来说,这个转换器可以处理来自ROME 项目的Channel对象。
ClientHttpRequestFactory:用于根据URI和HttpMethod创建出一个ClientHttpRequest来发送请求
源码很简单,一个工厂接口,定义了生成ClientHttpRequest的方法。
public interface ClientHttpRequestFactory {
ClientHttpRequest createRequest(URI uri, HttpMethod httpMethod) throws IOException;
}
具体实现类:
SimpleClientHttpRequestFactory
:使用标准 JDK 工具创建请求。(默认)
HttpComponentsClientHttpRequestFactory
:使用HttpClient 创建请求。
OkHttp3ClientHttpRequestFactory
:使用OkHttp 3.x 创建请求。
BufferingClientHttpRequestFactory
:在内存中缓冲所有传出和传入流。使用此包装器允许多次读取响应正文。
InterceptingClientHttpRequestFactory
:支持ClientHttpRequestInterceptors的包装器。
SimpleClientHttpRequestFactory为什么是默认?
HttpAccessor
抽象类源码
public abstract class HttpAccessor {
protected final Log logger = HttpLogging.forLogName(getClass());
private ClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
private final List<ClientHttpRequestInitializer> clientHttpRequestInitializers = new ArrayList<>();
public void setRequestFactory(ClientHttpRequestFactory requestFactory) {
Assert.notNull(requestFactory, "ClientHttpRequestFactory must not be null");
this.requestFactory = requestFactory;
}
public ClientHttpRequestFactory getRequestFactory() {
return this.requestFactory;
}
public void setClientHttpRequestInitializers(
List<ClientHttpRequestInitializer> clientHttpRequestInitializers) {
if (this.clientHttpRequestInitializers != clientHttpRequestInitializers) {
this.clientHttpRequestInitializers.clear();
this.clientHttpRequestInitializers.addAll(clientHttpRequestInitializers);
AnnotationAwareOrderComparator.sort(this.clientHttpRequestInitializers);
}
}
public List<ClientHttpRequestInitializer> getClientHttpRequestInitializers() {
return this.clientHttpRequestInitializers;
}
protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
ClientHttpRequest request = getRequestFactory().createRequest(url, method);
initialize(request);
if (logger.isDebugEnabled()) {
logger.debug("HTTP " + method.name() + " " + url);
}
return request;
}
private void initialize(ClientHttpRequest request) {
this.clientHttpRequestInitializers.forEach(initializer -> initializer.initialize(request));
}
}
UriTemplateHandler:组装uri的模板处理器
默认实现类是DefaultUriBuilderFactory
public class DefaultUriBuilderFactory implements UriBuilderFactory
public interface UriBuilderFactory extends UriTemplateHandler
RequestCallback:回调接口
@FunctionalInterface
public interface RequestCallback {
/**
* 通过打开的ClientHttpRequest由RestTemplate.execute调用。
* 不需要关心关闭请求或处理错误:这都将由RestTemplate处理。
*/
void doWithRequest(ClientHttpRequest request) throws IOException;
}
ResponseErrorHandler:用于确定特定响应是否有错误的策略接口。
public interface ResponseErrorHandler {
/**
* 指示给定的响应是否有任何错误。
* 实现通?;峒觳橄煊Φ腍ttpStatus 。
*/
boolean hasError(ClientHttpResponse response) throws IOException;
/**
* 处理给定响应中的错误。
* 仅当hasError(ClientHttpResponse)返回true时才调用此方法。
*/
void handleError(ClientHttpResponse response) throws IOException;
/**
* 替代handleError(ClientHttpResponse)提供对请求 URL 和 HTTP 方法的访问的额外信息
*/
default void handleError(URI url, HttpMethod method, ClientHttpResponse response) throws IOException {
handleError(response);
}
}
ResponseExtractor:提取返回数据,但无需担心异常处理或关闭资源。
@FunctionalInterface
public interface ResponseExtractor<T> {
/**
* 从给定的ClientHttpResponse中提取数据并返回。
*/
@Nullable
T extractData(ClientHttpResponse response) throws IOException;
}
RestTemplate请求示例
GET请求例子
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
//三种方式请求
String url = "https://restapi.amap.com/v3/weather/weatherInfo?city=110101&key=3ff9482454cb60bcb73f65c8c48d4209](https://restapi.amap.com/v3/weather/weatherInfo?city=110101&key=3ff9482454cb60bcb73f65c8c48d4209)";
String result = restTemplate.getForObject(url, String.class);
System.out.println(result);
}
POST请求例子
public static void main(String[] args) {
RestTemplate restTemplate = new RestTemplate();
//三种方式请求
String url = "https://restapi.amap.com/v3/weather/weatherInfo?city=110101&key=3ff9482454cb60bcb73f65c8c48d4209](https://restapi.amap.com/v3/weather/weatherInfo?city=110101&key=3ff9482454cb60bcb73f65c8c48d4209)";
Map<String,Object> params=new HashMap<>();
ResponseEntity<String> result = restTemplate.postForEntity(url,params, String.class);
System.out.println(result.getStatusCode().getReasonPhrase());
System.out.println(result.getStatusCodeValue());
System.out.println(result.getBody());
}
RestTemplate相关博客推荐
源码分析:https://blog.csdn.net/zhawengan/article/details/121042628
所有请求用法分析:https://blog.csdn.net/weixin_38987366/article/details/109701339
上传文件:https://blog.csdn.net/weixin_39614177/article/details/113542058
下载文件:https://zzzgd.blog.csdn.net/article/details/88915818
相关博客专栏:https://blog.csdn.net/hanxiaotongtong/category_11999208.html