作用

用于http申请,且封装了不同http框架,
1.jdk api //默认
2.httpclient //1.连接池2.超时
3.okhttp //异步

RestTemplate,自身不实现http申请,http申请的底层实现是其余框架,RestTemplate的外围有两个
1.更不便http申请
2.且能够切换不同http框架
不同http框架,提供的性能不齐全一样

应用层-应用

步骤
1.获取模板
2.调用模板的办法

List<AuditResult> auditResultList = null; //响应数据try {   auditResultList = HttpClientUtil.getTemplate().postForObject(url,         audits //入参数据的类型个别是map/list, List.class //响应数据的数据类型);} catch (Throwable e) {   log.error(msg + " 调用风控系统超时!" + e.getMessage());   return;}

切换默认jdk api为httpclient

默认是jdk api,为什么要切换?
因为有更多的配置项,比方
1.连接池
2.超时


如何切换?
须要简略封装一下,
1.用httpclient的客户端申请类CloseableHttpClient笼罩默认的
2.配置连接池
3.配置超时

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;// 连接池   private static PoolingHttpClientConnectionManager connMgr = null;//超时配置项   private final static int SOCKETTIMEOUT = 1000;// 读取响应超时工夫   private final static int CONNECTIONREQUESTTIMEOUT = 3000; // 从连接池获取连贯超时工夫   private final static int CONNECTTIMEOUT = 2000;// 连贯超时工夫   public static RestTemplate getTemplate() {      CloseableHttpClient httpClient = getConnection();      RestTemplate template = new RestTemplate(            new HttpComponentsClientHttpRequestFactory(httpClient)); //用httpclient的客户端申请类CloseableHttpClient笼罩默认的      List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();      // 采纳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) {         // 创立链接池。连接池能够并发申请100个连贯         connMgr = new PoolingHttpClientConnectionManager();         connMgr.setMaxTotal(POOLSIZE + 1);         connMgr.setDefaultMaxPerRoute(POOLSIZE);      }      RequestConfig requestConfig = RequestConfig.custom()            .setConnectionRequestTimeout(CONNECTIONREQUESTTIMEOUT)            .setConnectTimeout(CONNECTTIMEOUT)            .setSocketTimeout(SOCKETTIMEOUT).build(); //配置超时      CloseableHttpClient httpClient = HttpClients.custom()            .setConnectionManager(connMgr) //配置连接池            .setDefaultRequestConfig(requestConfig).build();      return httpClient;   }}

源码

流程是
1.获取客户端
2.申请服务器

不论是哪一种http框架,流程都是一样。外围步骤就是这两个。

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); //获取http申请客户端        if (requestCallback != null) {            requestCallback.doWithRequest(request);        }        response = request.execute(); //申请服务器        if (!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;}

因为切换了http框架,客户端类当初是CloseableHttpClient(httpclient框架的客户端类)。其实就是两个步骤,
1.封装的时候,用httpclient的客户端申请类CloseableHttpClient笼罩默认的
2.底层申请服务器的时候,就应用切换之后的客户端

设计模式

看名字是模板模式,spring里还有其余的相似名字,JdbcTemplate(mybatis/hibernate等dao框架)、RedisTemplate。

RestTemplate也是不同http框架(jdk api/httpclient/okhttp)的封装。

slf也是对不同日志框架(log4j等)的封装,叫门面模式。

不论模式名字叫什么,实质是
1.本人不实现,只是封装其余框架
底层实现是框架
2.能够切换不同框架
不同框架,提供的性能不齐全一样

精确的说,模式名字应该叫切换模式,即
1.封装了不同框架
2.而后,实现了对不同框架的切换