role
JDK API // default. Httpclient //1. Connection pool 2. timeout 3.okhttp // async
RestTemplate, which itself does not implement HTTP requests. The underlying implementation of HTTP requests is another framework. The core of RestTemplate has two 1’s. Facilitate HTTP requests 2. You can switch between different HTTP frameworks. Different HTTP frameworks provide different functions
Application layer – Use
Step 1 Obtain the template. 2. Invoke methods of the template
List<AuditResult> auditResultList = null; / / response data try {auditResultList = HttpClientUtil. GetTemplate () postForObject (url, audits / / into the parameters according to the type of the general's map/list, List.class // The data type of the response data); } catch (Throwable e) { log.error(msg +"Call to risk control system timeout!" + e.getMessage());
return;
}
Copy the code
Switch the default JDK API to HttpClient
The default is the JDK API, why switch? Because there are more configuration items, such as 1. Connection pool 2. Timeout
How to switch? 1. Override the default 2 with the httpClient client request class CloseableHttpClient. Configure connection pool 3. Configure timeout
package xxx.util; import java.util.ArrayList; import java.util.List; import org.apache.http.client.config.RequestConfig; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.client.RestTemplate; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; Public class HttpClientUtil {private static int POOLSIZE = 150; / / the connection pool private static PoolingHttpClientConnectionManager connMgr = null; Private final static int SOCKETTIMEOUT = 1000; Private final static int CONNECTIONREQUESTTIMEOUT = 3000; private final static int CONNECTIONREQUESTTIMEOUT = 3000; Private final static int CONNECTTIMEOUT = 2000; private final static int CONNECTTIMEOUT = 2000; // Connection timeout public static RestTemplategetTemplate() { CloseableHttpClient httpClient = getConnection(); RestTemplate template = new RestTemplate( new HttpComponentsClientHttpRequestFactory(httpClient)); // Override the default List<HttpMessageConverter<? >> converters = new ArrayList<HttpMessageConverter<? > > (); / / using data conversion of fastjson FastJsonHttpMessageConverter fastjson = new FastJsonHttpMessageConverter (); fastjson.setFeatures(SerializerFeature.WriteClassName, SerializerFeature.BrowserCompatible, SerializerFeature.DisableCircularReferenceDetect); converters.add(fastjson); template.setMessageConverters(converters);return template;
}
private static CloseableHttpClient getConnection() {
if(connMgr == null) {// Create a link pool. Connection pool can be concurrent requests 100 connections connMgr = new PoolingHttpClientConnectionManager (); connMgr.setMaxTotal(POOLSIZE + 1); connMgr.setDefaultMaxPerRoute(POOLSIZE); } RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT) .setConnectTimeout(CONNECTTIMEOUT) .setSocketTimeout(SOCKETTIMEOUT).build(); CloseableHttpClient httpClient = httpclient.custom ().setConnectionManager(connMgr) // Configure connection pooling .setDefaultRequestConfig(requestConfig).build();returnhttpClient; }}Copy the code
The source code
The process is 1. Obtain client 2. Request server
Regardless of the HTTP framework, the flow is the same. These are the two core steps.
public class RestTemplate extends InterceptingHttpAccessor implements RestOperations {
protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCallback, ResponseExtractor<T> responseExtractor) throws RestClientException {
Assert.notNull(url, "'url' must not be null");
Assert.notNull(method, "'method' must not be null"); ClientHttpResponse response = null; Object var7; try { ClientHttpRequest request = this.createRequest(url, method); // Get the HTTP request clientif(requestCallback ! = null) { requestCallback.doWithRequest(request); } response = request.execute(); // Request serverif(! this.getErrorHandler().hasError(response)) { this.logResponseStatus(method, url, response); }else {
this.handleResponseError(method, url, response);
}
if (responseExtractor == null) {
var7 = null;
return var7;
}
var7 = responseExtractor.extractData(response);
} catch (IOException var11) {
throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + url + "\":" + var11.getMessage(), var11);
} finally {
if (response != null) {
response.close();
}
}
return var7;
}
Copy the code
Due to the switch to the HTTP framework, the client class is now CloseableHttpClient(the client class of the HttpClient framework). CloseableHttpClient: CloseableHttpClient: CloseableHttpClient: CloseableHttpClient: CloseableHttpClient When the underlying requests the server, the switched client is used
Design patterns
JdbcTemplate(Mybatis/Hibernate); RedisTemplate (RedisTemplate);
RestTemplate is also a wrapper around different HTTP frameworks (JDK API/httpClient/OKHTTP).
SLF is also a wrapper around different logging frameworks (Log4j, etc.) called facade patterns.
Whatever the schema is called, the essence is 1. It does not implement itself, but encapsulates other frameworks. The underlying implementation is Framework 2. You can switch between different frameworks and different frameworks provide different functions
To be precise, the mode name should be switch mode, i.e. 1. Encapsulate different frameworks 2. Then, the switch between different frameworks is implemented