RestTemplate

背景

学习记录一种请求方式

分析

	逻辑
		简单
	代码量
		少
	维护
		中等
	更新
		Spring5 推荐是WebClient 用于替换RestTemplate
	提供了很多工厂配置类,根据具体需求进行对请求或响应做出处理,且提供了许多的API供使用
	RestTemplateClient
		RestTemplateClient() //构造方法用于初始化配置
			BufferingClientHttpRequestFactory(ClientHttpRequestFactory factory) //缓存工厂,用来获取多次Body内容,RestTemplate如果不配置该工厂则只能获取一次Body内容
			new RestTemplateClientConfig() //自定义的工厂配置类
				继承SimpleClientHttpRequestFactory类,重写prepareConnection方法获取底层链接,将链接封装一层SSLSocket工厂,用来支持HTTPS协议,也可以做其他处理
				实现ClientHttpRequestInterceptor接口 intercept方法 用于拦截请求 (打印日志或者夹带私货)
		rest(请求路径,请求方式,请求头,返回类型,请求体) //调用者调用 可以根据业务逻辑增加参数
		 

代码

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.BufferingClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
import java.net.URI;
import java.util.Collections;

public class RestTemplateClient {

    @Resource
    private RestTemplate restTemplate;
    
    public RestTemplateClient() {
        BufferingClientHttpRequestFactory bufferFactory = new BufferingClientHttpRequestFactory(new RestTemplateClientConfig());
        restTemplate = new RestTemplate(bufferFactory);
        restTemplate.setInterceptors(Collections.singletonList(new RestTemplateClientConfig()));
    }

    public <T> ResponseEntity<T> rest(String path, HttpMethod method, HttpHeaders headers, Class<T> tClass, Object o) {
        if (headers == null) {
            headers = new HttpHeaders();
            headers.put("Accept", Collections.singletonList("*/*"));
            headers.put("Content-Type", Collections.singletonList("application/json;charset=utf-8"));
        }

        RequestEntity<Object> request = new RequestEntity<>(o, headers, method, URI.create(path));
        return rest(path, method, request, tClass);
    }

    public <T> ResponseEntity<T> rest(String uri, HttpMethod method, RequestEntity<?> request, Class<T> c) {
        return restTemplate.exchange(URI.create(uri), method, request, c);
    }
}
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import javax.net.ssl.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

@Slf4j
public class RestTemplateClientConfig extends SimpleClientHttpRequestFactory implements ClientHttpRequestInterceptor {


    @Override
    protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {

        if (connection instanceof HttpsURLConnection) {
            HttpsURLConnection https = (HttpsURLConnection) connection;
            https.setHostnameVerifier((String var1, SSLSession var2)->true);
            try {
                https.setSSLSocketFactory(creatSSLsocketFactory());
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        super.prepareConnection(connection,httpMethod);

    }

    private SSLSocketFactory creatSSLsocketFactory() throws NoSuchAlgorithmException, KeyManagementException {
        SSLContext tls = SSLContext.getInstance("TLS");
        tls.init(null,new TrustManager[]{new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        }},new SecureRandom());
        return tls.getSocketFactory();
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        ClientHttpResponse response = null;
        traceRequest(request, body);

        try {
            response = execution.execute(request, body);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(String.format("RestRemote is Error 产品端拒绝链接,请检查通信是否正常 Uri:[%s]", request.getURI()));
        }

        if (response.getRawStatusCode() != 200) {
            throw new RuntimeException(String.format("RestRemote is Error 请检查路径或根据Code判断错误 Uri:[%s]  Code:[%s]", request.getURI(), response.getStatusCode()));
        }


        traceResponse(response);
        return response;

    }


    private void traceRequest(HttpRequest request, byte[] body) throws IOException {
        log.info("===========================request begin=============================================");
        log.debug("URI         : {}", request.getURI());
        log.debug("Method      : {}", request.getMethod());
        log.debug("Headers     : {}", request.getHeaders());
        log.debug("Request body: {}", new String(body, "UTF-8"));
        log.info("==========================request end================================================");
    }

    private void traceResponse(ClientHttpResponse response) throws IOException {
        StringBuilder inputStringBuilder = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody(), "UTF-8"));
        String line = bufferedReader.readLine();
        while (line != null) {
            inputStringBuilder.append(line);
            inputStringBuilder.append('\n');
            line = bufferedReader.readLine();
        }

        log.info("============================response begin==========================================");
        log.debug("Status code  : {}", response.getStatusCode());
        log.debug("Headers      : {}", response.getHeaders());
        log.debug("Response body: {}", inputStringBuilder.toString());
        log.info("============================response end============================================");
    }
}

API

简单请求

特殊场景的请求

配置相关

Https

编解码

错误处理

日志

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值