用於http請求,且封裝了不一樣http框架,
1.jdk api //默認
2.httpclient //1.鏈接池2.超時
3.okhttp //異步 java
RestTemplate,自己不實現http請求,http請求的底層實現是其餘框架,RestTemplate的核心有兩個
1.更方便http請求
2.且能夠切換不一樣http框架
不一樣http框架,提供的功能不徹底同樣web
步驟
1.獲取模板
2.調用模板的方法spring
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,爲何要切換?
由於有更多的配置項,好比
1.鏈接池
2.超時apache
如何切換?
須要簡單封裝一下,
1.用httpclient的客戶端請求類CloseableHttpClient覆蓋默認的
2.配置鏈接池
3.配置超時json
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框架,流程都是同樣。核心步驟就是這兩個。api
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。mybatis
RestTemplate也是不一樣http框架(jdk api/httpclient/okhttp)的封裝。併發
slf也是對不一樣日誌框架(log4j等)的封裝,叫門面模式。
無論模式名字叫什麼,本質是
1.本身不實現,只是封裝其餘框架
底層實現是框架
2.能夠切換不一樣框架
不一樣框架,提供的功能不徹底同樣
準確的說,模式名字應該叫切換模式,即1.封裝了不一樣框架2.而後,實現了對不一樣框架的切換