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

news2025/1/12 1:10:37

环境: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>() {
  @Override
  public void failed(Exception ex) {
    System.err.printf("请求失败: %s%n", ex.getMessage()) ;
  }
  @Override
  public 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);

  @PostExchange
  void 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 {

  @Bean
  PersonService 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.coloradmin.cn/o/1820140.html

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

相关文章

Word同行内的文字如何左右分别对齐

先打开标尺&#xff08;视图-标尺&#xff09; 开右边&#xff0c;选一个制表位置&#xff0c;比如我选34 切回开始&#xff0c;点段落段落右下角 然后 然后 我修改为35&#xff08;因为“6月13日”总共3个字符&#xff09; 在文字中间按下Tab键&#xff0c;效果如下

Spring Boot 自定义校验注解

1.创建注解&#xff0c;可参考其他检验注解进行创建 2.创建校验类&#xff0c;需实现ContraintValidator并重写isValid方法,注意范型中表示给那个注解(State)提供校验及校验类型&#xff08;String&#xff09;,然后自行编写校验规则true为检验成功&#xff0c;false为失败 3.使…

网工内推 | 外企、上市公司运维工程师,有软考中高项证书优先

01 优尼派特&#xff08;苏州&#xff09;物流有限公司 &#x1f537;招聘岗位&#xff1a;软件运维测试工程师 &#x1f537;任职要求&#xff1a; 1、负责公司自主研发的软件售后服务工作, 包括软件的安装, 调试, 升级,培训, 参数配置, 需求与Bug的处理; 2、负责数据库升级及…

unDraw —— 免费且可定制的插画库,为您的设计注入灵魂

&#x1f3a8; unDraw —— 免费且可定制的插画库&#xff0c;为您的设计注入灵魂 在寻找能够完美融入您品牌风格的插画吗&#xff1f;unDraw&#xff0c;一个提供大量免费插画资源的网站&#xff0c;可能是您的理想选择&#xff01; &#x1f310; 网站特色 免费且开源 unDraw…

Doris集群管理工具Doris Manager安装使用(已踩坑)

背景&#xff1a;Doris集群管理、监控相对复杂&#xff0c;就想着有没有免费的、好用的管理工具&#xff0c;就发现了Doris Manager&#xff0c;给大家分享一下。 官网&#xff1a;https://docs.selectdb.com/docs/enterprise/cluster-manager-guide/deployment-guide/deployme…

【算法训练记录——Day28】

Day28——回溯算法Ⅳ 1.复原IP地址2.[全排列](https://leetcode.cn/problems/permutations/submissions/539240290/)3.[全排列Ⅱ](https://leetcode.cn/problems/permutations-ii/description/) ● 93.复原IP地址 ● 78.子集 ● 90.子集II 1.复原IP地址 思路&#xff1a;相当于…

【OceanBase DBA早下班系列】—— 性能问题如何 “拍CT“ (一键获取火焰图和扁鹊图)

1. 前言 最近接连遇到几个客户的环境在排查集群性能问题&#xff0c;总结了一下&#xff0c;直接教大家如何去获取火焰图、扁鹊图&#xff08;调用关系图&#xff09;&#xff0c;直击要害&#xff0c;就像是内脏的疾病去医院看病&#xff0c;上来先照一个CT&#xff0c;通过分…

HarmonyOS Next 系列之HTTP请求封装和Token持久化存储(四)

系列文章目录 HarmonyOS Next 系列之省市区弹窗选择器实现&#xff08;一&#xff09; HarmonyOS Next 系列之验证码输入组件实现&#xff08;二&#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现&#xff08;三&#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…

家用洗地机排行榜前十名:2024十大王牌机型精准种草

最近很多人都在问我洗地机相关的问题&#xff0c;不愧是改善家庭生活品质的“三神器”之一。洗地机依靠其清洁力和清洁效率吸引了越来越多的平时需要做家务人群的兴趣&#xff0c;为了解答大家关于洗地机的各种疑问&#xff0c;我把市面上目前非常火爆的洗地机型号和参数都进行…

探索未来通信的新边界:AQChat一款融合AI的在线匿名聊天

探索未来通信的新边界&#xff1a;AQChat一款融合AI的在线匿名聊天 在数字时代&#xff0c;即时通讯变得无处不在&#xff0c;但隐私和性能仍旧是许多用户和开发者关注的焦点。今天&#xff0c;我要介绍一个开创性的开源项目 —— AQChat&#xff0c;它不仅重定义了在线匿名聊…

Spring IoC注解

一、回顾反射机制 反射的调用三步&#xff1a;1&#xff09;获取类。2&#xff09;获取方法。3&#xff09;调用方法 调用方法&#xff1a;调用哪个对象&#xff0c;哪个方法&#xff0c;传什么参数&#xff0c;返回什么值。 方法&#xff08;Do&#xff09;类&#xff1a; …

eFuse电子保险丝,需要了解的技术干货来啦

热保险丝作为一种基本的电路保护器件&#xff0c;已经成功使用了150多年。热保险丝有效可靠、易用&#xff0c;具有各种不同的数值和版本&#xff0c;能够满足不同的设计目标。然而&#xff0c;对于寻求以极快的速度切断电流的设计人员来说&#xff0c;热保险丝不可避免的缺点就…

【高校科研前沿】北京大学赵鹏军教授团队在Nature Communications发文:揭示城市人群移动的空间方向性

文章简介 论文名称&#xff1a;Unravelling the spatial directionality of urban mobility 第一作者及单位&#xff1a;赵鹏军&#xff08;教授|第一作者|北京大学&#xff09;&王浩&#xff08;博士生|共同一作|北京大学&#xff09;; 通讯作者及单位&#xff1a;赵鹏军…

SCI二区|鲸鱼优化算法(WOA)原理及实现【附完整Matlab代码】

目录 1.背景2.算法原理2.1算法思想 3.结果展示4.参考文献5.代码获取 1.背景 2016年&#xff0c;S Mirjalili受到自然界座头鲸社会行为启发&#xff0c;提出了鲸鱼优化算法&#xff08;Whale Optimization Algorithm, WOA&#xff09;。 2.算法原理 WOA模拟了座头鲸的社会行为…

会议室占用全透明化,内幕大揭秘!

会议室管理的现实问题 &#x1f3e2; 有限的会议室资源: 在现代办公环境中&#xff0c;会议室资源通常是有限的&#xff0c;特别是在大型企业或繁忙的办公楼内&#xff0c;会议室的预订和管理变得尤为重要。 &#x1f552; 复杂的预订流程: 常常会出现会议室预订流程繁琐、不…

2024年6月14日 十二生肖 今日运势

小运播报&#xff1a;2024年6月14日&#xff0c;星期五&#xff0c;农历五月初九 &#xff08;甲辰年庚午月己酉日&#xff09;&#xff0c;法定工作日。今天世界献血日&#xff0c;捐献新鲜血液&#xff0c;挽救更多生命&#xff0c;每位献血者都是英雄&#xff01; 红榜生肖…

【论文复现|智能算法改进】基于改进鲸鱼优化算法的移动机器人多目标点路径规划

目录 1.算法原理2.数学模型3.改进点4.结果展示5.参考文献6.代码获取 1.算法原理 SCI二区|鲸鱼优化算法&#xff08;WOA&#xff09;原理及实现【附完整Matlab代码】 2.数学模型 使用 A* 算法生成所有目标点之间的距离矩阵U: U [ d 1 − 1 d 1 − 2 d 1 − 3 ⋯ d 1 − i d…

【JVM】JVisualVM的介绍、使用和GC过程

VisualVM介绍 VisualVM 是Netbeans的profile子项目&#xff0c;已在JDK6.0 update 7 中自带&#xff0c;能够监控线程&#xff0c;内存情况&#xff0c;查看方法的CPU时间和内存中的对 象&#xff0c;已被GC的对象&#xff0c;反向查看分配的堆栈(如100个String对象分别由哪几…

C#——类和对象详情

类和对象 类 类是一种数据结构&#xff0c;它可以包含数据成员&#xff08;常量和字段&#xff09;、函数成员&#xff08;方法、属性、事件、索引器、运算符、实例构造函数、静态构造函数和析构函数&#xff09;以及嵌套类型。类类型支持继承&#xff0c;继承是一种机制&…

【第9章】“基础工作流”怎么用?(图生图/局部重绘/VAE/更多基础工作流)ComfyUI基础入门教程

🎁引言 学到这里,大家是不是会比较纠结,好像还在持续学习新的东西,未来还有多少基础的东西要学习,才能正常使用ComfyUI呢? 这其实需要转变一个心态。 AI绘画还处于一个快速迭代的过程,隔三岔五的就会有很多新技术、新模型出现,ComfyUI目前同样处于一个快速更新的阶…