源码中的方法
源码中的方法
### 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 RestClientException
HttpHeaders headForHeaders(String url, Map<String, ?> uriVariables) throws RestClientException
HttpHeaders headForHeaders(URI url) throws RestClientException
===============================================================================================================================================================
POST 数据到一个URL,返回新创建资源的URL
===============================================================================================================================================================
URI postForLocation(String url, @Nullable Object request, Object... uriVariables) throws RestClientException
URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientException
URI 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 RestClientException
void put(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientException
void put(URI url, @Nullable Object request) throws RestClientException
删除某个内容
void delete(String url, Object... uriVariables) throws RestClientException
void delete(String url, Map<String, ?> uriVariables) throws RestClientException
void delete(URI url) throws RestClientException
===============================================================================================================================================================
###发送HTTP OPTIONS请求,返回对特定URL的Allow头信息,询问可以执行哪些方法
Set<HttpMethod> optionsForAllow(String url, Object... uriVariables) throws RestClientException
Set<HttpMethod> optionsForAllow(String url, Map<String, ?> uriVariables) throws RestClientException
Set<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);
}
@Bean
public 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;
}
}