OkHttp工具类

OkHttp工具类

Java生态中主流的HTTP客户端工具

1.Apache HttpClient

  • 类型: 同步阻塞
  • 依赖: org.apache.httpcomponents:httpclient
  • 特点:
    • 成熟稳定
    • 支持连接池、重试、缓存等高级功能
    • 完整的HTTP协议支持(包括HTTP/2)
  • 适用场景: 传统企业级应用、复杂HTTP交互

2.OkHttp

  • 类型: 同步|异步(通过Callbacks)
  • 依赖: com.squareup.okhttp3:okhttp
  • 特点:
    • 默认支持HTTP/2和QUIC
    • 自动GZIP压缩、连接池、缓存
    • 简洁的API设计
  • 适用场景: Android应用、高并发服务、API网关

3.Spring WebClient

  • 类型: 异步非阻塞(Reactive)
  • 依赖: org.springframework.boot:spring-boot-start-webflux
  • 特点:
    • 响应式编程(基于Project Reactor)
    • 函数式API、流式处理
    • 支持SSE(Server-Sent Events)
  • 使用场景: Spring WebFlux应用、微服务间通信

4.Retrofit

  • 类型: 同步|异步(基于OkHttp)
  • 依赖: com.squareup.retrofit2:retrofit
  • 特点:
    • 声明式API(接口+注解)
    • 自动JSON序列化(集成Gson/Jackson)
    • 支持RxJava|Coroutines
  • 适用场景: Android应用、REST API封装

5.HttpClient(JDK11自带)

  • 类型: 同步|异步(内置JDK)
  • 依赖: JDK11+自带
  • 特点:
    • 官方标准库(无需额外依赖)
    • 支持HTTP/2和WebSocket
    • 简单的异步API
  • 适用场景: 简单HTTP请求、无依赖场景

6.Feign

  • 类型: 声明式客户端
  • 依赖: io.github.openfeign:feign-core
  • 特点:
    • 注解驱动(类似Retrofit)
    • 与Spring Cloud集成(负载均衡、熔断)
    • 可插拔编码器/解码器
  • 适用场景: 微服务架构(配合Spring Cloud)

HTTP客户端工具对比表

工具 同步|异步 HTTP/2 连接池 学习曲线 适用场景 性能
Apache HttpClient 同步 中等 企业级复杂应用
OkHttp 同步|异步 Android|高并发服务 极高
Spring WebClient 同步 Spring响应式应用
Retrofit 同步|异步 Android|Rest API 封装
Java HttpClient 同步|异步 × JDK内置简单场景 中高
Feign 同步 依赖实现 依赖实现 中等 Spring Cloud微服务 中高

HTTP客户端工具的选型建议

  • Android开发: OkHttp或Retrofit
  • Spring Boot项目: 响应式-Spring WebClient,传统同步-Apache HttpClient
  • 轻量级|无依赖: Java HttpClient
  • 高性能要求: OkHttp(同步|异步)
  • 微服务架构: Feign+Spring Cloud

OkHttp概述

OkHttp是由Square公司开发的高效、开源的HTTP客户端库,专为Java和Android平台设计。它以简洁的API、强大的功能和卓越的性能著称,称为Android开发中网络请求的事实标准,并广泛用于Java后端服务

核心特性

1.高效连接管理

  • 连接池复用: 减少TCP握手开销,提升请求速度
  • HTTP/2支持: 多路复用请求,降低延迟
  • 自动GZIP压缩: 透明压缩响应体,节省带宽

2.灵活的请求与响应

  • 同步或异步调用: 支持阻塞式同步请求和基于回调的异步请求
  • 链式拦截器(Interceptor): 可自定义拦截请求/响应(如日志,鉴权)
  • 流式API: 通过RequestBody和ResponseBody处理大文件流式传输

3.安全与可靠性

  • 默认TLS支持: 自动适配TLS1.3,支持证书固定
  • 自动重试与路由切换: 在连接失败时智能切换到备用路由
  • 超时控制: 支持连接、读取、写入超时配置

4.扩展性与兼容性

  • WebSocket支持: 内置全双工通信协议
  • 缓存控制: 可配置的响应缓存(遵循HTTP缓存规范)
  • 无缝集成: 与Retrofit(REST API封装库)、Picasso/Glide(图片加载)完美协作

基本用法

// 1. 创建 OkHttpClient 实例
OkHttpClient client = new OkHttpClient();

// 2. 构建请求
Request request = new Request.Builder()
    .url("https://api.example.com/data")
    .header("User-Agent", "OkHTTP-Demo")
    .build();

// 3. 同步执行请求
try (Response response = client.newCall(request).execute()) {
    if (response.isSuccessful()) {
        String result = response.body().string();
        System.out.println(result);
    }
}

// 异步请求(回调方式)
client.newCall(request).enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) throws IOException {
        // 处理响应
    }
    @Override
    public void onFailure(Call call, IOException e) {
        // 处理错误
    }
});

关键优势

  • 简洁的API: 链式调用设计,降低学习成本
  • 高性能: 连接池复用、HTTP/2支持等优化,比原生HttpURLConnection快30%+
  • 强健的错误处理: 自动恢复常见网络问题(如重定向、连接中断)
  • 模块化拦截器: 通过拦截器实现日志、监控、重试等逻辑,无需修改业务代码。

典型应用场景

  1. Android应用开发: 替代HttpURLConnection,处理REST API请求
  2. 微服务通信: Java后端服务间的HTTP调用
  3. 文件下载/上传: 支持进度监听和断点续传(需结合拦截器实现)
  4. WebSocket实时通信: 聊天室、实时数据推送等场景
  5. 测试框架集成: Mock网络响应

OKHttp工具类

引入依赖

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.12.0</version>
        </dependency>

工具类代码

import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * okHttp客户端工具类
 */
public class OkHttpUtil {

    /**
     * 创建静态的Logger实例
     */
    private static final Logger log = LoggerFactory.getLogger(OkHttpUtil.class);
    private static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";

    private static final Object OBJECT = new Object();

    private static OkHttpClient okHttpClient;

    private OkHttpUtil() {

    }

    /**
     * 单例模式获取okhttp客户端
     *
     * @return http客户端实例
     */
    public static OkHttpClient getOkHttpClient() {
        if (okHttpClient == null) {
            synchronized (OBJECT) {
                okHttpClient = getOkHttpClient(600, 600, 600);
            }
        }
        return okHttpClient;
    }

    /**
     * 生成okhttp客户端
     *
     * @return http客户端实例
     */
    public static OkHttpClient getOkHttpClient(int connectTimeOut, int readTimeOut, int writeTimeOut) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(connectTimeOut, TimeUnit.SECONDS);
        builder.readTimeout(readTimeOut, TimeUnit.SECONDS);
        builder.writeTimeout(writeTimeOut, TimeUnit.SECONDS);
        return builder.build();
    }

    /**
     * get请求
     *
     * @param okHttpClient okhttp客户端
     * @param url          请求url
     * @param headers      请求头
     * @return 响应结果
     */
    public static String get(OkHttpClient okHttpClient, String url, Headers headers) {
        Request request = new Request.Builder().url(url).headers(headers).get().build();
        String responseData = request(okHttpClient, url, request);
        log.info("okHttpClient get url:{}, request responseData:{}", url, responseData);
        return responseData;
    }

    /**
     * get请求
     *
     * @param okHttpClient okhttp客户端
     * @param url          请求url
     * @return 响应结果
     */
    public static String get(OkHttpClient okHttpClient, String url) {
        Headers headers = new Headers.Builder().build();
        return get(okHttpClient, url, headers);
    }

    /**
     * get请求
     *
     * @param url 请求url
     * @return 响应结果
     */
    public static String get(String url) {
        OkHttpClient okHttpClient = getOkHttpClient();
        Headers headers = new Headers.Builder().build();
        return get(okHttpClient, url, headers);
    }

    /**
     * post请求
     *
     * @param okHttpClient okhttp客户端
     * @param url          请求url
     * @param bodyJson     请求json
     * @param headers      请求头
     * @return 响应结果
     */
    public static String post(OkHttpClient okHttpClient, String url, String bodyJson, Headers headers) {
        MediaType mediaType = MediaType.get(MEDIA_TYPE_JSON);
        RequestBody responseBody = RequestBody.create(bodyJson, mediaType);
        Request request = new Request.Builder().url(url).headers(headers).post(responseBody).build();
        String responseData = request(okHttpClient, url, request);
        log.info("okHttpClient post url:{}, request responseData:{}", url, responseData);
        return responseData;
    }

    /**
     * post请求
     *
     * @param url      请求url
     * @param bodyJson 请求json
     * @return 响应结果
     */
    public static String post(Map<String, String> headersMap, String url, String bodyJson) {
        OkHttpClient okHttpClient = getOkHttpClient();
        Headers headers = Headers.of(headersMap);
        return post(okHttpClient, url, bodyJson, headers);
    }

    /**
     * post请求
     *
     * @param url      请求url
     * @param bodyJson 请求json
     * @return 响应结果
     */
    public static String post(String url, String bodyJson) {
        OkHttpClient okHttpClient = getOkHttpClient();
        Headers headers = new Headers.Builder().build();
        return post(okHttpClient, url, bodyJson, headers);
    }


    /**
     * 获取响应结果
     *
     * @param okHttpClient http客户端
     * @param url          请求url
     * @param request      请求体
     * @return 响应结果
     */
    public static String request(OkHttpClient okHttpClient, String url, Request request) {
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.body() != null) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error("okHttpClient request error, url:{}, error: ", url, e);
        }
        return "";
    }
}

参考资料

OkHttp-github网址: https://github.com/square/okhttp
OkHttp项目网址: https://square.github.io/okhttp/
OkHttp项目中文网址: https://square.ac.cn/okhttp/

posted @ 2025-07-08 00:24  柯南。道尔  阅读(191)  评论(0)    收藏  举报