当前位置:   article > 正文

HttpClient、OKhttp、RestTemplate接口调用对比( Java HTTP 客户端)_resttemplate和hhtpclient哪个好用

resttemplate和hhtpclient哪个好用

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);
    }


}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390
  • 391
  • 392
  • 393
  • 394
  • 395
  • 396
  • 397
  • 398
  • 399
  • 400
  • 401
  • 402
  • 403
  • 404
  • 405
  • 406
  • 407
  • 408
  • 409
  • 410
  • 411
  • 412
  • 413
  • 414
  • 415
  • 416
  • 417
  • 418
  • 419
  • 420
  • 421
  • 422
  • 423
  • 424
  • 425
  • 426
  • 427
  • 428
  • 429
  • 430
  • 431
  • 432
  • 433
  • 434
  • 435
  • 436
  • 437
  • 438
  • 439
  • 440
  • 441
  • 442
  • 443
  • 444
  • 445
  • 446
  • 447
  • 448
  • 449
  • 450
  • 451
  • 452
  • 453
  • 454
  • 455
  • 456
  • 457
  • 458
  • 459
  • 460
  • 461
  • 462
  • 463
  • 464
  • 465
  • 466
  • 467
  • 468
  • 469
  • 470
  • 471
  • 472
  • 473
  • 474
  • 475
  • 476
  • 477
  • 478
  • 479
  • 480
  • 481
  • 482
  • 483
  • 484
  • 485
  • 486
  • 487
  • 488
  • 489
  • 490
  • 491
  • 492
  • 493
  • 494
  • 495
  • 496
  • 497
  • 498
  • 499
  • 500
  • 501
  • 502
  • 503
  • 504
  • 505
  • 506
  • 507
  • 508
  • 509
  • 510
  • 511
  • 512
  • 513
  • 514
  • 515
  • 516
  • 517
  • 518
  • 519
  • 520
  • 521
  • 522
  • 523
  • 524
  • 525
  • 526
  • 527
  • 528
  • 529
  • 530
  • 531
  • 532
  • 533
  • 534
  • 535
  • 536
  • 537
  • 538
  • 539
  • 540
  • 541
  • 542
  • 543
  • 544
  • 545
  • 546
  • 547
  • 548
  • 549
  • 550
  • 551
  • 552
  • 553
  • 554
  • 555
  • 556
  • 557
  • 558
  • 559
  • 560
  • 561
  • 562
  • 563
  • 564
  • 565
  • 566
  • 567
  • 568
  • 569
  • 570
  • 571
  • 572
  • 573
  • 574
  • 575
  • 576
  • 577
  • 578
  • 579
  • 580
  • 581
  • 582
  • 583
  • 584
  • 585
  • 586
  • 587
  • 588
  • 589
  • 590
  • 591
  • 592
  • 593
  • 594
  • 595
  • 596
  • 597
  • 598
  • 599
  • 600
  • 601
  • 602
  • 603
  • 604

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;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198

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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/754642
推荐阅读
相关标签
  

闽ICP备14008679号