【怎样基于Okhttp3来实现各种各样的远程调用,表单、JSON、文件、文件流等待】

news2024/9/28 9:34:03

HTTP客户端工具 okhttp3 form/json/multipart

  • 提供表达、json、混合表单、混合表单文件流传输等HTTP请求调用
  • 支持自定义配置默认客户端,参数列表如下:
     okhtt3.config.connectTimeout 连接超时,TimeUnit.SECONDS
     okhtt3.config.readTimeOut 读取超时,TimeUnit.SECONDS
     okhtt3.config.writeTimeOut 写超时,TimeUnit.SECONDS
     okhtt3.config.callTimeout 流程超时,TimeUnit.SECONDS
  • 写一个组件,第一步首先就是定义功能接口啦
public interface Okhttp3 {
    String postRequest(OkHttpClient httpClient, RequestBody requestBody, String url, Map<String, String> headers) throws IOException;
}

  • 然后就是注入我们自定义的okhttpClient,自定义配置参数如下:
@ConfigurationProperties(prefix = "okhtt3.config")
public class DefaultOkhttp3ClientProperties {
    private Integer connectTimeout = 2;
    private Integer readTimeout = 10;
    private Integer writeTimeout = 10;
    private Integer callTimeOut = 20;

    public Integer getConnectTimeout() {
        return connectTimeout;
    }

    public void setConnectTimeout(Integer connectTimeout) {
        this.connectTimeout = connectTimeout;
    }

    public Integer getReadTimeout() {
        return readTimeout;
    }

    public void setReadTimeout(Integer readTimeout) {
        this.readTimeout = readTimeout;
    }

    public Integer getWriteTimeout() {
        return writeTimeout;
    }

    public void setWriteTimeout(Integer writeTimeout) {
        this.writeTimeout = writeTimeout;
    }

    public Integer getCallTimeOut() {
        return callTimeOut;
    }

    public void setCallTimeOut(Integer callTimeOut) {
        this.callTimeOut = callTimeOut;
    }
}

  • 注入自定义客户端,支持HTTP/HTTPS
@Configuration
@EnableConfigurationProperties(DefaultOkhttp3ClientProperties.class)
public class Okhttp3Configuration {

    @Bean
    public DefaultOkhttp3 defaultOkhttp3() {
        return new DefaultOkhttp3();
    }

    @Bean
    @ConditionalOnMissingBean
    public OkHttpClient okHttpClient(@Autowired DefaultOkhttp3ClientProperties defaultOkhttp3ClientProperties) {
        X509TrustManager x509TrustManager = trustManager();
        final SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{x509TrustManager}, new java.security.SecureRandom());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.sslSocketFactory(sslSocketFactory, x509TrustManager);
        builder.hostnameVerifier((hostname, session) -> true);
        builder.connectTimeout(defaultOkhttp3ClientProperties.getConnectTimeout(), TimeUnit.SECONDS);
        builder.readTimeout(defaultOkhttp3ClientProperties.getReadTimeout(), TimeUnit.SECONDS);
        builder.writeTimeout(defaultOkhttp3ClientProperties.getWriteTimeout(), TimeUnit.SECONDS);
        builder.callTimeout(defaultOkhttp3ClientProperties.getCallTimeOut(), TimeUnit.SECONDS);
        return builder.build();
    }

    private static X509TrustManager trustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] chain, String authType) {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] chain, String authType) {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }
        };
    }
}
  • 下面就是我们应对何种复杂业务的实现了,简单的表单请求、JSON请求,到文件上传,接着就是文件流传输等等,针对大文件的传入,直接通过网络流传递,避免内存问题。下面是各种需求的实现
public class DefaultOkhttp3 implements Okhttp3 {

    @Override
    public String postRequest(OkHttpClient httpClient, RequestBody requestBody, String url, Map<String, String> headers) throws IOException {
        Call call = makeRequestCall(httpClient, requestBody, url, headers);
        return postRequest(call);
    }

    public String buildUrlIncludeQueryParams(String url, Map<String, String> queryParams) {
        HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(url)).newBuilder();
        queryParams.forEach(builder::addQueryParameter);
        return builder.build().toString();
    }

    public RequestBody buildJsonRequestBody(String json) {
        return RequestBody.create(json, MediaType.parse("application/json; charset=utf-8"));
    }

    public RequestBody buildFormRequestBody(Map<String, String> formBody) {
        FormBody.Builder builder = new FormBody.Builder();
        formBody.forEach(builder::add);
        return builder.build();
    }

    public RequestBody buildMultipartRequestBodyOfFiles(Map<String, String> formBody, Map<String, FilePat> fileMap) {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        formBody.forEach(builder::addFormDataPart);
        fileMap.forEach((k, v) -> builder.addFormDataPart(k, v.getFile().getName(), RequestBody.create(v.getFile(), v.getMediaType())));
        return builder.build();
    }

    public RequestBody buildMultipartFilesRequestBody(Map<String, String> formBody, Map<String, MultipartFile> fileMap) {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        formBody.forEach(builder::addFormDataPart);
        fileMap.forEach((k, v) -> {
            try {
                builder.addFormDataPart(k, v.getName(), RequestBody.create(v.getBytes(), MediaType.get(Objects.requireNonNull(v.getContentType()))));
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        });
        return builder.build();
    }

    public RequestBody buildMultipartFilesInputStreamRequestBody(Map<String, String> formBody, Map<String, MultipartFile> fileMap) {
        MultipartBody.Builder builder = new MultipartBody.Builder();
        builder.setType(MultipartBody.FORM);
        formBody.forEach(builder::addFormDataPart);
        fileMap.forEach((k, v) -> {
            builder.addFormDataPart(k, v.getOriginalFilename(), new RequestBody() {
                @NotNull
                @Override
                public MediaType contentType() {
                    return MediaType.get(Objects.requireNonNull(v.getContentType()));
                }

                @Override
                public long contentLength() {
                    return v.getSize();
                }

                @Override
                public void writeTo(@NotNull BufferedSink bufferedSink) throws IOException {
                    try (InputStream inputStream = v.getInputStream()) {
                        byte[] buffer = new byte[2048];
                        int len;
                        while ((len = inputStream.read(buffer)) != -1) {
                            bufferedSink.write(buffer, 0, len);
                            bufferedSink.flush();
                        }
                    }
                }
            });
        });
        return builder.build();
    }

    public static class FilePat {
        private File file;
        private MediaType mediaType;

        public File getFile() {
            return file;
        }

        public void setFile(File file) {
            this.file = file;
        }

        public MediaType getMediaType() {
            return mediaType;
        }

        public void setMediaType(MediaType mediaType) {
            this.mediaType = mediaType;
        }
    }


    private Call makeRequestCall(OkHttpClient httpClient, RequestBody body, String reqUrl, Map<String, String> headers) {
        Request.Builder reqBuilder = new Request.Builder();
        reqBuilder.url(reqUrl).post(body);
        if (headers != null && !headers.isEmpty()) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                reqBuilder.header(entry.getKey(), entry.getValue());
            }
        }
        return httpClient.newCall(reqBuilder.build());
    }

    private String postRequest(Call call) throws IOException {
        try (Response resp = call.execute()) {
            ResponseBody rb = resp.body();
            if (resp.code() != 200) {
                String msg = null;
                if (rb != null) {
                    msg = rb.string();
                }
                throw new IOException("http code: " + resp.code() + (msg != null ? ",msg:" + msg : ""));
            }
            if (rb == null) {
                throw new IllegalStateException("http response body is null");
            }
            return rb.string();
        }
    }

}

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

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

相关文章

Linux进程的学习(持续更新)

冯诺依曼体系结构 概念&#xff1a; 冯・诺依曼体系结构是一种计算机体系结构&#xff0c;由美籍匈牙利科学家约翰・冯・诺依曼提出。它奠定了现代计算机的基本结构。 计算机分为以上五大部件组成&#xff1a; 输入设备&#xff1a;键盘&#xff0c;鼠标&#xff0c;网卡&…

【前端框架对比和选择】React 与 Vue 框架设计思路对比

框架总览 前端框架繁多&#xff0c;在学习的时候也会陷入困惑&#xff0c;我们应该抓住最主流的内容 Vue/React&#xff0c;深入底层&#xff0c;尝试揣摩框架作者的设计思路&#xff0c;开阔前端培训自己的视野&#xff0c;大家也不要把自己限制在框架之中&#xff0c;认为工…

Python | Leetcode Python题解之第442题数组中重复的数据

题目&#xff1a; 题解&#xff1a; class Solution:def findDuplicates(self, nums: List[int]) -> List[int]:ans []for x in nums:x abs(x)if nums[x - 1] > 0:nums[x - 1] -nums[x - 1]else:ans.append(x)return ans

气膜健身馆:提升运动体验与健康的理想选择—轻空间

近年来&#xff0c;气膜健身馆作为一种新兴的运动场所&#xff0c;正逐渐受到越来越多健身爱好者的青睐。这种独特的建筑形式不仅提供了良好的运动环境&#xff0c;更在健康和运动表现上展现出诸多优势。 优越的空气质量 气膜结构的核心技术通过内外气压差形成稳定的气膜&#…

Mysql调优之索引优化(四)

一、mysql索引结构B树原理 B树开始就是n树&#xff0c;不是二叉树 B树的非叶子结点存储了数据&#xff0c;导致层级会很深&#xff0c;每一层又有数据又有索引。 B树只有叶子结点存储数据&#xff0c;其余都是存储索引&#xff0c;增加了每层存取索引的数量&#xff08;3层结构…

Linux开源网络:高性能数据平面

数据平面的性能在很大程度上取决于网络 I/O 的性能&#xff0c;而网络数据包从网卡到用户空间的应用程序需要经历多个阶段&#xff0c;本文从数据平面基础到NFV&#xff0c;NFC基础设施再到OVS-DPDK VPP进行概论上的描述。 部分内容来源于《Linux开源网络全栈详解&#xff1a;从…

助力商用车远程检测维修,贝锐向日葵携手上海星融打造标杆案例

商用车是一个成熟且复杂的领域&#xff0c;伴随着数字化与信息化的不断发展&#xff0c;商用车领域的上下游厂商也正在积极的拥抱数字化&#xff0c;应用信息化工具所带来的“红利”&#xff0c;来提供更高质量的产品与服务&#xff0c;其中比较典型的代表&#xff0c;就是在商…

②EtherCAT转Modbus485RTU网关多路同步高速采集无需编程串口服务器

EtherCAT转Modbus485RTU网关多路同步高速采集无需编程串口服务器https://item.taobao.com/item.htm?ftt&id798036415719 EtherCAT 串口网关 EtherCAT 转 RS485 &#xff08;接上一章&#xff09; 自由协议通信步骤 &#xff08;以MS-A2-1041为例&#xff09; 接收与…

OSM转出shp的数据为啥有那么多空属性

当打开我们提供的OSM转出SHP格式的电力或其它类型数据可能会看到很多空属性&#xff0c;这个原因其实如果是写程序的人会很容易理解&#xff0c;但一般人可能理解起来比较困难。我试着解释一下&#xff0c;能理解就理解。不能理解您就记住这是格式转换产生的冗余数据就行&#…

【保姆级教程】批量下载Pexels视频Python脚本(以HumanVid数据集为例)

目录 方案一&#xff1a;转换链接为download模式 方案二&#xff1a;获取源链接后下载 附录&#xff1a;HumanVid链接 方案一&#xff1a;转换链接为download模式 将下载链接的后缀加入 /download 然后用下面的脚本下载&#xff1a; import argparse import json import o…

react 状态管理

Redux Redux是React中常用的状态管理组件&#xff0c;类似于Vue中的Pinia(Vuex)&#xff0c;可以独立于框架运行 作用&#xff1a; 通过集中管理的方式管理应用的状态 配套工具 在react中使用redux&#xff0c;官方要求按照两个插件&#xff0c;Redux Toolkit 和 react-red…

【补充】倒易点阵基本性质

&#xff08;1&#xff09;任意倒易矢量 r h k l ∗ h a ∗ k b ∗ l c ∗ \mathbf{r}_{hkl}^* h\mathbf{a^*} k\mathbf{b^*} l\mathbf{c^*} rhkl∗​ha∗kb∗lc∗必然垂直于正空间中的(hkl)晶面。 正空间中的(hkl)晶面的法向是[hkl]&#xff0c;和坐标轴的交点为A、B、…

基于yolov8的辣椒缺陷检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

阅读本文请注意该系统设计是针对单个辣椒进行缺陷检测&#xff0c;具体可以在训练数据集查看数据集具体情况 【算法介绍】 基于YOLOv8的辣椒缺陷检测系统是一种利用深度学习技术&#xff0c;特别是YOLOv8算法&#xff0c;来自动识别和检测辣椒表面缺陷的先进系统。YOLOv8作为…

Serilog文档翻译系列(六) - 可用的接收器、增强器、格式化输出

01、提供的接收器 Serilog 使用接收器将日志事件以各种格式写入存储。许多接收器由更广泛的 Serilog 社区开发和支持&#xff1b;可以通过在 NuGet 上搜索 serilog 标签找到。 02、增强器 日志事件可以通过多种方式增强属性。通过 NuGet 提供了一些预构建的增强器&#xff…

openEuler 20.03,22.03 一键部署Oracle21c zip

oracle21c前言 Oracle开发的关系数据库产品因性能卓越而闻名,Oracle数据库产品为财富排行榜上的前1000家公司所采用,许多大型网站也选用了Oracle系统,是世界最好的数据库产品。此外,Oracle公司还开发其他应用程序和软件。同时,Oracle在英语里还是“神谕”的意思,意为“替…

十进制与ip地址转换公式

1、十进制转为ip地址公式 TEXT(INT(C2/16777216),“0”)&“.”&TEXT(INT((C2-INT(C2/16777216)*16777216)/65536),“0”)&“.”&TEXT(INT((C2-INT(C2/16777216)*16777216-INT((C2-INT(C2/16777216)*16777216)/65536)*65536)/256),“0”)&“.”&TEXT(MO…

SpringBoot的概述与搭建

目录 一.SpringBoot的概述 二.SpringBoot 特点 三.SpringBoot 的核心功能 3.1起步依赖 3.2自动配置 四.SpringBoot 开发环境构建 五.SpringBoot 配置文件 六.SpringBoot数据访问管理 七.springboot注解 八.springboot集成mybatis 九.springboot全局异常捕获与处理 一…

数据集-目标检测系列-豹子 猎豹 检测数据集 leopard>> DataBall

数据集-目标检测系列-豹子 猎豹 检测数据集 leopard>> DataBall 数据集-目标检测系列-豹子 猎豹 检测数据集 leopard 数据量&#xff1a;5k 想要进一步了解&#xff0c;请联系。 DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#x…

C#测试调用FreeSpire.PDFViewer浏览PDF文件

Free Spire.PDFViewer是商业版Spire.PDFViewer的社区版本&#xff0c;支持以控件形式打开并查看PDf文件&#xff0c;但由于是免费版本&#xff0c;存在使用限制&#xff0c;打开的PDF文档只显示前10页内容。如果日常操作的pdf文件都不超过10页&#xff0c;可以考虑使用Free Spi…

我是如何将 Java 基础 docker 镜像大小从 674Mb 优化到 58Mb的

我是如何将 Java 基础 docker 镜像大小从 674Mb 优化到 58Mb的 如果您是 Java 开发人员&#xff0c;并且正在使用 Docker 打包应用程序&#xff0c;您可能已经注意到&#xff0c;即使是“hello world”类型的项目&#xff0c;最终镜像的大小也可能非常大。在本文中&#xff0c…