用于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.而后,实现了对不一样框架的切换