SpringBoot3 常用的第三方接口调用十种方式

环境:SpringBoot.3.3.0
在这里插入图片描述

  1. 简介
    在项目中调用第三方接口是日常开发中非常常见的。调用方式的选择通常遵循公司既定的技术栈和架构规范,以确保项目的一致性和可维护性。无论是RESTful API调用、Feign声明式HTTP客户端、Apache HttpClient等调用方式,每种方式都有其适用场景和优势,选择最适合的方式将有助于提高开发效率和系统性能。接下来将全面介绍10种第三方接口调用的实现方式。
  2. 实战案例
    2.1 JDK URL
URL url = URI.create("http://192.168.0.124:8000/api/data").toURL() ;
URLConnection connection = url.openConnection() ;
connection.setDoInput(true) ;
connection.setDoOutput(true) ;
InputStream inputStream = connection.getInputStream() ;
String ret = StreamUtils.copyToString(inputStream, StandardCharsets.UTF_8) ;
System.out.println(ret) ;

2.2 JDK HttpClient

URI uri = URI.create("http://192.168.0.124:8000/api/data") ;
HttpClient client = HttpClient.newBuilder()
.connectTimeout(Duration.ofSeconds(3))
.executor(Executors.newCachedThreadPool()
.build() ;
HttpRequest request = HttpRequest.newBuilder(uri).GET().build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString()) ;
System.out.println(response.body()) ;

2.3 Apache Http Client

HttpGet httpget = new HttpGet("http://192.168.0.124:8000/api/data") ;
CloseableHttpClient client = HttpClients.custom().build() ;
HttpClientResponseHandler<String> responseHandler = new BasicHttpClientResponseHandler() ; 
String ret = client.execute(httpget, responseHandler) ;
System.out.println(ret) ;

Apache HttpClient 5是一个支持HTTP/2、高度可定制、支持异步请求的开源HTTP工具包,提供了丰富的API和扩展特性。异步请求方式:

CloseableHttpAsyncClient client = HttpAsyncClients.custom().build() ;
client.start() ;
SimpleHttpRequest request = SimpleRequestBuilder.get().setHttpHost(HttpHost.create("http://192.168.0.124:8000")).setPath("/api/data").build() ;
FutureCallback<SimpleHttpResponse> callback = new FutureCallback<SimpleHttpResponse>() {@Overridepublic void failed(Exception ex) {System.err.printf("请求失败: %s%n", ex.getMessage()) ;}@Overridepublic void completed(SimpleHttpResponse result) {System.out.printf("当前线程: %s, 请求完成...%n", Thread.currentThread().getName()) ;}public void cancelled() {}
};
Future<SimpleHttpResponse> future = client.execute(request, callback) ;
System.out.println(new String(future.get().getBodyBytes(), StandardCharsets.UTF_8)) ;
client.close(CloseMode.GRACEFUL) ;

Apache Client功能还是非常强大的。
2.4 OkHttp
OkHttp是一个高效的HTTP客户端:
HTTP/2 支持允许对同一主机的所有请求共享一个套接字。
连接池可减少请求延迟(如果 HTTP/2 不可用)。
透明GZIP缩小了下载大小。
响应缓存可完全避免网络重复请求。
使用 OkHttp 非常简单。其请求/响应 API 采用流畅的构建器和不变性设计。它既支持同步阻塞调用,也支持带回调的异步调用。

URL url = URI.create("http://192.168.0.124:8000/api/data").toURL() ;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build() ;
try (Response response = client.newCall(request).execute()) {System.out.println(response.body().string()) ;
}

异步请求

URL url = URI.create("http://192.168.0.124:8000/api/data").toURL() ;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {public void onResponse(Call call, Response response) throws IOException {System.out.printf("当前线程: %s, 内容: %s%n", Thread.currentThread().getName(), response.body().string()) ;}public void onFailure(Call call, IOException e) {System.err.printf("请求失败: %s%n", e.getMessage()) ;}
}) ;

2.5 RestTemplate
RestTemplate是我们项目中最为常用的接口调用方式了,它以经典 Spring Template 类的形式为 HTTP 客户端库提供了高级 API。

RestTemplate restTemplate = new RestTemplate() ;
Map ret = restTemplate.getForObject(URI.create("http://192.168.0.124:8000/api/data"), Map.class) ;
System.out.println(ret) ;

通过RestTemplateBuilder可以对RestTemplate提供更多的配置。

RestTemplate restTemplate = new RestTemplateBuilder()// 设置超时时间.setConnectTimeout(Duration.ofSeconds(5)).setReadTimeout(Duration.ofSeconds(5))// 设置拦截器.interceptors(List.of()).build() ;
Map ret = restTemplate.getForObject(URI.create("http://192.168.0.124:8000/api/data"), Map.class) ;
System.out.println(ret) ;

注:默认情况下RestTemplate是通过JDK URL实现接口访问,我们可以自定义设置Apache Http或OKHttp实现。
2.6 WebClient
WebClient 是执行 HTTP 请求的非阻塞、反应式客户端。它在 Spring 5.0 中引入,提供了 RestTemplate 的替代方案,支持同步、异步和流场景。WebClient 支持以下功能:
非阻塞IO
反应流背压
用较少的硬件资源实现高并发
利用 Java 8 lambdas 的函数式流畅应用程序接口
支持同步和异步交互
向服务器传输数据流或从服务器向下传输数据流
WebClient 需要一个 HTTP 客户端库来执行请求。内置的支持包括:
Reactor Netty
JDK HttpClient
Jetty Reactive HttpClient
Apache HttpComponents
其他可以通过ClientHttpConnector插入。
如下示例:

WebClient client = WebClient.create("http://192.168.0.124:8000");
client.get().uri("/api/data")// 获取结果.retrieve().bodyToMono(String.class).subscribe(System.out::println) ;

更多配置,超时/错误


HttpClient httpClient = HttpClient.create().option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) ;
WebClient client = WebClient.builder().clientConnector(new ReactorClientHttpConnector(httpClient)).build() ;
client.get().uri("http://192.168.0.124:8000/api/data").retrieve().onStatus(HttpStatusCode::is4xxClientError, resp -> Mono.error(new RuntimeException("客户端请求错误"))).bodyToMono(String.class).subscribe(System.out::println) ;
System.in.read() ;

通过WebClient#builder可以进行更多的配置信息。
2.7 RestClient
RestClient是Spring6.1起添加的新的API。创建(或构建)后,RestClient 可由多个线程安全使用。

RestClient client = RestClient.create() ;
ParameterizedTypeReference<Map<String, Object>> bodyType = new ParameterizedTypeReference<Map<String, Object>>() {} ;
Map<String, Object> ret = client.get().uri(URI.create("http://192.168.0.124:8000/api/data")).retrieve().body(bodyType) ;

还可以通过RestClient#builder

RestClient client = RestClient.builder()// 设置请求Header.defaultHeader("Authorization", "Bearer eGvS0owCfhwkTcCHghNFMwOWODoz8WWXGhDT80R-EuBY7-EBNaMyZPsAZI0pmy3Zg7BTnoS3VTQlz_e7AKslpDL39trOYv_BY9uw5lZthsAi404iZnhWJz2p5v1Mm6Xb")// 设置拦截器.requestInterceptor((request, body, execution) -> execution.execute(request, body)).baseUrl("http://192.168.0.124:8000").build() ;

通过builder方式,你还可以进行更多的设置,具体查看API。
2.8 Http Interface
将 HTTP 服务定义为带有 @HttpExchange 方法的 Java 接口。你可以将这样的接口传递给 HttpServiceProxyFactory,创建一个代理,通过 HTTP 客户端(如 RestClient 或 WebClient)执行请求。

// 接口定义
public interface RemoteClient {@GetExchange("/api/data")Map<String, Object> queryInfo() ;
}
// 执行调用
RestClient restClient = RestClient.builder().baseUrl("http://192.168.0.124:8000").build() ;
RestClientAdapter adapter = RestClientAdapter.create(restClient) ;
HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build() ;
RemoteClient client = factory.createClient(RemoteClient.class);
System.out.println(client.queryInfo()) ;

上面调用通过RestClient进行,你也可以换成RestTemplate。

2.9 OpenFeign
注意这里是OpenFeign可不是Spring Cloud OpenFeign,Spring Cloud openfeign对OpenFeign进行了包装,所以在使用上是有差别的。

<!--feign 依赖-->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

示例代码

// 接口定义
public interface RemoteClient {@RequestLine("GET /api/data")Map<String, Object> queryInfo() ;
}
// 接口调用
RemoteClient client = Feign.builder().decoder(new JacksonDecoder()).target(RemoteClient.class, "http://192.168.0.124:8000") ;
Map<String, Object> ret = client.queryInfo() ;

OpenFeign还是至其他很多的注解,如:@Param,@Headers,@Body等。
2.10 Gateway Proxy
引入依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-gateway-mvc</artifactId>
</dependency>

代码示例

private URI uri = URI.create("http://192.168.0.124:8000");@GetMapping("/api")
public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {return proxy.uri(String.format("%s%s", uri.toString(), "/api/data")).get() ;
}

在上面的方法中通过ProxyExchange进行远程接口的调用。

Spring Boot 3太强:全新Controller接口定义方式

  1. 回顾定义接口方式

1.1 常规定义

@RestController
@RequestMapping("/user")
public class UsersController {@PostMapping("addUer")public Object save(@RequestBody Users users) {}
}

正确Servlet定义方法


@Component("/user/api")
public class ControllerHttpRequestHandler implements HttpRequestHandler {public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, 		      IOException {response.setContentType("text/html;charset=utf8");PrintWriter out = response.getWriter() ;out.print("<h1>你好,HttpRequestHandler</h1>") ;out.close() ;}
}

注意:接下来定义接口的方式需要在Spring6.0以上版本
2. 新的定义方式

从Spring6开始新增了一个新注解@HttpExchange。该注解将一个类或具体方法声明为HTTP 接口。接口的细节通过注解的属性以及方法参数定义。如下示例:


@HttpExchange("/persons")
interface PersonService {@GetExchange("/{id}")Person getPerson(@PathVariable Long id);@PostExchangevoid add(@RequestBody Person person) ;
}
// Person对象
@Data
@TableName("person")
@EqualsAndHashCode(callSuper = false)
public class Person {private Long id ;private String name ;
}

实现接口

@RestController
public class PersonController implements PersonService {public Person getPerson(@PathVariable Long id) {return new Person(id, "姓名 - " + id) ;}@ResponseStatus(HttpStatus.CREATED)public void add(@RequestBody Person person) {}
}

除了上面使用的@GetExchange和@PostExchange,还有下面这几个注解:
@DeleteExchange
@PatchExchange
@PutExchange
与@RequestMapping一样,这里的@HttpExchange注解也可以直接使用到方法上,如下:

@HttpExchange(value = "/list", method = "GET")
default List<Person> listPerson() {return List.of(new Person(100L, "mandala")) ;
} ;
  1. @HttpExchange真正目的
    @HttpExchange的主要目的是使用生成的代理抽象HTTP客户端代码。如下示例
    还是使用上面的PersonService接口定义,通过该接口生成代理类
@Configuration
public class PersonServiceClient {@BeanPersonService personServiceProxy() {RestClient restClient = RestClient.builder().baseUrl("http://192.168.13.124:8000").build();RestClientAdapter adapter = RestClientAdapter.create(restClient);HttpServiceProxyFactory factory = HttpServiceProxyFactory.builderFor(adapter).build();PersonService personService = factory.createClient(PersonService.class);return personService ;}}

将PersonService创建代理对象,通过JDK代理。注意:这里的RestClient必须使用Spring6.1以上版本,如果你不是那你可以换成RestTemplate.


@Resource
private PersonService personServiceProxy;@GetMapping("/persons")
public List<Person> list() {return this.personServiceProxy.listPerson() ;
}

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

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

相关文章

经典的带环链表问题(链表补充)

环形链表1 运用快慢指针的方法&#xff0c;fast ,slow从头节点出发&#xff0c;快指针走两步&#xff0c;慢指针走一步&#xff0c;若有环&#xff0c;快指针先进环&#xff0c;后续如果慢指针和快指针相遇&#xff0c;则链表带环。转换成了追击问题。 struct ListNode {int v…

重温react-01

创建react项目 // 第一步 npm install create-react-app -g // 第二步 create-react-app my-app目录介绍 my-app/README.md# 项目第三方依赖包node_modules/package.json# 一般用来存放静态依赖public/index.htmlfavicon.ico# 存放项目源代码&#xff0c;注意只有放在scr目录…

快速提升沟通能力:客服必备的话术技巧

在现在的这个互联网时代&#xff0c;各行业竞争日益激烈&#xff0c;而客服作为连接商家和消费者的桥梁&#xff0c;无疑是一个重要的岗位。可以说客服是一个极具挑战性的岗位&#xff0c;客服每天需要面对来自全国各地的客户&#xff0c;同时还要对不同地区、不同性格、不同需…

SQLServer 借助Navcate做定时备份的脚本

首先创建SQLServer链接&#xff0c;然后在Query标签种创建一个查询 查询内容如下 use ChengYuMES declare ls_time varchar(1000) declare ls_dbname varchar(1000) set ls_time convert(varchar, getdate(), 112) _ replace(convert(varchar, getdate(), 108), :, )-- 需…

LeetCode20.有效的括号

题目描述 分析 我们刚上来的思路可能是&#xff1a;找出这三种括号的个数 如果都是偶数 说明匹配 但是这里还有一个顺序问题 比如 " )( "这样是不匹配的&#xff01; 所以这种思路不可取&#xff01; 我们想 如果遇到左括号&#xff0c;把他读到一个顺序表中&#…

Redis应用:基于Redis实现排行榜、点赞、关注功能

文章目录 1. 环境准备2. 实现排行榜功能2.1 添加用户分数2.2 获取排行榜2.3 获取用户排名2.4 更新用户分数示例代码3. 实现点赞功能3.1 添加点赞3.2 获取点赞数3.3 检查用户是否点赞3.4 取消点赞示例代码4. 实现关注功能4.1 添加关注4.2 获取粉丝列表4.3 获取关注列表4.4 取消关…

【Pycharm】设置双击打开文件

概要 习惯真可怕。很多小伙伴用习惯了VsCode开发&#xff0c;或者其他一些开发工具&#xff0c;然后某些开发工具是单击目录文件就能打开预览的&#xff0c;而换到pycharm后&#xff0c;发现目录是双击才能打开预览&#xff0c;那么这个用起来就特别不习惯。 解决办法 只需一…

高清视频+AI算法,EasyCVR视频智能监控方案打造无死角吸烟行为检测

一、背景与意义 1、吸烟危害&#xff1a;吸烟不仅有害健康&#xff0c;而且在特定场所带来的安全隐患极大。据统计&#xff0c;全年火灾事故中有五分之一系抽烟引起&#xff0c;引发的人员伤亡和财产损失巨大。 2、政策与法规&#xff1a;为了保护公共安全&#xff0c;消除消…

解决方案︱视频孪生智慧高速解决方案

系统概述 在交通强国战略的指导下&#xff0c;我国政府高度重视以数字化为核心的智慧高速公路建设与发展。2023年9月&#xff0c;交通运输部印发了《交通运输部关于推进公路数字化转型加快智慧公路建设发展的意见》&#xff0c;强调到2035年&#xff0c;全面实现公路数字化转型…

java多线程概念

在Java多线程编程中有几个重要的概念&#xff0c;这些概念对于理解和编写正确的多线程应用程序至关重要&#xff1a; 1.线程&#xff08;Thread&#xff09;: 线程是操作系统能够进行运算调度的最小单位&#xff0c;Java通过线程实现并发执行。 2.进程&#xff08;Process&…

助力OTT大屏营销,酷开科技引领产业变革与创新

随着大屏电视产品的迭代&#xff0c;越来越多家庭以增换购等多种形式获得超高清、超大屏的智能电视&#xff0c;大屏的人均拥有量和渗透率进一步增加。在这种情况下&#xff0c;通过OTT应用为载体&#xff0c;将大量内容持续输送到大屏终端&#xff0c;从而形成了电视硬件普及与…

工控机与普通电脑的区别对于工业自动化应用至关重要

商用计算机和工业计算机之间的相似之处可能多于差异之处。工业电脑利用了消费技术领域的许多进步&#xff0c;但增加了工业应用所必需的软件、编程、确定性和连接性。 专业人士表示&#xff1a;“从增加内存到摩尔定律所描述的处理能力的指数级增长&#xff0c;工业控制必将受…

【C++】和【预训练模型】实现【机器学习】【图像分类】的终极指南

目录 &#x1f497;1. 准备工作和环境配置&#x1f495; &#x1f496;安装OpenCV&#x1f495; &#x1f496;安装Dlib&#x1f495; 下载并编译TensorFlow C API&#x1f495; &#x1f497;2. 下载和配置预训练模型&#x1f495; &#x1f496;2.1 下载预训练的ResNet…

pip 配置缓存路径

在windows操作平台&#xff0c;默认情况&#xff0c;pip下使用的系统目录 C:\Users\用名名称\AppData\Local\pip C盘是系统盘&#xff0c;如果常常使用pip安装会占用大量的空间很快就满&#xff0c;这时候就有必要变更一下缓存保存路径了。 pip 配置缓存路径&#xff1a; Win…

FM全网自动采集聚合影视搜索源码

源码介绍 FM 全网聚合影视搜索(响应式布局)&#xff0c;基于 TP5.1 开发的聚合影视搜索程序&#xff0c;本程序无数据库&#xff0c;本程序内置P2P 版播放器&#xff0c;承诺无广告无捆绑。片源内部滚动广告与本站无关,谨防上当受骗&#xff0c;资源搜索全部来自于网络。 环境…

效率翻倍!ComfyUI 必装的工作流+模型管理插件 Workspace Manager

一、Workspace Manager 安装方式 插件 Github 网址&#xff1a; https://github.com/11cafe/comfyui-workspace-manager 如果你没有安装 Workspace Manager 插件&#xff0c;可以通过以下 2 种方式安装&#xff1a; ① 通过 ComfyUI Manager 安装&#xff08;推荐&#xff0…

基于python-CNN卷积网络训练识别牛油果和猕猴桃-含数据集+pyqt界面

代码下载地址&#xff1a; https://download.csdn.net/download/qq_34904125/89383066 本代码是基于python pytorch环境安装的。 下载本代码后&#xff0c;有个requirement.txt文本&#xff0c;里面介绍了如何安装环境&#xff0c;环境需要自行配置。 或可直接参考下面博文…

LeetCode | 35.搜索插入位置

这套题可以直接遍历&#xff0c;找到第一个大于target的数并返回其位置即可&#xff0c;但是时间复杂度为 O ( n 2 ) O(n^2) O(n2)&#xff0c;题目中明确要求时间复杂度为 O ( l o g n ) O(logn) O(logn)&#xff0c;考虑二分查找算法&#xff0c;这道题就是标准的二分查找的一…

android 播放视频

播放视频文件 新建一个activity_main.xml文件&#xff0c;文件中放置了3个按钮&#xff0c;分别用于控制视频的播放、暂停和重新播放。另外在按钮的下面又放置了一个VideoView&#xff0c;稍后的视频就将在这里显示。 <LinearLayout xmlns:android"http://schemas.an…

浅谈数据管理架构 Data Fabric(数据编织)及其关键特征、落地应用

伴随着企业从数字化转型迈向更先进的数智化运营新阶段&#xff0c;对看数、用数的依赖越来越强&#xff0c;但数据的海量增长给数据管理带来一系列难题&#xff0c;如数据类型和加工链路日益复杂&#xff0c;数据存储和计算引擎更加分散&#xff0c;数据需求响应与数据质量、数…