Restful接口配置自定义的RestTemplete

RestTemplete默认不是支持所有的contentType,需要自己配置RestTemplete,添加自定的请求转换器,获取对应的contentType的数据并进行转换。

import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Configuration
public class RestTemplateConfig {
    @Bean
    public RestTemplate httpsRestTemplate(ClientHttpRequestFactory httpsFactory) {
        RestTemplate restTemplate = new RestTemplate(httpsFactory);
        // 添加自定义的转换器
        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);
        httpsFactory.setReadTimeout(40000);
        httpsFactory.setConnectTimeout(40000);
        return httpsFactory;
    }
}

自定义的消息转换器

import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * http消息转换器
 *  支持所有消息转换
 * </p>
 */
public class CustomMappingJackson2HttpMessageConverter extends MappingJackson2HttpMessageConverter {

    public CustomMappingJackson2HttpMessageConverter() {
        List<MediaType> mediaTypes = new ArrayList<>();
        mediaTypes.add(MediaType.ALL);
        setSupportedMediaTypes(mediaTypes);
    }
}

RestTemplete支持https接口配置工具类

import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class HttpClientUtils {

    public static CloseableHttpClient acceptsUntrustedCertsHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        HttpClientBuilder b = HttpClientBuilder.create();

        // setup a Trust Strategy that allows all certificates.
        //
        SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
                return true;
            }
        }).build();
        b.setSSLContext(sslContext);

        // don't check Hostnames, either.
        //      -- use SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
        HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE;

        // here's the special part:
        //      -- need to create an SSL Socket Factory, to use our weakened "trust strategy";
        //      -- and create a Registry, to register it.
        //
        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
        Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("http", PlainConnectionSocketFactory.getSocketFactory())
                .register("https", sslSocketFactory)
                .build();

        // now, we create connection-manager using our Registry.
        //      -- allows multi-threaded use
        PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
        connMgr.setMaxTotal(200);
        connMgr.setDefaultMaxPerRoute(100);
        b.setConnectionManager( connMgr);

        // finally, build the HttpClient;
        //      -- done!
        CloseableHttpClient client = b.build();

        return client;
    }

}

配置的RestTemplete拦截器,添加默认的hearder,拦截统一添加token

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import java.io.IOException;
import java.net.URI;
/**
 * 拦截所有的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
        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;
    }
}

部分代码不方便给出,需要自行理解修改。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值