使用RestTemplate | 8lovelife's life
0%

使用RestTemplate

记录如何使用Spring中的RestTemplate(with apache.httpcomponents)发起 REST API请求

REQUIREMENTS

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

SETTING UP

HttpConfigProperties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Component
@Data
public class HttpConfigProperties {

private Integer maxTotalConnections = 200;
private Integer maxPerRoute = 100;
/**
* 等待连接建立的超时时间 5秒
*/
private Integer connectTimeout = 5000;

/**
* 等待数据传输的超时时间 15秒
*/
private Integer socketTimeout = 15000;

/**
* 等待请求连接池的超时时间 5秒
*/
private Integer connectionRequestTimeout = 5000;

/**
* 允许连接idle的时间 10秒
*/
private Integer keeAliveTimeMillis = 10000;

/**
* idle最大时间
*/
private Integer closeIdleConnectionWaitTimeSecs = 20;

}

HttpClientPoolingConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
@Configuration
@EnableScheduling
@Slf4j
public class HttpClientPoolingConfig {

@Resource
private HttpConfigProperties properties;

@Bean(name = "poolingConnectionManager")
public PoolingHttpClientConnectionManager poolingConnectionManager() {
try {
LayeredConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(SSLContext.getDefault());
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("https", sslsf)
.register("http", new PlainConnectionSocketFactory())
.build();
PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
poolingConnectionManager.setMaxTotal(properties.getMaxTotalConnections());
poolingConnectionManager.setDefaultMaxPerRoute(properties.getMaxPerRoute());
return poolingConnectionManager;
} catch (Exception e) {
log.error("Pooling Connection Manager Initialisation failure because of " + e.getMessage(), e);
throw new RuntimeException();
}

}

@Bean(name = "connectionKeepAliveStrategy")
public ConnectionKeepAliveStrategy connectionKeepAliveStrategy() {
return (response, context) -> {
HeaderElementIterator it = new BasicHeaderElementIterator
(response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();

if (value != null && param.equalsIgnoreCase("timeout")) {
return Long.parseLong(value) * 1000;
}
}
return properties.getKeeAliveTimeMillis();
};
}

@Bean(name = "httpClient")
public CloseableHttpClient httpClient(@Qualifier(value = "connectionKeepAliveStrategy") ConnectionKeepAliveStrategy connectionKeepAliveStrategy) {
RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(properties.getConnectionRequestTimeout())
.setConnectTimeout(properties.getConnectTimeout())
.setSocketTimeout(properties.getSocketTimeout()).build();

return HttpClients.custom()
.setDefaultRequestConfig(requestConfig)
.setConnectionManager(poolingConnectionManager())
.setKeepAliveStrategy(connectionKeepAliveStrategy)
.build();
}

@Bean
public Runnable idleConnectionMonitor(@Qualifier(value = "poolingConnectionManager") PoolingHttpClientConnectionManager poolingConnectionManager) {
return new Runnable() {
@Override
@Scheduled(fixedDelay = 10000, initialDelay = 1000)
public void run() {
try {
if (poolingConnectionManager != null) {
log.info("run IdleConnectionMonitor - Closing expired and idle connections...");
poolingConnectionManager.closeExpiredConnections();
poolingConnectionManager.closeIdleConnections(properties.getCloseIdleConnectionWaitTimeSecs(), TimeUnit.SECONDS);
} else {
log.info("run IdleConnectionMonitor - Http Client Connection manager is not initialised");
}
} catch (Exception e) {
log.error("run IdleConnectionMonitor - Exception occurred. msg={}, e={}", e.getMessage(), e);
}
}
};
}

}

RestTemplateConfig

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
@Slf4j
public class RestTemplateConfig {

@Bean
public RestTemplate restTemplate(@Qualifier(value = "httpClient") CloseableHttpClient httpClient) {
HttpComponentsClientHttpRequestFactory clientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory);
List<ClientHttpRequestInterceptor> interceptors
= restTemplate.getInterceptors();
if (CollectionUtils.isEmpty(interceptors)) {
interceptors = new ArrayList<>();
}
interceptors.add(new RestTemplateLogInterceptor());
restTemplate.setInterceptors(interceptors);
restTemplate.getMessageConverters().add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
return restTemplate;
}

}

RestTemplateLogInterceptor

1
2
3
4
5
6
7
8
9
10
11
12
@Slf4j
public class RestTemplateLogInterceptor implements ClientHttpRequestInterceptor {

@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
ClientHttpResponse response = execution.execute(request, body);
if (response.getStatusCode() != HttpStatus.OK) {
log.error("RESTful api error, request is {} ,response is {}", request.getURI(), response.getStatusCode());
}
return response;
}
}

DEMO

image

image

image

image

image

I’m just a girl, standing in front of a boy, asking him to love her. - Allie

The Notebook