HttpClient、OKhttp、RestTemplate接口调用对比,选择一个优秀的 HTTP Client 的重要性

前言:
在Feign中,Client是一个非常重要的组件,Feign最终发送Request请求以及接收Response响应都是由Client组件来完成的。Client在Feign源码中是一个接口,在默认情况下,Client的实现类是Client.Default。Client.Default是由HttpURLConnection来实现网络请求的。另外,Client还支持HttpClient和OkHttp来进行网络请求。

首先查看FeignRibbonClient的自动配置类FeignRibbonClientAutoConfiguration,该类在程序启动的时候注入一些Bean,其中注入了一个BeanName为feignClient的Client类型的Bean。在省缺配置BeanName为FeignClient的Bean的情况下,会自动注入Client.Default这个对象,跟踪Client.Default源码,Client.Default使用的网络请求框架是HttpURLConnection,
源码为Default 类;
使用HttpClient,源码为:HttpClientFeignConfiguration
用OkHttp,源码为:OkHttpFeignConfiguration

选择一个优秀的 HTTP Client 的重要性

连接池
请求/响应编解码(异步、超时设置等)
API丰富程度及扩展性

JAVA 项目中接口调用怎么做 ?

HttpClient
OKhttp
RestTemplate
上面是最常见的几种用法,我们基于目前主流的SpringBoot简单的介绍一下用法及对比。

基于springboot的HttpClient、OKhttp、RestTemplate对比

一般okhttp配置,部分源码分析,参考:
参考分析

一、HttpClient

1、HttpClient 是Apache的一个三方网络框架,网络请求做了完善的封装,api众多,用起来比较方便,开发快。
Util工具类

package org.example;

import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.*;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @desc httpClient工具类
 * @author liangliang
 * @date 2019/3/11 13:23
 */

@Slf4j
public class HttpClientUtil {
    /**
     * httpclient基础配置信息
     */
    private static final RequestConfig requestConfig = RequestConfig.custom()
            // 设置连接超时时间(单位毫秒)
            .setConnectTimeout(2000)
            // 设置请求超时时间(单位毫秒)
            .setConnectionRequestTimeout(2000)
            // socket读写超时时间(单位毫秒)
            .setSocketTimeout(1000)
            // 设置是否允许重定向(默认为true)
            .setRedirectsEnabled(true)
            //是否启用内容压缩,默认true
            .setContentCompressionEnabled(true)
            .build();
    /**
     * 获得Http客户端
     */
    private static final CloseableHttpClient HTTP_CLIENT = HttpClientBuilder.create()
            .setRetryHandler(new DefaultHttpRequestRetryHandler()) //失败重试,默认3次
            .build();

    /**
     * 异步Http客户端
     */
    private static final CloseableHttpAsyncClient HTTP_ASYNC_CLIENT = HttpAsyncClients.custom()
            .setDefaultRequestConfig(requestConfig)
            .build();


    /**
     * @desc 异步请求
     * @param httpRequestBase
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    private static void executeAsync(HttpRequestBase httpRequestBase) {
        HTTP_ASYNC_CLIENT.start();
        HTTP_ASYNC_CLIENT.execute(httpRequestBase, new FutureCallback<HttpResponse>() {
            @SneakyThrows
            @Override
            public void completed(HttpResponse httpResponse) {
                log.info("thread id is : {}" ,Thread.currentThread().getId());

                StringBuffer stringBuffer = new StringBuffer();
                for (Header header : httpRequestBase.getAllHeaders()) {
                    stringBuffer.append(header.toString()).append(",");
                }
                log.info("请求头信息: {}", stringBuffer.toString());


                String responseResult = null;
                HttpEntity responseEntity = httpResponse.getEntity();
                log.info("响应状态为:{}", httpResponse.getStatusLine());
                if (responseEntity != null) {
                    responseResult = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
                    log.info("响应内容为:{}",responseResult);

                }

                stringBuffer = new StringBuffer();
                for (Header header : httpResponse.getAllHeaders()) {
                    stringBuffer.append(header.toString()).append(",");
                }
                log.info("响应头信息: {}", stringBuffer.toString()));


            }

            @Override
            public void failed(Exception e) {
                log.info("thread id is : {}",Thread.currentThread().getId());
                log.error("Exception responseResult:{}", e);
                e.printStackTrace();
            }

            @Override
            public void cancelled() {
                log.info(httpRequestBase.getRequestLine() + " cancelled");
            }
        });
    }

     /**
     * @desc String请求
     * @param httpRequestBase
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    private static String execute(HttpRequestBase httpRequestBase) {
        log.info("请求地址: {},请求类型: {}", httpRequestBase.getURI().toString(,httpRequestBase.getMethod()));

        StringBuffer stringBuffer = new StringBuffer();
        for (Header header : httpRequestBase.getAllHeaders()) {
            stringBuffer.append(header.toString()).append(",");
        }
        log.info("请求头信息: {}", stringBuffer.toString());


        log.info("请求参数: {}", httpRequestBase.getURI().getQuery());

        String responseResult = null;
        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 将上面的配置信息 运用到这个Get请求里
            httpRequestBase.setConfig(requestConfig);
            long t1 = System.nanoTime();//请求发起的时间
            response = HTTP_CLIENT.execute(httpRequestBase);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            log.info("响应状态为:{}",response.getStatusLine());
            long t2 = System.nanoTime();//收到响应的时间
            if (responseEntity != null) {

                responseResult = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);

                log.info("响应内容为:{}",responseResult);

            }

            stringBuffer = new StringBuffer();
            for (Header header : response.getAllHeaders()) {
                stringBuffer.append(header.toString()).append(",");
            }
            log.info("响应头信息: {}", stringBuffer.toString());

            log.info("执行时间: {}", (t2 - t1));

        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
            	log.error("Exception responseResult:{}", e.getMassage());
                e.printStackTrace();
            }

        }
        return responseResult;

    }
    
     /**
     * @desc byte[]请求
     * @param httpRequestBase
     * @return byte[]
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    private static byte[] executeBytes(HttpRequestBase httpRequestBase) {
        log.info("请求地址: {},请求类型: {}", httpRequestBase.getURI().toString(,httpRequestBase.getMethod()));
        StringBuffer stringBuffer = new StringBuffer();
        for (Header header : httpRequestBase.getAllHeaders()) {
            stringBuffer.append(header.toString()).append(",");
        }
        log.info("请求头信息: {}", stringBuffer.toString());


        log.info("请求参数: {}", httpRequestBase.getURI().getQuery());

        byte[] bytes = null;
        // 响应模型
        CloseableHttpResponse response = null;
        try {
            // 将上面的配置信息 运用到这个Get请求里
            httpRequestBase.setConfig(requestConfig);
            long t1 = System.nanoTime();//请求发起的时间
            response = HTTP_CLIENT.execute(httpRequestBase);
            // 从响应模型中获取响应实体
            HttpEntity responseEntity = response.getEntity();
            log.info("响应状态为:{}", response.getStatusLine());
            long t2 = System.nanoTime();//收到响应的时间
            if (responseEntity != null) {
                bytes = EntityUtils.toByteArray(responseEntity);

                //判断是否需要解压,即服务器返回是否经过了gzip压缩--start
                Header responseHeader = response.getFirstHeader("Content-Encoding");
                if (responseHeader != null && responseHeader.getValue().contains("gzip")) {
                    GZIPInputStream gzipInputStream = null;
                    ByteArrayOutputStream out = null;
                    try {
                        gzipInputStream = new GZIPInputStream(new ByteArrayInputStream(bytes));
                        out = new ByteArrayOutputStream();
                        byte[] buffer = new byte[1024];
                        int offset = -1;
                        while ((offset = gzipInputStream.read(buffer)) != -1) {
                            out.write(buffer, 0, offset);
                        }
                        bytes = out.toByteArray();

                    } catch (IOException e) {
                    	log.error("Exception responseResult:{}", e.getMassage());
                        e.printStackTrace();
                    } finally {
                        try {
                            gzipInputStream.close();
                            out.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
                //判断是否需要解压,即服务器返回是否经过了gzip压缩--end

                log.info("响应byte长度:{}", bytes.length);
            }

            stringBuffer = new StringBuffer();
            for (Header header : response.getAllHeaders()) {
                stringBuffer.append(header.toString()).append(",");
            }
            log.info("响应头信息: {}", stringBuffer.toString());

            log.info("执行时间: {}", (t2 - t1));

        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
        return bytes;

    }

     /**
     * @desc get请求
     * @param url
     * @return tring
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String get(String url) {
        return get(url, new HashMap<>());
    }

     /**
     * @desc get请求
     * @param url, params
     * @return tring
     * @author mal
     * @date 2019/3/11 13:23
     */
    public static String get(String url, Map<String, Object> params) {
        HttpGet httpGet = null;
        List<NameValuePair> list = new ArrayList<>();
        for (String key : params.keySet()) {
            list.add(new BasicNameValuePair(key, params.get(key).toString()));
        }

        // 由客户端执行(发送)Get请求
        try {
            URI uri = new URIBuilder(url).addParameters(list).build();
            // 创建Get请求
            httpGet = new HttpGet(uri);

        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }
        return execute(httpGet);
    }

     /**
     * @desc get请求
     * @param url, params
     * @return byte[]
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static byte[] getBytes(String url, Map<String, Object> params) {
        HttpGet httpGet = null;
        List<NameValuePair> list = new ArrayList<>();
        for (String key : params.keySet()) {
            list.add(new BasicNameValuePair(key, params.get(key).toString()));
        }

        // 由客户端执行(发送)Get请求
        try {
            URI uri = new URIBuilder(url).addParameters(list).build();
            // 创建Get请求
            httpGet = new HttpGet(uri);

        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }
        return executeBytes(httpGet);
    }

     /**
     * @desc post请求
     * @param url
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String post(String url) {
        return post(url, new HashMap<>());
    }
     /**
     * @desc post请求
     * @param url, params
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String post(String url, Map<String, Object> params) {
        HttpPost httpPost = null;
        List<NameValuePair> list = new ArrayList<>();
        for (String key : params.keySet()) {
            list.add(new BasicNameValuePair(key, params.get(key).toString()));
        }

        try {
            URI uri = new URIBuilder(url).addParameters(list).build();
            httpPost = new HttpPost(uri);
        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }

        return execute(httpPost);
    }

     /**
     * @desc post请求
     * @param url, params
     * @return byte[]
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static byte[] postBytes(String url, Map<String, Object> params) {
        HttpPost httpPost = null;
        List<NameValuePair> list = new ArrayList<>();
        for (String key : params.keySet()) {
            list.add(new BasicNameValuePair(key, params.get(key).toString()));
        }

        try {
            URI uri = new URIBuilder(url).addParameters(list).build();
            httpPost = new HttpPost(uri);
        } catch (Exception e) {
        	log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }

        return executeBytes(httpPost);
    }

     /**
     * @desc post请求
     * @param url, json
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String postJson(String url, String json) {
        return postJson(url, json, false);
    }

     /**
     * @desc post请求
     * @param url, json, gzip
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String postJson(String url, String json, boolean gzip) {
        HttpPost httpPost = null;
        try {
            URI uri = new URIBuilder(url).build();
            httpPost = new HttpPost(uri);

            // post请求是将参数放在请求体里面传过去的,这里将entity放入post请求体中

            httpPost.setHeader("Content-Type", "application/json;charset=utf8");

            if (gzip) {
                httpPost.setHeader("Content-Encoding", "gzip");
                ByteArrayOutputStream originalContent = new ByteArrayOutputStream();
                originalContent.write(json.getBytes(StandardCharsets.UTF_8));
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
                originalContent.writeTo(gzipOut);
                gzipOut.finish();
                httpPost.setEntity(new ByteArrayEntity(baos
                        .toByteArray(), ContentType.create("text/plain", "utf-8")));
            } else {
                StringEntity entity = new StringEntity(json, "UTF-8");
                httpPost.setEntity(entity);

            }

        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }
        return execute(httpPost);
    }
    
     /**
     * @desc post请求byte流
     * @param url, bytes
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String postInputBytes(String url, byte[] bytes) {
        return postInputBytes(url, bytes, false);
    }

     /**
     * @desc post请求byte流
     * @param url, bytes, gzip
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String postInputBytes(String url, byte[] bytes, boolean gzip) {
        HttpPost httpPost = null;
        try {
            URI uri = new URIBuilder(url).build();
            httpPost = new HttpPost(uri);

            // post请求是将参数放在请求体里面传过去的,这里将entity放入post请求体中
            if (gzip) {
                httpPost.setHeader("Content-Encoding", "gzip");
                ByteArrayOutputStream originalContent = new ByteArrayOutputStream();
                originalContent.write(bytes);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                GZIPOutputStream gzipOut = new GZIPOutputStream(baos);
                originalContent.writeTo(gzipOut);
                gzipOut.finish();
                httpPost.setEntity(new ByteArrayEntity(baos
                        .toByteArray(), ContentType.create("text/plain", "utf-8")));
            } else {
                ByteArrayEntity entity = new ByteArrayEntity(bytes, ContentType.create("text/plain", "utf-8"));
                httpPost.setEntity(entity);
            }

        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }

        return execute(httpPost);
    }
    
     /**
     * @desc post请求流
     * @param url, is
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String postInputStream(String url, InputStream is) {
        return postInputStream(url, is, false);
    }

     /**
     * @desc post请求流
     * @param url, is, gzip
     * @return String
     * @author liangliang
     * @date 2019/3/11 13:23
     */
    public static String postInputStream(String url, InputStream is, boolean gzip) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int ch;
        byte[] bytes = null;
        try {
            while ((ch = is.read(buffer)) != -1) {
                byteArrayOutputStream.write(buffer, 0, ch);
            }
            bytes = byteArrayOutputStream.toByteArray();
            byteArrayOutputStream.close();
        } catch (Exception e) {
        	log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }
        return postInputBytes(url, bytes, gzip);
    }

     /**
     * @desc post请求文件
     * @param url, files
     * @return String
     * @author zhangh
     * @date 2019/3/11 13:23
     */
    public static String postFile(String url, File[] files) {
        return postFile(url, new HashMap<>(), files);
    }


     /**
     * @desc post请求文件
     * @param url, params, files
     * @return String
     * @author zhangh
     * @date 2019/3/11 13:23
     */
    public static String postFile(String url, Map<String, Object> params, File[] files) {
        HttpPost httpPost = null;
        try {
            URI uri = new URIBuilder(url).build();
            httpPost = new HttpPost(uri);

            MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
            String filesKey = "files";
            for (File file : files) {
                //multipartEntityBuilder.addPart(filesKey,new FileBody(file)); //与下面的语句作用相同
                //multipartEntityBuilder.addBinaryBody(filesKey, file);

                // 防止服务端收到的文件名乱码。 我们这里可以先将文件名URLEncode,然后服务端拿到文件名时在URLDecode。就能避免乱码问题。
                // 文件名其实是放在请求头的Content-Disposition里面进行传输的,如其值为form-data; name="files"; filename="头像.jpg"
                multipartEntityBuilder.addBinaryBody(filesKey, file, ContentType.DEFAULT_BINARY, URLEncoder.encode(file.getName(), "utf-8"));

            }

            // 其它参数(注:自定义contentType,设置UTF-8是为了防止服务端拿到的参数出现乱码)
            ContentType contentType = ContentType.create("text/plain", StandardCharsets.UTF_8);
            for (String key : params.keySet()) {
                multipartEntityBuilder.addTextBody(key, params.get(key).toString(), contentType);
            }
            HttpEntity entity = multipartEntityBuilder.build();

            // post请求是将参数放在请求体里面传过去的,这里将entity放入post请求体中
            httpPost.setEntity(entity);

        } catch (Exception e) {
            log.error("Exception responseResult:{}", e.getMassage());
            e.printStackTrace();
        }

        return execute(httpPost);
    }


}


二、OKhttp

1、高效的HTTP客户端,它能允许同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力,透明的GZIP压缩减少响应数据的大小;缓存响应内容。
2、okhttp 对http和https都有良好的支持。
3、okhttp 对大数据量的网络请求支持非常好。

Util工具类

import okhttp3.*;
import org.apache.commons.lang3.exception.ExceptionUtils;

import java.io.File;
import java.util.Iterator;
import java.util.Map;

@Slf4j
public class OkHttpUtil{
    
    private static OkHttpClient  okHttpClient;

    @Autowired
    public OkHttpUtil(OkHttpClient  okHttpClient) {
        OkHttpUtil.okHttpClient= okHttpClient;
    } 
    
    /**
     * get
     * @param url   请求的url
     * @param param 请求的参数
     * @return
     */
    public static  String get(String url, Map<String, String> param) {
        String responseBody = "";
        StringBuffer sb = new StringBuffer(url);
        if (param!= null && param.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = param.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "=" + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "=" + entry.getValue());
                }
            }
        }
        Request request = new Request.Builder()
                .url(sb.toString())
                .build();
        Response response = null;
        try { 
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("okhttp3 post exception:{}", e.getMessage());
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * post
     *
     * @param url    请求的url
     * @param params post form 提交的参数
     * @return
     */
    public static String post(String url, Map<String, String> params) {
        String responseBody = "";
        FormBody.Builder builder = new FormBody.Builder();
        //添加参数
        if (params != null && params.keySet().size() > 0) {
            for (String key : params.keySet()) {
                builder.add(key, params.get(key));
            }
        }
        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();
        Response response = null;
        try { 
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("okhttp3 post exception:{}", e.getMessage());
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * get
     * @param url     请求的url
     * @param param 请求的参数
     * @return
     */
    public static String getForHeader(String url, Map<String, String> param) {
        String responseBody = "";
        StringBuffer sb = new StringBuffer(url);
        if (param != null && param.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = param.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "=" + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "=" + entry.getValue());
                }
            }
        }
        Request request = new Request.Builder()
                .addHeader("key", "value")
                .url(sb.toString())
                .build();
        Response response = null;
        try { 
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("okhttp3 post exception:{}", e.getMessage());
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * Post请求发送JSON数据
     * @param url 请求Url
     * @param jsonParams 请求的JSON
     */
    public static String postJsonParams(String url, String jsonParams) {
        String responseBody = "";
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), jsonParams);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        Response response = null;
        try { 
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("okhttp3 post exception:{}", e.getMessage());
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }

    /**
     * Post请求发送xml类型数据
     * @param url 请求Url
     * @param xml 请求的xml
     */
    public static String postXmlParams(String url, String xml) {
        String responseBody = "";
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/xml; charset=utf-8"), xml);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        Response response = null;
        try { 
            response = okHttpClient.newCall(request).execute();
            int status = response.code();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("okhttp3 post exception:{}", e.getMessage());
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return responseBody;
    }
}

三、RestTemplate

1、Spring 提供的用于访问Rest服务的客户端, RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
2、面向对 RESTful Web 服务调用的功能。

在微服务中的使用

1、第三方服务调用,个人常用 RestTemplate, 这里RestTemplate未未进行封装,直接使用其方法。

2、微服务间调用,个人使用feign,同时使用OKhttp替换feign中默认的httpClient。
Feign在默认情况下使用的是JDK原生的URLConnection发送HTTP请求,没有连接池,但是对每个地址会保持一个长连接,即利用HTTP的persistence connection 。 我们可以用HTTP Client 或 OKhttp 替换Feign原始的http client, 从而获取连接池、超时时间等与性能息息相关的控制能力。

SpringCloud 1.x
<!-- 使用Apache HttpClient替换Feign原生httpclient -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>com.netflix.feign</groupId>
            <artifactId>feign-httpclient</artifactId>
            <version>${feign-httpclient}</version>
        </dependency>
application.properties中添加:
feign.httpclient.enabled=true
<!-- 使用OKhttp替换Feign原生httpclient -->
<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
    <version>10.2.0</version>
</dependency>
application.properties中添加:
feign.okhttp.enabled=true


SpringColud 2.x
<!-- 使用OKhttp替换openFeign原生httpclient -->
<dependency>
  <groupId>com.squareup.okhttp3</groupId>
  <artifactId>okhttp</artifactId>
  <version>3.10.0</version>
</dependency>

feign.okhttp.enabled=true


原文链接:https://blog.csdn.net/weixin_44739349/article/details/106097201

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值