Spring boot 整合 Okhttp3 并封装请求工具

news2024/12/23 2:44:18

一、 为什么要使用okHttp

OkHttp是一个高效、灵活、易于使用的HTTP客户端库,优势如下:

  1. 性能更高:OkHttp在网络请求处理上采用了异步模型,并将连接池、压缩、网络协议等多种技术应用到其中,从而提高了网络请求的效率和处理速度。

  2. 功能更强大:OkHttp支持HTTP/2协议,可以进行数据流复用以及服务器推送。同时,OkHttp还支持GZIP压缩、连接超时设置、缓存、重试等功能,提供了非常丰富的API接口,方便开发者进行扩展和个性化定制。

  3. 使用更简单:OkHttp具有良好的API设计,可以轻松地实现网络请求的发送和响应处理。其内置了许多预定义的请求类型,如Get, Post, Head, Put, Delete等,使得开发者可以快速地进行开发。

  4. 兼容性更好:OkHttp的代码精简,运行效率高,并且兼容Android平台和Java平台,可以在各种场景下进行使用。

OkHttp作为一款成熟、稳定、易用的HTTP客户端库,拥有较高的性能和多样化的功能,已被广泛应用于移动应用开发、Web服务端开发等领域。

二、 导入依赖

<!-- okhttp3 依赖 -->
<dependency>
	<groupId>com.squareup.okhttp3</groupId>
	<artifactId>okhttp</artifactId>
	<version>4.9.3</version>
</dependency>

三、 配置

  1. 使用okhttp3 是很简单的,但是需要配置连接池,缓存代理等
  2. 项目配置,application.yml 文件配置
ok:
  http:
    connect-timeout: 60
    read-timeout: 60
    write-timeout: 60
    # 连接池中整体的空闲连接的最大数量
    max-idle-connections: 200
    # 连接空闲时间最多为 300 秒
    keep-alive-duration: 300
  1. 添加 配置应用,连接池,缓存,代理等开启
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;

/**
 * @author luoqifeng
 */
@Configuration
public class OkHttpConfiguration {

    @Value("${ok.http.connect-timeout}")
    private Integer connectTimeout;
    @Value("${ok.http.read-timeout}")
    private Integer readTimeout;
    @Value("${ok.http.write-timeout}")
    private Integer writeTimeout;
    @Value("${ok.http.max-idle-connections}")
    private Integer maxIdleConnections;
    @Value("${ok.http.keep-alive-duration}")
    private Long keepAliveDuration;
    @Bean
    public OkHttpClient okHttpClient() {
        return new OkHttpClient.Builder()
                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
                // 是否开启缓存
                .retryOnConnectionFailure(false)
                .connectionPool(pool())
                .connectTimeout(connectTimeout, TimeUnit.SECONDS)
                .readTimeout(readTimeout, TimeUnit.SECONDS)
                .writeTimeout(writeTimeout,TimeUnit.SECONDS)
                .hostnameVerifier((hostname, session) -> true)
                // 设置代理
                // .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888)))
                // 拦截器
                // .addInterceptor()
                .build();
    }
    @Bean
    public X509TrustManager x509TrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }
            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType)
                    throws CertificateException {
            }
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }
    @Bean
    public SSLSocketFactory sslSocketFactory() {
        try {
            // 信任任何链接
            SSLContext sslContext = SSLContext.getInstance("TLS");
            sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
            return sslContext.getSocketFactory();
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
        return null;
    }
    @Bean
    public ConnectionPool pool() {
        return new ConnectionPool(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
    }
}
  1. 配置创建工具类
package cn.wjj.wjjUtils.util;

import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author luoqifeng
 */
@Slf4j
@Component
public class OkHttpClientUtil {
    private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    private static final MediaType XML = MediaType.parse("application/xml; charset=utf-8");

    private static OkHttpClient okHttpClient;

    // 为使用静态调用异步注入
    @Autowired
    private OkHttpClient getOkHttpClient;
    @PostConstruct
    public void init() {
        okHttpClient = getOkHttpClient;
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @return string
     * */
    public static String doGet(String url) {
        return doGet(url, null, null);
    }

    public static byte[] doGetByte(String url) {
        return doGetByte(url, null, null);
    }

    public static String doPost(String url) {
        return doPost(url, null, null);
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @param params 请求参数 map
     * @return string
     * */
    public static String doGetToParams(String url, Map<String, String> params) {
        return doGet(url, params, null);
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @param headers 请求头字段 {k1, v1 k2, v2, ...}
     * @return string
     * */
    public static String doGetToHeaders(String url, Map<String, String> headers) {
        return doGet(url, null, headers);
    }
    /**
     * get 请求
     * @param url  请求url地址
     * @param params 请求参数 map
     * @param headers 请求头字段 {k1, v1 k2, v2, ...}
     * @return string
     * */
    public static String doGet(String url, Map<String, String> params, Map<String, String> headers) {
        StringBuilder sb = new StringBuilder(url);
        if (params != null && params.keySet().size() > 0) {
            boolean firstFlag = true;
            for (String key : params.keySet()) {
                if (firstFlag) {
                    sb.append("?").append(key).append("=").append(params.get(key));
                    firstFlag = false;
                } else {
                    sb.append("&").append(key).append("=").append(params.get(key));
                }
            }
        }
        Request.Builder builder = new Request.Builder();
        if (headers != null && !headers.isEmpty()) {
            for (String header:headers.keySet()){
                builder.addHeader(header, headers.get(header));
            }
        }
        Request request = builder.url(sb.toString()).build();
        log.info("do get request and url[{}]", sb.toString());
        return executeBody(request);
    }

    public static byte[] doGetByte(String url, Map<String, String> params, Map<String, String> headers) {
        StringBuilder sb = new StringBuilder(url);
        if (params != null && params.keySet().size() > 0) {
            boolean firstFlag = true;
            for (String key : params.keySet()) {
                if (firstFlag) {
                    sb.append("?").append(key).append("=").append(params.get(key));
                    firstFlag = false;
                } else {
                    sb.append("&").append(key).append("=").append(params.get(key));
                }
            }
        }
        Request.Builder builder = new Request.Builder();
        if (headers != null && !headers.isEmpty()) {
            for (String header:headers.keySet()){
                builder.addHeader(header, headers.get(header));
            }
        }
        Request request = builder.url(sb.toString()).build();
        log.info("do get request and url[{}]", sb.toString());
        return executeByte(request);
    }
    /**
     * post 请求
     * @param url  请求url地址
     * @param params 请求参数 map
     * @return string
     */
    public static String doPostForm(String url, Map<String, String> params) {
        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();
        log.info("do post request and url[{}]", url);
        return execute(request);
    }

    /**
     * post 请求
     * @param url  请求url地址
     * @param params 请求参数 map
     * @param headers 请求头字段 {k1:v1, k2: v2, ...}
     * @return string
     */
    public static String doPost(String url, Map<String, String> params, Map<String, String> headers) {
        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.Builder requestBuilder = new Request.Builder();
        if (headers != null && !headers.isEmpty()) {
            for (String header:headers.keySet()){
                requestBuilder.addHeader(header, headers.get(header));
            }
        }
        Request request = requestBuilder.url(url).post(builder.build()).build();
        log.info("do post request and url[{}]", url);
        return execute(request);
    }
    /**
     * post 请求, 请求数据为 json 的字符串
     * @param url  请求url地址
     * @param json  请求数据, json 字符串
     * @return string
     */
    public static String doPostJson(String url, String json) {
        log.info("do post request and url[{}]", url);
        return executePost(url, json, JSON);
    }
    /**
     * post 请求, 请求数据为 json 的字符串
     * @param url  请求url地址
     * @param json  请求数据, json 字符串
     * @param headers 请求头字段 {k1, v1 k2, v2, ...}
     * @return string
     */
    public static String doPostJson(String url, String json, Map<String, String> headers) {
        log.info("do post request and url[{}]", url);

        RequestBody requestBody = RequestBody.create(json, JSON);
        Request.Builder builder = new Request.Builder();
        if (headers != null && !headers.isEmpty()) {
            for (String header:headers.keySet()){
                builder.addHeader(header, headers.get(header));
            }
        }
        Request request = builder.url(url).post(requestBody).build();
        return execute(request);
    }
    /**
     * post 请求, 请求数据为 xml 的字符串
     * @param url  请求url地址
     * @param xml  请求数据, xml 字符串
     * @return string
     */
    public static String doPostXml(String url, String xml) {
        log.info("do post request and url[{}]", url);
        return executePost(url, xml, XML);
    }
    private static String executePost(String url, String data, MediaType contentType) {
        RequestBody requestBody = RequestBody.create(data ,contentType);
        Request request = new Request.Builder().url(url).post(requestBody).build();
        return execute(request);
    }
    private static String execute(Request request) {
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return "";
    }

    private static String executeBody(Request request) {
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            if (response.body() != null) {
                return response.body().string();
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return "";
    }

    private static byte[] executeByte(Request request) {
        Response response = null;
        try {
            response = okHttpClient.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().bytes();
            }
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return null;
    }


}

四、 测试

/**
 * @author luoqifeng
 */
@RestController
@RequestMapping("test")
public class testController {
    
    @GetMapping("testOkhttp")
    public String testOkhttp(){
        String s = OkHttpClientUtil.doGet("https://www.baidu.com");
        return s;
    }
}

响应结果:
在这里插入图片描述
至此已经完成基本的Spring Boot整合 okhttp3 的示例。并使用okhttp3来发送HTTP请求,然后返回HTTP响应。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/948169.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c语言每日一练(12)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

MongoDB实验——在MongoDB集合中查找文档

在MongoDB集合中查找文档 一、实验目的二、实验原理三、实验步骤1.启动MongoDB数据库、启动MongoDB Shell客户端2.数据准备-->person.json3.指定返回的键4 .包含或不包含 i n 或 in 或 in或nin、$elemMatch&#xff08;匹配数组&#xff09;5.OR 查询 $or6.Null、$exists7.…

Vue3 学习 组合式API setup语法糖 响应式 指令 DIFF(一)

文章目录 前言一、Composition Api二、setup语法糖三、响应式refreactive 四、其他一些关键点v-prev-oncev-memov-cloak 五、虚拟Dom五、diff算法 前言 本文用于记录学习Vue3的过程 一、Composition Api 我觉得首先VUE3最大的改变就是对于代码书写的改变&#xff0c;从原来选择…

《自然语言处理》chapter7-预训练语言模型

这是阅读《自然语言处理-基于预训练模型的方法》的学习笔记&#xff0c;记录学习过程&#xff0c;详细的内容请大家购买书籍查阅。 同时参考沐神的两个视频&#xff1a; GPT&#xff0c;GPT-2&#xff0c;GPT-3 论文精读【论文精读】 BERT 论文逐段精读【论文精读】 概述 自然…

如何保证跨境传输的安全性?

随着互联网时代的到来&#xff0c;全球文件传输频率不断增加&#xff0c;市场经济的发展也对信息共享提出更高要求。传统电话交流已无法满足跨国企业的需求&#xff0c;企业内部诸如Web、电子邮件、企业资源计划&#xff08;ERP&#xff09;、网络电话&#xff08;VOIP&#xf…

SAP ABAP 代码调优检查工具及性能调优

一&#xff1a;代码检查工具 ABAP 测试仪表盘(ATC) 所有检查工具, 豁免处理, 结果存储的中心 代码检查器 (SCI) 提供给客户&#xff0c;合作伙伴和SAP的做代码相关检查的开放式架构 扩展程序检查(SLIN) 扩展的代码检查&#xff0c;用来分析源代码 SAP NetWeaver 应用服务器&a…

VMware虚拟机网络连接设置——NAT模式(Windows版)

首先参考VMware虚拟机网络连接设置——仅主机模式&#xff08;Windows版&#xff09;_vmware仅主机模式_Mr.LiuZB的博客-CSDN博客配置&#xff0c;网络还是不通&#xff0c;再结合Linux 虚拟机和主机互通 [万能方法]_linux虚拟机与主机网络连接_核桃胡子的博客-CSDN博客 配置&…

AD域中批量添加域用户

首先在C盘中建立一个文件&#xff0c;名字为file.csv 格式如下 根据CSV文件的ABCDE列来进行识别的 然后我们在cmd命令行中输入一下命令 for /f "tokens1,2,3,4,5 delims," %a in (C:file.csv) do dsadd user "cn%c,ou业务部,ou博迈科技,dcBMKJ,dccom" -s…

Qt应用开发(基础篇)——消息对话框 QMessageBox

一、前言 QMessageBox类继承于QDialog&#xff0c;是一个模式对话框&#xff0c;常用于通知用户或向用户提出问题并接收答案。 对话框QDialog QMessageBox消息框主要由四部分组成&#xff0c;一个主要文本text&#xff0c;用于提醒用户注意某种情况;一个信息文本informativeTex…

linux c编程之“hello world”一

文章目录 hello world开始学习汇编文件 hello.s第1行第2行第3行第4行第5行第6行第7行第8行第9行第10行第11行第12行第13行 X [注]&#xff1a;环境说明&#xff1a; OS&#xff1a;CentOS 7 GCC&#xff1a; 4.8.5 其他环境下的结果可能不尽相同。 声明&#xff1a;本文是我的一…

10年前的显卡 NVIDIA_Quadro_FX_5800

NVIDIA_Quadro_FX_5800 主要参数核心频率610 MHzTurbo频率流处理单元240 个核心架构Tesla 2.0 共71款GPU代号GT200B生产工艺55 nmTDP功耗189W 内存参数内存频率1600 Mbps内存类型GDDR3内存位宽512 bit最大显存4 GB 参数补充晶体管数量1,400 million代工厂TSMC核心面积470 mm二…

python web 开发与 Node.js + Express 创建web服务器入门

目录 1. Node.js Express 框架简介 2 Node.js Express 和 Python 创建web服务器的对比 3 使用 Node.js Express 创建web服务器示例 3.1 Node.js Express 下载安装 3.2 使用Node.js Express 创建 web服务器流程 1. Node.js Express 框架简介 Node.js Express 是一种…

无涯教程-Android Intent Standard Extra Data函数

下表列出了各种重要的Android Intent Standard Extra Data。您可以查看Android官方文档以获取额外数据的完整列表- Sr.NoExtra Data & Description1 EXTRA_ALARM_COUNT 用作AlarmManager intents(意图)中的int Extra字段,以告诉正在调用的应用程序intents(意图)释放了多少…

java八股文面试[多线程]——指令重排序

关于a的操作&#xff0c;由原来的6个指令&#xff0c;变成了4个指令。 1. 指令重排序的介绍 1&#xff09;指令重排序的类型 在执行程序时为了提高性能&#xff0c;编译器和处理器常常会对指令做重排序。 重排序分三种类型&#xff1a;编译器优化的重排序 编译器在不改变单线…

深度分析:如何轻松掌握文件大小管理

大家好&#xff0c;今天我要与大家分享一个实用至极的脚本。简单易用&#xff0c;但效果却让人惊艳。它可以在几秒钟内完成文件大小的统计&#xff0c;并生成一份统计信息。 功能概览 完整性分析&#xff1a;一次性告诉你不同大小区间的文件分布&#xff0c;让你一目了然。 速…

【Unity】常见的角色移动旋转

在Unity 3D游戏引擎中&#xff0c;可以使用不同的方式对物体进行旋转。以下是几种常见的旋转方式&#xff1a; 欧拉角&#xff08;Euler Angles&#xff09;&#xff1a;欧拉角是一种常用的旋转表示方法&#xff0c;通过绕物体的 X、Y 和 Z 轴的旋转角度来描述物体的旋转。在Un…

七、MySQL(DML)如何往表中添加数据?

1、基础语法&#xff1a; &#xff08;1&#xff09;一对一添加数据&#xff1a; 一次只能添加一组数据&#xff0c;可以指定对应字段 insert into 表名 (字段名1,字段名2,……) values (数值1.数值2&#xff0c;……) &#xff08;2&#xff09;给全部字段添加数据&#…

vmware安装centos7虚拟机图文详解

1.打开vmware&#xff0c;点击创建新的虚拟机 2.选择自定义&#xff08;高级&#xff09;&#xff0c;下一步 3.下一步 4.选择稍后安装操作系统 5.操作系统选择linux&#xff0c;版本选择centos7 64位&#xff0c;下一步 6.创建文件夹&#xff0c;选择虚拟机存放的位置&#x…

Exactly Protocol 攻击事件原理分析

Exactly Protocol 攻击事件原理分析 8 月 18 日&#xff0c;Exactly protocol 遭遇黑客攻击&#xff0c;攻击者已获利约 1204 万美元。 安全公司Safful对此事件第一时间进行了技术分析&#xff0c;并总结了安全防范手段&#xff0c;希望后续项目可以引以为戒&#xff0c;共筑区…

企业小件固定资产怎么管理,有什么有效方式?

小件固定资产是指价值较低、使用寿命较短的固定资产&#xff0c;一般用于生产、制造、维修等领域。一些常见的行业中广泛使用小件固定资产&#xff1a;  制造业&#xff1a;小件固定资产在制造业中应用广泛&#xff0c;如机器设备、工具、测量仪器等。  建筑业&#xff1a;…