源码中的方法
源码中的方法### getForObject()方法只返回结果 getForEntity方法返回ResponseEntity封装后的结果,可以从ResponseEntity中获得status,headers,body================================================================================================================================================================<T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException<T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException<T> T getForObject(URI url, Class<T> responseType) throws RestClientException<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException<T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException<T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException===============================================================================================================================================================发送HTTP HEAD请求,返回包含特定资源URL的HTTP头 ,类似于GET, 但是不返回body信息,用于检查对象是否存在,以及得到对象的元数据===============================================================================================================================================================HttpHeaders headForHeaders(String url, Object... uriVariables) throws RestClientExceptionHttpHeaders headForHeaders(String url, Map<String, ?> uriVariables) throws RestClientExceptionHttpHeaders headForHeaders(URI url) throws RestClientException ===============================================================================================================================================================POST 数据到一个URL,返回新创建资源的URL===============================================================================================================================================================URI postForLocation(String url, @Nullable Object request, Object... uriVariables) throws RestClientExceptionURI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientExceptionURI postForLocation(URI url, @Nullable Object request) throws RestClientException throws RestClientException==============================================================================================================================================================================================================================================================================================================================<T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException<T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException<T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException<T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException<T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException===============================================================================================================================================================put用于修改某个内容,若不存在则添加===============================================================================================================================================================void put(String url, @Nullable Object request, Object... uriVariables) throws RestClientExceptionvoid put(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientExceptionvoid put(URI url, @Nullable Object request) throws RestClientException删除某个内容void delete(String url, Object... uriVariables) throws RestClientExceptionvoid delete(String url, Map<String, ?> uriVariables) throws RestClientExceptionvoid delete(URI url) throws RestClientException===============================================================================================================================================================###发送HTTP OPTIONS请求,返回对特定URL的Allow头信息,询问可以执行哪些方法Set<HttpMethod> optionsForAllow(String url, Object... uriVariables) throws RestClientExceptionSet<HttpMethod> optionsForAllow(String url, Map<String, ?> uriVariables) throws RestClientExceptionSet<HttpMethod> optionsForAllow(URI url) throws RestClientException===============================================================================================================================================================###在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的 允许调用者指定HTTP请求的方法,可以在请求中增加body以及头信息,其内容通过参数‘HttpEntity<?>requestEntity'描述<T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException两个重载方法同上===============================================================================================================================================================###在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException两个重载方法同上,此方法为根方法,上述方法最终执行此方法
SpringBoot注入自定义的RestTemplate
简单配置RestTemplate
private ClientHttpRequestFactory getClientHttpRequestFactory() { int timeout = 5000; RequestConfig config = RequestConfig.custom() .setConnectTimeout(timeout) .setConnectionRequestTimeout(timeout) .setSocketTimeout(timeout) .build(); CloseableHttpClient client = HttpClientBuilder .create() .setDefaultRequestConfig(config) .build(); return new HttpComponentsClientHttpRequestFactory(client);}@Beanpublic RestTemplate restTemplate(){ RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory()); return restTemplate;}
完整配置
public class HttpClientUtils { public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { HttpClientBuilder b = HttpClientBuilder.create(); // 设置允许所有证书的信任策略 SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { @Override public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { return true; } }).build(); b.setSSLContext(sslContext); // 也不要检查主机名,如果不想削弱,请使用SSLConnectionSocketFactory.getDefaultHostnameVerifier() HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; //需要创建SSL套接字工厂,以使用我们削弱的“信任策略”;并创建一个注册表来注册它 SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create() .register("http", PlainConnectionSocketFactory.getSocketFactory()) .register("https", sslSocketFactory) .build(); // 用注册表创建了链接管理器,允许多线程使用 PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry); connMgr.setMaxTotal(200);// 连接池最大连接数 connMgr.setDefaultMaxPerRoute(100);//每个IP+port,允许的最大连接数 b.setConnectionManager( connMgr); RequestConfig config = RequestConfig.custom() .setConnectionRequestTimeout(5000) .setConnectTimeout(5000) .setSocketTimeout(5000)//读取超时 当返回response太长时,readtimeout .build(); b.setDefaultRequestConfig(config); b.evictIdleConnections(60,TimeUnit.SECONDS);定期回收空闲链接 b.evictExpiredConnections();定期回收过期链接 b.setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE);// 链接重试策略,是否能keepAlive b.setRetryHandler(new DefaultHttpRequestRetryHandler(0,false));// 重试策略,默认3此,false为禁用 CloseableHttpClient client = b.build(); return client; }}
/**
* 拦截所有的restTemplate请求:
*/
public class RestClientInterceptor implements ClientHttpRequestInterceptor {
private static final String HEAD_TOKEN="Token";
private static final String HEAD_TRACE_ID="trace_id";
private static final String HEAD_SPAN_ID="span_id";
private SecurityAuthenticator identityAuthenticator = AuthenticatorFactory.getAuthenticator();
private static final Logger logger = LoggerFactory.getLogger(RestClientInterceptor.class);
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] body, ClientHttpRequestExecution execution) throws IOException {
RequestHolder.setRequest(httpRequest);
HttpHeaders httpHeaders = httpRequest.getHeaders();
//没有Token,增加Token参数
if(!httpHeaders.containsKey(HEAD_TOKEN)){
httpHeaders.add(HEAD_TOKEN, identityAuthenticator.getIdentityToken(null));
}
//如果没有设置contentType,则设置默认为application/json,也可添加Accept为application/json
MediaType contentType = httpHeaders.getContentType();
if(contentType == null){
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
}
// 以下为链路追踪设置
TraceContext tc = TraceLocalUtil.getTraceContext();
if(tc==null){
//记录是否为当前调用链的发起方
RequestHolder.setStartFlag(true);
TraceRecordGenerator.traceStart();
}
URI uri = httpRequest.getURI();
HttpMethod httpMethod = httpRequest.getMethod();
TraceRecordGenerator.clientSend("call->" + httpMethod.name() + ":" + uri.toString());
tc = TraceLocalUtil.getTraceContext();
if (tc != null) {
httpHeaders.set(HEAD_TRACE_ID, tc.getTraceId());
httpHeaders.set(HEAD_SPAN_ID,tc.getSpanId());
}
final ClientHttpResponse response;
try {
response = execution.execute(httpRequest, body);
}catch (Exception e){
TraceRecordGenerator.clientReceiveFailed(e.getMessage(), ServicePropertyUtil.getErrorcodeProfix()+DefaultErrorCode.ERROR.getCode());
Boolean startFlag = RequestHolder.getStartFlag();
if(startFlag != null && startFlag){
TraceRecordGenerator.traceEnd();
}
RequestHolder.clear();
throw e;
}
return response;
}
}
public class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {
public CustomMappingJackson2HttpMessageConverter() {
List<MediaType> mediaTypes = new ArrayList<>();
mediaTypes.add(MediaType.ALL);
setSupportedMediaTypes(mediaTypes);
}
}
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate httpsRestTemplate(ClientHttpRequestFactory httpsFactory) {
RestTemplate restTemplate = new RestTemplate(httpsFactory);
// 添加自定义的转换器,也可重新设置StringHttpMessageConverter字符集为UTF-8,解决中文乱码问题(默认使用的字符集是ISO-8859-1,先移除再添加)
restTemplate.getMessageConverters().add(new CustomMappingJackson2HttpMessageConverter());
restTemplate.setErrorHandler(new ErrorResponseHandler());//自定义的错误处理,继承DefaultResponseErrorHandler
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
interceptors.add(new RestClientInterceptor());//自定义拦截器,继承于ClientHttpRequestInterceptor
restTemplate.setInterceptors(interceptors);
return restTemplate;
}
@Bean(name = "httpsFactory")
public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory() throws Exception {
CloseableHttpClient httpClient = HttpClientUtils.acceptsUntrustedCertsHttpClient();
HttpComponentsClientHttpRequestFactory httpsFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return httpsFactory;
}
}