HttpClient、OKhttp、RestTemplate接口调用对比( Java HTTP 客户端)

avatar
作者
筋斗云
阅读量:1

文章目录

HttpClient、OKhttp、RestTemplate接口调用对比

HttpClient、OkHttp 和 RestTemplate 是三种常用的 Java HTTP 客户端库,它们都可以用于发送 HTTP 请求和接收 HTTP 响应,但在一些方面有所不同。
对比总结:
● 性能和效率: OkHttp 在性能和效率上通常优于 Apache HttpClient 和 RestTemplate,特别是在并发场景和对性能要求较高的情况下。
● 功能和灵活性: Apache HttpClient 提供了更丰富的功能和灵活的配置选项,适用于需要定制化的场景;而 OkHttp 和 RestTemplate 则更加简洁易用。
● 异步支持: OkHttp 提供了异步调用的支持,而 Apache HttpClient 和 RestTemplate 需要通过额外的工作来实现异步调用。
● 与框架集成: RestTemplate 与 Spring 框架集成度高,更适合于 Spring 项目;而 Apache HttpClient 和 OkHttp 可以在各种项目中独立使用。
● 更新维护: OkHttp 是 Square 公司维护的开源项目,更新迭代较为活跃;Apache HttpClient 在过去曾有一段时间的停滞,但也在持续维护;而 RestTemplate 在新项目中可能会被 WebClient 替代,不再是 Spring 官方推荐的首选。
综上所述,选择合适的 HTTP 客户端库取决于项目需求、性能要求、对框架集成的需求以及个人偏好等因素。

HttpClient:

  1. Apache HttpClient:
    ○ 成熟稳定: Apache HttpClient 是 Apache 软件基金会的一个项目,经过多年的发展,已经非常成熟和稳定。
    ○ 灵活性: 提供了丰富的配置选项和扩展点,可以灵活地定制和扩展功能。
    ○ 线程安全: HttpClient 的实例是线程安全的,可以在多线程环境中共享使用。
    ○ 相对庞大: 相对于其他库来说,Apache HttpClient 的体积较大,可能会增加应用程序的大小。

OkHttp:

  1. Square OkHttp:
    ○ 高性能: OkHttp 是一个现代化的 HTTP 客户端,具有优秀的性能和效率。
    ○ 简洁易用: 提供了简洁的 API 设计,易于学习和使用。
    ○ 支持 HTTP/2: 支持 HTTP/2,可以实现多路复用,提高并发性能。
    ○ 轻量级: OkHttp 的体积相对较小,对应用程序的大小影响较小。

RestTemplate:

  1. Spring RestTemplate:
    ○ 与 Spring 集成: RestTemplate 是 Spring 框架提供的一个 HTTP 客户端,与 Spring 生态集成度高。
    ○ 便捷的 RESTful 支持: 提供了便捷的 RESTful 风格的 API 调用支持,如 HTTP 方法映射、请求和响应消息转换等。
    ○ 同步阻塞: RestTemplate 是一个同步阻塞的 HTTP 客户端,对于高并发场景可能性能较差。
    ○ 可能过时: 随着 Spring 5 推出的 WebClient,RestTemplate 在新项目中可能会逐渐被 WebClient 替代。

HttpClient

Apache HttpClient 是一个用于执行 HTTP 请求的开源 Java 库。它提供了丰富的功能和灵活的接口,可以用来发送 HTTP 请求并处理 HTTP 响应。
HttpClient 是Apache的一个三方网络框架,网络请求做了完善的封装,api众多,用起来比较方便,开发快
功能特点:

  1. 支持多种 HTTP 方法: Apache HttpClient 支持 GET、POST、PUT、DELETE 等常见的 HTTP 方法,以及任意自定义的 HTTP 方法。
  2. 支持 HTTPS: HttpClient 支持使用 SSL/TLS 加密协议进行 HTTPS 请求,并可以自定义 SSL/TLS 配置。
  3. 连接管理: HttpClient 提供了连接池管理机制,可以有效地管理 HTTP 连接,减少连接建立的开销。
  4. 请求和响应拦截器: HttpClient 允许用户定义请求和响应的拦截器,可以在请求发送前或响应返回后对请求和响应进行处理。
  5. 自定义请求头和请求参数: HttpClient 允许用户自定义请求头和请求参数,可以灵活地设置 HTTP 请求的各种参数。
  6. 重定向处理: HttpClient 可以自动处理 HTTP 请求的重定向,并且允许用户配置重定向策略。
  7. Cookie 管理: HttpClient 支持自动管理 HTTP Cookie,可以处理 Cookie 的存储、发送和接收。
  8. 代理支持: HttpClient 可以配置使用代理服务器进行 HTTP 请求。
  9. 认证机制: HttpClient 支持多种认证机制,包括基本认证、摘要认证、OAuth 等。
    核心组件:
  10. HttpClient: HttpClient 类是 Apache HttpClient 的核心类,用于执行 HTTP 请求并处理 HTTP 响应。
  11. HttpRequest: HttpRequest 接口表示一个 HTTP 请求,包括请求方法、请求头、请求参数等信息。
  12. HttpResponse: HttpResponse 接口表示一个 HTTP 响应,包括状态码、响应头、响应体等信息。
  13. HttpClientBuilder: HttpClientBuilder 是用于创建 HttpClient 实例的构建器,可以配置 HttpClient 的各种参数。
  14. HttpEntity: HttpEntity 接口表示一个 HTTP 实体,包括请求体、响应体等信息。
  15. HttpClientContext: HttpClientContext 类表示一个 HTTP 执行上下文,包括请求的上下文信息、连接状态等。

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

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

高效的HTTP客户端,它能允许同一ip和端口的请求重用一个socket,这种方式能大大降低网络连接的时间,和每次请求都建立socket,再断开socket的方式相比,降低了服务器服务器的压力,透明的GZIP压缩减少响应数据的大小;缓存响应内容。
OkHttp 是一个现代化的 HTTP 客户端库,由 Square 公司开发并维护,用于在 Android 和 Java 应用程序中发送 HTTP 请求和接收 HTTP 响应。它具有以下特点和优势:
高性能: OkHttp 使用了连接池、复用连接、异步请求等技术,可以实现高效的 HTTP 请求和响应处理,性能优秀。
支持 HTTP/2: OkHttp 支持 HTTP/2,能够实现多路复用,提高了网络请求的并发效率。
简洁易用的 API: OkHttp 提供了简洁易用的 API 设计,使用起来非常方便,易于学习和使用。
丰富的功能: OkHttp 提供了丰富的功能,包括请求和响应的拦截、重定向、GZIP 压缩、连接池管理等,可以满足各种复杂的应用场景需求。
灵活性: OkHttp 提供了丰富的配置选项和扩展点,可以灵活地定制和扩展功能,满足各种特定需求。
支持同步和异步请求: OkHttp 支持同步和异步请求,可以根据需求选择合适的方式进行网络请求。
轻量级: OkHttp 的体积相对较小,对应用程序的大小影响较小,适合于移动端应用和对包大小敏感的项目。
持续更新和维护: OkHttp 是由 Square 公司维护的开源项目,更新迭代较为活跃,能够及时修复 bug 和添加新功能。

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

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

RestTemplate 是 Spring 框架提供的一个用于进行 HTTP 请求的模板类,它简化了在 Java 中进行 HTTP 请求的操作。RestTemplate 提供了丰富的方法来发送 HTTP 请求,并且支持多种 HTTP 请求方法(如 GET、POST、PUT、DELETE 等),以及各种数据格式(如 JSON、XML 等)的处理。
RestTemplate 是由Spring提供的一个HTTP请求工具。比传统的Apache和HttpCLient便捷许多,能够大大提高客户端的编写效率。

1、Spring 提供的用于访问Rest服务的客户端, RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
2、面向对 RESTful Web 服务调用的功能。
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, 从而获取连接池、超时时间等与性能息息相关的控制能力。

特点和优势:

  1. 与 Spring 集成: RestTemplate 是 Spring 框架的一部分,与 Spring 生态完美集成,可以轻松在 Spring 项目中使用。
  2. 简化 HTTP 请求: RestTemplate 封装了发送 HTTP 请求的底层细节,使得发送 HTTP 请求变得简单和方便。
  3. RESTful 支持: RestTemplate 提供了便捷的 RESTful 风格的 API 调用支持,可以方便地进行资源的增删改查操作。
  4. 丰富的方法: RestTemplate 提供了多种方法来发送不同类型的 HTTP 请求,包括 getForObject()、postForObject()、exchange() 等,以及一系列便捷的方法用于设置请求参数、请求头等。
  5. 支持数据转换: RestTemplate 支持自动将请求和响应的数据转换为 Java 对象,可以通过消息转换器实现 JSON、XML 等格式的数据转换。
  6. 同步阻塞: RestTemplate 是一个同步阻塞的 HTTP 客户端,发送请求后会阻塞当前线程直到收到响应或超时。
  7. 异常处理: RestTemplate 提供了异常处理机制,可以捕获和处理请求过程中可能出现的异常。
    RestTemplate 是由Spring提供的一个HTTP请求工具。比传统的Apache和HttpCLient便捷许多,能够大大提高客户端的编写效率。
    1、Spring 提供的用于访问Rest服务的客户端, RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
    2、面向对 RESTful Web 服务调用的功能。
    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, 从而获取连接池、超时时间等与性能息息相关的控制能力。

RestTemplate 是由Spring提供的一个HTTP请求工具。比传统的Apache和HttpCLient便捷许多,能够大大提高客户端的编写效率。

1、Spring 提供的用于访问Rest服务的客户端, RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率。
2、面向对 RESTful Web 服务调用的功能。
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>   SpringColud 2.x <!-- 使用OKhttp替换openFeign原生httpclient --> <dependency>   <groupId>com.squareup.okhttp3</groupId>   <artifactId>okhttp</artifactId>   <version>3.10.0</version> </dependency> 

application.properties中添加:
feign.okhttp.enabled=true

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!