目录
(1)使用 Apache HttpClient 作为 RestTemplate 的底层实现
(2) 使用 OkHttp 作为 RestTemplate 的底层实现
(3)HttpComponentsClientHttpRequestFactory和OkHttp3ClientHttpRequestFactory
1、RestTemplete介绍
RestTemplate 是 Spring 框架中的一个工具类,它用于简化客户端与HTTP服务之间的通信。RestTemplate 封装了底层的HTTP连接细节,为开发者提供了高级别的抽象,使得调用 RESTful服务(RESTful到底是什么?)变得简单和直观。
RestTemplate 提供了多种方法来执行HTTP请求,如GET、POST、PUT、DELETE等,这些方法允许你指定请求的URL、HTTP方法、请求头、请求体(如果适用的话)以及响应的预期类型(如String、ResponseEntity、自定义的Java对象等)。RestTemplate 会处理HTTP请求的发送和响应的接收,并将响应体自动转换为指定的类型,如果配置了相应的消息转换器(MessageConverters)。
由于RestTemplate是Spring框架的一部分,因此它与其他Spring组件(如Spring MVC、Spring Data等)紧密集成,可以轻松地与Spring应用程序中的其他部分一起使用。此外,RestTemplate 还支持异步请求和拦截器等功能,为开发者提供了更强大的HTTP通信能力。
Spring Framework 中的 RestTemplate 默认使用 HttpURLConnection 作为其底层 HTTP 客户端实现。
2、RestTemplate底层实现切换方法
尽管 RestTemplate 默认使用 HttpURLConnection,但它也允许开发者替换为其他 HTTP 客户端实现,例如 Apache HttpClient 或 OkHttp。这可以通过配置不同的 ClientHttpRequestFactory 来实现。
(1)使用 Apache HttpClient 作为 RestTemplate 的底层实现
要使用 Apache HttpClient 作为 RestTemplate 的底层实现,可以按照以下步骤进行配置:
1、添加 Apache HttpClient 依赖(如果尚未添加)
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
2、配置 RestTemplate 使用 Apache HttpClient:
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
// RestTemplate 配置类,用于自定义和配置 RestTemplate 实例
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate restTemplate() {
// 使用HttpClients的createDefault方法创建一个默认的CloseableHttpClient实例
// 这个HttpClient实例可以使用Apache HttpClient的默认配置,也可以根据需要进行自定义配置
CloseableHttpClient httpClient = HttpClients.createDefault();
// 使用上面创建的HttpClient实例来初始化HttpComponentsClientHttpRequestFactory
// 这个工厂负责将RestTemplate的请求转换为HttpClient的请求,并处理响应
HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
// 使用自定义的请求工厂来创建RestTemplate实例
return new RestTemplate(factory);
}
}
(2) 使用 OkHttp 作为 RestTemplate 的底层实现
1、添加 OkHttp 依赖(如果尚未添加)
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.2</version>
</dependency>
2、配置 RestTemplate 使用 OkHttp:
import okhttp3.OkHttpClient;
import org.springframework.http.client.OkHttp3ClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
// 返回一个配置好的RestTemplate对象,该对象将使用OkHttpClient作为底层的HTTP客户端来执行HTTP请求
@Bean
public RestTemplate restTemplate() {
// 创建一个OkHttpClient实例,它是OkHttp的HTTP客户端,用于执行HTTP请求
OkHttpClient okHttpClient = new OkHttpClient();
// 使用OkHttpClient实例来初始化OkHttp3ClientHttpRequestFactory
// OkHttp3ClientHttpRequestFactory是Spring对OkHttpClient的封装,它实现了ClientHttpRequestFactory接口,这个工厂负责将RestTemplate的请求转换为OkHttpClient的请求,并处理响应
OkHttp3ClientHttpRequestFactory factory = new OkHttp3ClientHttpRequestFactory(okHttpClient);
// 使用自定义的请求工厂来创建RestTemplate实例
return new RestTemplate(factory);
}
}
所以:RestTemplate 支持至少三种HTTP客户端库。
SimpleClientHttpRequestFactory:对应的HTTP库是java JDK自带的HttpURLConnection。
HttpComponentsAsyncClientHttpRequestFactory:对应的HTTP库是Apache HttpComponents。
OkHttp3ClientHttpRequestFactory:对应的HTTP库是OkHttp
1、java JDK自带的HttpURLConnection是默认的底层HTTP实现客户端
2、SimpleClientHttpRequestFactory,即java JDK自带的HttpURLConnection不支持HTTP协议的Patch方法,如果希望使用Patch方法,需要将底层HTTP客户端实现切换为Apache HttpComponents 或 OkHttp
3、可以通过设置setRequestFactory方法,来切换RestTemplate的底层HTTP客户端实现类库。
(3)HttpComponentsClientHttpRequestFactory和OkHttp3ClientHttpRequestFactory
HttpComponentsClientHttpRequestFactory和OkHttp3ClientHttpRequestFactory是由Spring提供的,但它们的功能依赖于相应的HTTP客户端库(Apache HttpClient和OkHttp)。
下面是详细说明:
一、HttpComponentsClientHttpRequestFactory:
HttpComponentsClientHttpRequestFactory是Spring提供的一个工厂类,用于将Apache HttpClient集成到RestTemplate中。
依赖关系
- HttpComponentsClientHttpRequestFactory:由Spring Web模块提供,位于org.springframework.http.client包中。
- Apache HttpClient:由Apache提供的HTTP客户端库,HttpComponentsClientHttpRequestFactory使用它来执行实际的HTTP请求。
二、OkHttp3ClientHttpRequestFactory:
OkHttp3ClientHttpRequestFactory是Spring提供的一个工厂类,用于将OkHttp集成到RestTemplate中。
依赖关系
- OkHttp3ClientHttpRequestFactory:由Spring Web模块提供,位于org.springframework.http.client包中。
- OkHttp:由Square提供的HTTP客户端库,OkHttp3ClientHttpRequestFactory使用它来执行实际的HTTP请求。
3、使用RestTemplete的原因
既然可以直接使用 OkHttp 和 Apache HttpClient 等第三方Http客户端库,那为什么还要用resttemplete?
RestTemplate提供了一些高级功能和简化的API,使得它在许多情况下更具优势。
以下是一些主要原因:
(1)简化的API:RestTemplate提供了一个高级的、易于使用的API,用于处理常见的HTTP操作,如GET、POST、PUT、DELETE等。它封装了很多底层细节,使代码更简洁
使用RestTemplate发送GET请求
// 使用RestTemplate发送GET请求
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject("http://example.com", String.class);
System.out.println(result);
相比之下,直接使用Apache HttpClient或OkHttp需要更多的代码来处理相同的操作:
// 使用Apache HttpClient发送GET请求
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet request = new HttpGet("http://example.com");
try (CloseableHttpResponse response = httpClient.execute(request)) {
HttpEntity entity = response.getEntity();
if (entity != null) {
String result = EntityUtils.toString(entity);
System.out.println(result);
}
} catch (IOException e) {
e.printStackTrace();
}
// 使用OkHttp发送GET请求
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://example.com").build();
try (Response response = client.newCall(request).execute()) {
if (response.body() != null) {
String result = response.body().string();
System.out.println(result);
}
} catch (IOException e) {
e.printStackTrace();
}
(2)序列化和反序列化:RestTemplate提供了自动的对象序列化和反序列化功能。可以轻松地将JSON或XML响应映射到Java对象
使用RestTemplate可以自动将JSON响应映射到Java对象
// 自动将JSON响应映射到Java对象
RestTemplate restTemplate = new RestTemplate();
User user = restTemplate.getForObject("http://example.com/user/1", User.class);
直接使用HttpClient或OkHttp时,你需要手动处理这些序列化和反序列化工作
// 使用OkHttp并手动处理JSON响应
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://example.com/user/1").build();
try (Response response = client.newCall(request).execute()) {
if (response.body() != null) {
ObjectMapper mapper = new ObjectMapper();
User user = mapper.readValue(response.body().string(), User.class);
}
} catch (IOException e) {
e.printStackTrace();
}
(3)异常处理:RestTemplate提供了一组内置的异常处理机制,可以更方便地处理HTTP错误代码和其他异常情况
使用RestTemplate时处理异常
try {
User user = restTemplate.getForObject("http://example.com/user/1", User.class);
} catch (HttpClientErrorException e) {
System.out.println("HTTP Error: " + e.getStatusCode());
} catch (ResourceAccessException e) {
System.out.println("Connection error: " + e.getMessage());
}
使用HttpClient或OkHttp时,异常处理需要更多的手动工作
// 使用OkHttp并手动处理异常
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url("http://example.com/user/1").build();
try (Response response = client.newCall(request).execute()) {
if (!response.isSuccessful()) {
throw new IOException("HTTP error: " + response.code());
}
// 处理响应
} catch (IOException e) {
e.printStackTrace();
}
(4) 拦截器和过滤器:RestTemplate支持使用拦截器,可以在请求和响应之间添加额外的逻辑,例如日志记录、认证等
ClientHttpRequestInterceptor interceptor = (request, body, execution) -> {
// 处理请求前逻辑
ClientHttpResponse response = execution.execute(request, body);
// 处理响应后逻辑
return response;
};
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add(interceptor);
虽然OkHttp和HttpClient也支持拦截器,但Spring提供的这种方式更加集成化和统一。
推荐:
【Spring】Spring AOP底层原理:JDK动态代理和CGLIB动态代理_spring cglib和jdk动态代理-CSDN博客https://blog.csdn.net/m0_65277261/article/details/139243897?spm=1001.2014.3001.5501【Spring】Spring AOP底层原理前置知识:代理模式中的静态代理-CSDN博客
https://blog.csdn.net/m0_65277261/article/details/139106845?spm=1001.2014.3001.5501【Spring】AOP中的核心概念:通知(Advice)和切点(Pointcut)_aop advice-CSDN博客
https://blog.csdn.net/m0_65277261/article/details/138890487?spm=1001.2014.3001.5501