源码中的方法

  1. 源码中的方法
  2. ### getForObject()方法只返回结果
  3. getForEntity方法返回ResponseEntity封装后的结果,可以从ResponseEntity中获得statusheadersbody
  4. ================================================================================================================================================================
  5. <T> T getForObject(String url, Class<T> responseType, Object... uriVariables) throws RestClientException
  6. <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException
  7. <T> T getForObject(URI url, Class<T> responseType) throws RestClientException
  8. <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables) throws RestClientException
  9. <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException
  10. <T> ResponseEntity<T> getForEntity(URI url, Class<T> responseType) throws RestClientException
  11. ===============================================================================================================================================================
  12. 发送HTTP HEAD请求,返回包含特定资源URLHTTP ,类似于GET, 但是不返回body信息,用于检查对象是否存在,以及得到对象的元数据
  13. ===============================================================================================================================================================
  14. HttpHeaders headForHeaders(String url, Object... uriVariables) throws RestClientException
  15. HttpHeaders headForHeaders(String url, Map<String, ?> uriVariables) throws RestClientException
  16. HttpHeaders headForHeaders(URI url) throws RestClientException
  17. ===============================================================================================================================================================
  18. POST 数据到一个URL,返回新创建资源的URL
  19. ===============================================================================================================================================================
  20. URI postForLocation(String url, @Nullable Object request, Object... uriVariables) throws RestClientException
  21. URI postForLocation(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientException
  22. URI postForLocation(URI url, @Nullable Object request) throws RestClientException throws RestClientException
  23. ===============================================================================================================================================================
  24. ===============================================================================================================================================================
  25. <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException
  26. <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException
  27. <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException
  28. <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables) throws RestClientException
  29. <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables) throws RestClientException
  30. <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType) throws RestClientException
  31. ===============================================================================================================================================================
  32. put用于修改某个内容,若不存在则添加
  33. ===============================================================================================================================================================
  34. void put(String url, @Nullable Object request, Object... uriVariables) throws RestClientException
  35. void put(String url, @Nullable Object request, Map<String, ?> uriVariables) throws RestClientException
  36. void put(URI url, @Nullable Object request) throws RestClientException
  37. 删除某个内容
  38. void delete(String url, Object... uriVariables) throws RestClientException
  39. void delete(String url, Map<String, ?> uriVariables) throws RestClientException
  40. void delete(URI url) throws RestClientException
  41. ===============================================================================================================================================================
  42. ###发送HTTP OPTIONS请求,返回对特定URLAllow头信息,询问可以执行哪些方法
  43. Set<HttpMethod> optionsForAllow(String url, Object... uriVariables) throws RestClientException
  44. Set<HttpMethod> optionsForAllow(String url, Map<String, ?> uriVariables) throws RestClientException
  45. Set<HttpMethod> optionsForAllow(URI url) throws RestClientException
  46. ===============================================================================================================================================================
  47. ###在URL上执行特定的HTTP方法,返回包含对象的ResponseEntity,这个对象是从响应体中映射得到的
  48. 允许调用者指定HTTP请求的方法,可以在请求中增加body以及头信息,其内容通过参数‘HttpEntity<?>requestEntity'描述
  49. <T> ResponseEntity<T> exchange(String url, HttpMethod method, @Nullable HttpEntity<?> requestEntity, Class<T> responseType, Object... uriVariables) throws RestClientException
  50. 两个重载方法同上
  51. ===============================================================================================================================================================
  52. ###在URL上执行特定的HTTP方法,返回一个从响应体映射得到的对象
  53. public <T> T execute(String url, HttpMethod method, @Nullable RequestCallback requestCallback, @Nullable ResponseExtractor<T> responseExtractor, Object... uriVariables) throws RestClientException
  54. 两个重载方法同上,此方法为根方法,上述方法最终执行此方法

SpringBoot注入自定义的RestTemplate

简单配置RestTemplate

  1. private ClientHttpRequestFactory getClientHttpRequestFactory() {
  2. int timeout = 5000;
  3. RequestConfig config = RequestConfig.custom()
  4. .setConnectTimeout(timeout)
  5. .setConnectionRequestTimeout(timeout)
  6. .setSocketTimeout(timeout)
  7. .build();
  8. CloseableHttpClient client = HttpClientBuilder
  9. .create()
  10. .setDefaultRequestConfig(config)
  11. .build();
  12. return new HttpComponentsClientHttpRequestFactory(client);
  13. }
  14. @Bean
  15. public RestTemplate restTemplate(){
  16. RestTemplate restTemplate = new RestTemplate(getClientHttpRequestFactory());
  17. return restTemplate;
  18. }

完整配置

  1. public class HttpClientUtils {
  2. public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
  3. HttpClientBuilder b = HttpClientBuilder.create();
  4. // 设置允许所有证书的信任策略
  5. SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
  6. @Override
  7. public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
  8. return true;
  9. }
  10. }).build();
  11. b.setSSLContext(sslContext);
  12. // 也不要检查主机名,如果不想削弱,请使用SSLConnectionSocketFactory.getDefaultHostnameVerifier()
  13. HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;
  14. //需要创建SSL套接字工厂,以使用我们削弱的“信任策略”;并创建一个注册表来注册它
  15. SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
  16. Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
  17. .register("http", PlainConnectionSocketFactory.getSocketFactory())
  18. .register("https", sslSocketFactory)
  19. .build();
  20. // 用注册表创建了链接管理器,允许多线程使用
  21. PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
  22. connMgr.setMaxTotal(200);// 连接池最大连接数
  23. connMgr.setDefaultMaxPerRoute(100);//每个IP+port,允许的最大连接数
  24. b.setConnectionManager( connMgr);
  25. RequestConfig config = RequestConfig.custom()
  26. .setConnectionRequestTimeout(5000)
  27. .setConnectTimeout(5000)
  28. .setSocketTimeout(5000)//读取超时 当返回response太长时,readtimeout
  29. .build();
  30. b.setDefaultRequestConfig(config);
  31. b.evictIdleConnections(60,TimeUnit.SECONDS);定期回收空闲链接
  32. b.evictExpiredConnections();定期回收过期链接
  33. b.setConnectionReuseStrategy(NoConnectionReuseStrategy.INSTANCE);// 链接重试策略,是否能keepAlive
  34. b.setRetryHandler(new DefaultHttpRequestRetryHandler(0,false));// 重试策略,默认3此,false为禁用
  35. CloseableHttpClient client = b.build();
  36. return client;
  37. }
  38. }
/**
 * 拦截所有的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;
    }
}