这是我参与2022首次更文挑战的第19天,活动详情查看:2022首次更文挑战」
RestTemplate常用于访问HTTP端点的RESTful接口,SpringBoot 中提供简单快速的使用,同时也支持自定义配置相关连接参数。
RestTemplate 是 SpringBoot 提供的用于访问 RESTful 服务的客户端模板工具类,位于 org.springframework.web.client 包中。
1. 引入 RestTemplate
1.1 手动创建
创建一个RestTemplate对象,可以使用创建对象的方法来 new 一个实例对象,但是此种方法下的实例对象并不能交由 Spring 容器管理,此时并不能发挥 Spring 框架的作用。
RestTemplate restTemplate = new RestTemplate()
1.2 注解注入
SpringBoot 中内置了 RestTemlate 类并交由容器管理,因此对于同样交由容器管理的类,其中使用 restTemplate 对象时可以通过注解注入使用。
@Autowried
private RestTemplate restTemplate;
1.3 Could not autowire. No beans of 'RestTemplate' type found
如果直接使用注入的 restTemplate 对象,则会报错以上信息,并且提示 Consider defining a bean of type 'org.springframework.web.client.RestTemplate' in your configuration。
出现此问题的原因是因为RestTemplate没有定义,也就是该对象没有实例化,在使用时到容器中无法找不到这个 bean 对象,此时只需要定义配置类来实现对象加入到容器中。
@Configuration
public class Config {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
}
需要注意的是:
- SpringBoot1.3 版本之前并不需手动配置加入容器,SpringBoot 会自动定义 RestTemplate 并注入到容器
- SpringBoot1.4 版本之后,SpringBoot 不再自定义 RestTemplate 注入,而是定义了一个RestTemplateBuilder,需要使用者进一步定义 RestTemplate
- RestTemplateBuilder 对象的 build() 方法其本质就是使用
new RestTemplate()来创建restTemplate 对象
- RestTemplateBuilder 对象的 build() 方法其本质就是使用
2. 自定义配置 RestTemplate
SpringBoot 中对 RestTemplate 的各项参数有提供默认值,因此我们可以尽量少的配置进行使用,当然也可以根据需要自定义 RestTemplate 的生成配置。
2.1 定义HTTP客户端工厂类
通过客户端工厂类,可以定义 restTemplate 连接中使用的连接池、最大允许的连接数、连接超时时间等属性。
RestTemplate 是 SpringBoot 封装的请求工具类,其底层还是使用了 HttpClient,因此我们对 RestTemplate 的HTTP客户端工厂进行操作时,需要引入 HttpClient 依赖信息。
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
配置HTTP连接池参数
@Bean
public HttpClientConnectionManager poolingConnectionManager() {
// 连接池
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
// 最大连接数
poolingConnectionManager.setMaxTotal(1000);
// 每个主机的并发
poolingConnectionManager.setDefaultMaxPerRoute(100);
// 空闲连接过期时间
poolingConnectionManager.setValidateAfterInactivity(10_000);
}
创建HTTP工厂类
@Bean
public HttpClientBuilder createFactory() {
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setHttpClient(httpClientBuilder().build());
//连接请求超时时间
httpRequestFactory.setConnectionRequestTimeout(3000);
//客户端和服务器建立连接的超时时间
httpRequestFactory.setConnectTimeout(3000);
//读取数据的超时时间
httpRequestFactory.setReadTimeout(120000);
return httpRequestFactory
}
最后,在创建 RestTemplete 对象时传入HTTP工厂类对象
RestTemplate restTemplate=new RestTemplate(httpRequestFactory);
2.2 使用 utf-8 字符集
RestTemplate 中的 StringHttpMessageConverter 转换器默认使用ISO-8859-1字符集,该字符集在转换中文字符时可能会导致乱码,因此可以修改为utf-8字符集。
// 获取restTemplate中的转换器集合
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters();
//遍历转换器集合,找到对应的StringHttpMessageConverter转换器
HttpMessageConverter<?> converterTarget = null;
for (HttpMessageConverter<?> item : converterList) {
if (StringHttpMessageConverter.class == item.getClass()) {
converterTarget = item;
break;
}
}
//如果存在目标转换器,则移除已有的
if (null != converterTarget) {
converterList.remove(converterTarget);
}
//添加新的StringHttpMessageConverter转换器,并设置字符集为UTF-8
converterList.add(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
2.3 使用 fastjson 转换器
Spring 为RestTemplate 提供的json转换器是Jackson,该转换器要求json字符串与待转换的实体类严格对应,为了使用更加方便,可以将json转换器切换为阿里的fastJson。 使用fastjson需要先引入相关的依赖信息
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.54</version>
</dependency>
之后,便可以如切换String消息转换器一样,将原有转换器移除,将fastjson转换器加入。
//移除原有的json转换器
for (HttpMessageConverter<?> item : converterList) {
if(converter instanceof GsonHttpMessageConverter || converter instanceof MappingJackson2HttpMessageConverter){
iterator.remove();
}
}
//加入fastjson转换器
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullListAsEmpty,
SerializerFeature.DisableCircularReferenceDetect);
fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
converterList.add(fastJsonHttpMessageConverter);
最后,返回restTemplate交给Spring容器管理,在使用时注入的对象就是自定义的restTemplate对象。