当前位置: 首页 > news >正文

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

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

  • 提供表达、json、混合表单、混合表单文件流传输等HTTP请求调用
  • 支持自定义配置默认客户端,参数列表如下:
     okhtt3.config.connectTimeout 连接超时,TimeUnit.SECONDSokhtt3.config.readTimeOut 读取超时,TimeUnit.SECONDSokhtt3.config.writeTimeOut 写超时,TimeUnit.SECONDSokhtt3.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 {@Beanpublic DefaultOkhttp3 defaultOkhttp3() {return new DefaultOkhttp3();}@Bean@ConditionalOnMissingBeanpublic 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() {@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType) {}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType) {}@Overridepublic X509Certificate[] getAcceptedIssuers() {return new X509Certificate[0];}};}
}
  • 下面就是我们应对何种复杂业务的实现了,简单的表单请求、JSON请求,到文件上传,接着就是文件流传输等等,针对大文件的传入,直接通过网络流传递,避免内存问题。下面是各种需求的实现
public class DefaultOkhttp3 implements Okhttp3 {@Overridepublic 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@Overridepublic MediaType contentType() {return MediaType.get(Objects.requireNonNull(v.getContentType()));}@Overridepublic long contentLength() {return v.getSize();}@Overridepublic 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.lryc.cn/news/447991.html

相关文章:

  • excel统计分析(3): 一元线性回归分析
  • 搜索引擎onesearch3实现解释和升级到Elasticsearch v8系列(一)-概述
  • ArcGIS Pro高级地图可视化—双变量符号地图
  • rust属性宏
  • 《pyqt+open3d》open3d可视化界面集成到qt中
  • 学习记录:js算法(四十七):相同的树
  • 使用Hutool-poi封装Apache POI进行Excel的上传与下载
  • asp.net core grpc快速入门
  • 拿到一个新项目,如何开展测试
  • pre-commit 的配置文件
  • 5G-A和F5G-A,对于AI意味着什么?
  • vue-实现rtmp直播流
  • 论文阅读【时间序列】ModerTCN (ICLR2024)
  • Robot Operating System——二维平面中的位置和方向
  • 一文带你读懂分库分表,分片,Sharding的许多概念
  • 算法实战(五):如何用学过的数据结构和算法实现一个短网址系统?
  • Python 环境搭建
  • uniapp vue3 使用echarts绘制图表 柱状图等
  • 字符串处理的艺术:深入探索charAt(), indexOf(), nextLine(), 和 next() 的应用与组合
  • C#八股总结
  • iOS 中的 sqlite-shm 和 sqlite-wal 文件丢失
  • ubuntu22上C/C++程序使用weston+wayland+OpenGLES渲染
  • 打点 - 泛微 E-Cology WorkflowServiceXml
  • Go语言接口与多态
  • 【ADC】SAR 型 ADC 和 ΔΣ ADC 的选型决策方法
  • 探探Java与python中的闭包
  • LD2 Scalable Heterophilous Graph Neural Network with Decoupled Embeddings
  • 【Mysql】Mysql数据库基本操作-------DDL(上)
  • MySQL知识点复习 - 常用的日志类型
  • 基于PHP+MySQL组合开发地方门户分类信息网站源码系统 带完整的安装代码包以及搭建部署教程