Spring Boot 调用外部接口的三种姿势

news/2025/3/25 15:44:48/文章来源:https://www.cnblogs.com/haoyul/p/18788573

引言

在当今数字化时代,Java 开发技术在软件开发领域占据着重要地位,而 Spring Boot 作为 Java 开发中备受青睐的框架之一,其简洁、高效的特点深受开发者喜爱。对于初学者来说,掌握 Spring Boot 调用外部接口的方法是迈向 Java 开发世界的重要一步。在实际项目开发中,我们常常需要与外部系统进行数据交互,调用各种外部接口来获取所需的信息或实现特定的功能。本文将详细介绍 Spring Boot 调用外部接口的三种方式,帮助初学者轻松应对这一常见的开发需求,提升开发技能,为今后的 Java 开发之路打下坚实的基础。

方式一:使用 RestTemplate 

1. RestTemplate 简介

RestTemplate 是 Spring 提供的一个用于访问 HTTP 服务的客户端,它简化了与 HTTP 服务的通信,提供了多种便捷的方法来发送请求和处理响应。在 Spring Boot 项目中,我们可以很方便地使用 RestTemplate 来调用外部接口。

2. 使用步骤

  1. 引入依赖

在 Spring Boot 项目的 pom.xml 文件中,确保已引入 Spring Web 依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
  1. 创建 RestTemplate 实例

在需要调用外部接口的类中,创建 RestTemplate 实例:

import org.springframework.web.client.RestTemplate;public class MyService {private RestTemplate restTemplate = new RestTemplate();}
  1. 发送请求并处理响应

使用 RestTemplate 提供的方法发送请求,例如发送一个 GET 请求:

import org.springframework.web.client.RestTemplate;public class MyService {private RestTemplate restTemplate = new RestTemplate();public void callExternalApi() {String url = "https://api.example.com/data";String response = restTemplate.getForObject(url, String.class);System.out.println("Response: " + response);}}
 

在上述代码中,getForObject 方法用于发送 GET 请求,并将响应结果转换为指定的类型(这里为 String 类型)。

3. 配置与优化

  1. 设置超时时间

可以通过自定义 RestTemplate 的 ClientHttpRequestFactory 来设置超时时间:

import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;public class MyService {public MyService() {RestTemplate restTemplate = new RestTemplate();HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();factory.setConnectTimeout(5000); // 设置连接超时时间为 5000 毫秒factory.setReadTimeout(5000); // 设置读取超时时间为 5000 毫秒
        restTemplate.setRequestFactory(factory);}}

 

 
  1. 添加请求头

如果需要在请求中添加自定义的请求头,可以使用 HttpHeaders 和 HttpEntity :

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;publicclass MyService {public void callExternalApiWithHeaders() {RestTemplate restTemplate = new RestTemplate();HttpHeaders headers = new HttpHeaders();headers.add("Authorization", "Bearer " + "your_token");HttpEntity<String> entity = new HttpEntity<>(headers);String url = "https://api.example.com/protected-data";ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class);System.out.println("Response: " + response.getBody());}}

 

 

4. 实际案例

假设我们需要调用一个天气查询接口,获取指定城市的天气信息。接口地址为 https://api.weather.com/v3/weather/forecast/daily ,需要传递城市参数和 API 密钥。以下是使用 RestTemplate 实现的代码:

import org.springframework.web.client.RestTemplate;public class WeatherService {private RestTemplate restTemplate = new RestTemplate();public void getWeatherForecast(String city) {String apiKey = "your_api_key";String url = "https://api.weather.com/v3/weather/forecast/daily?q=" + city + "&apiKey=" + apiKey;String response = restTemplate.getForObject(url, String.class);System.out.println("Weather Forecast: " + response);}}

 

 

通过以上代码,我们可以轻松地调用天气查询接口,获取指定城市的天气预报信息。

方式二:使用 WebClient 

1. WebClient 简介

WebClient 是 Spring 5 引入的一个响应式 Web 客户端,它基于 Project Reactor 实现了响应式编程模型,可以更高效地处理高并发场景下的 HTTP 请求。与 RestTemplate 不同,WebClient 采用函数式编程风格,提供了更灵活的请求构建和响应处理方式。

2. 使用步骤

  1. 引入依赖

在 Spring Boot 项目的 pom.xml 文件中,引入 Spring WebFlux 依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

 

 
  1. 创建 WebClient 实例

在需要调用外部接口的类中,创建 WebClient 实例:

import org.springframework.web.reactive.function.client.WebClient;public class MyService {private WebClient webClient = WebClient.create();}
 
  1. 发送请求并处理响应

使用 WebClient 构建请求并处理响应,例如发送一个 GET 请求:

import org.springframework.web.reactive.function.client.WebClient;publicclass MyService {private WebClient webClient = WebClient.create();public void callExternalApi() {String url = "https://api.example.com/data";webClient.get().uri(url).retrieve().bodyToMono(String.class).subscribe(response -> System.out.println("Response: " + response));}}
 

在上述代码中,get 方法用于指定请求方法为 GET,uri 方法用于设置请求的 URI,retrieve 方法用于发送请求并获取响应,bodyToMono 方法用于将响应体转换为指定的类型(这里为 String 类型),subscribe 方法用于订阅响应并处理结果。

3. 高级用法

  1. 请求体的构建

如果需要发送 POST 请求并传递请求体,可以使用 bodyValue 方法:

import org.springframework.web.reactive.function.client.WebClient;publicclass MyService {private WebClient webClient = WebClient.create();public void callExternalApiWithBody() {String url = "https://api.example.com/data";MyRequestData requestData = new MyRequestData("value1", "value2");webClient.post().uri(url).bodyValue(requestData).retrieve().bodyToMono(String.class).subscribe(response -> System.out.println("Response: " + response));}publicstaticclass MyRequestData {private String field1;private String field2;public MyRequestData(String field1, String field2) {this.field1 = field1;this.field2 = field2;}// getter 和 setter 方法
    }}
 
  1. 响应数据的流式处理

对于大文件或大数据量的响应,可以使用 bodyToFlux 方法进行流式处理:

import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;publicclass MyService {private WebClient webClient = WebClient.create();public void callExternalApiWithStream() {String url = "https://api.example.com/large-data";webClient.get().uri(url).retrieve().bodyToFlux(String.class).subscribe(data -> System.out.println("Processing data: " + data));}}
 

4. 实际案例

假设我们需要调用一个用户信息查询接口,根据用户 ID 获取用户详细信息。接口地址为 https://api.user.com/v1/users/{id} ,需要传递用户 ID 参数。以下是使用 WebClient 实现的代码:

import org.springframework.web.reactive.function.client.WebClient;publicclass UserService {private WebClient webClient = WebClient.create();public void getUserInfo(String userId) {String url = "https://api.user.com/v1/users/" + userId;webClient.get().uri(url).retrieve().bodyToMono(String.class).subscribe(response -> System.out.println("User Info: " + response));}}
 

通过以上代码,我们可以使用 WebClient 调用用户信息查询接口,获取指定用户的信息。

方式三:使用 HttpClient 

1. HttpClient 简介

HttpClient 是 Apache HttpComponents 项目中的一个组件,它是一个功能强大的 HTTP 客户端库,可以用于发送 HTTP 请求和接收响应。在 Spring Boot 项目中,我们可以集成 HttpClient 来调用外部接口,它具有高度的灵活性和可定制性。

2. 使用步骤

  1. 引入依赖

在 Spring Boot 项目的 pom.xml 文件中,引入 HttpClient 依赖:

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.13</version>
</dependency>
  1. 创建 HttpClient 实例

在需要调用外部接口的类中,创建 HttpClient 实例:

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;public class MyService {private CloseableHttpClient httpClient = HttpClients.createDefault();}
 
  1. 发送请求并处理响应

使用 HttpClient 发送请求并处理响应,例如发送一个 GET 请求:

import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;publicclass MyService {private CloseableHttpClient httpClient = HttpClients.createDefault();public void callExternalApi() {String url = "https://api.example.com/data";HttpGet httpGet = new HttpGet(url);try {CloseableHttpResponse response = httpClient.execute(httpGet);String responseBody = EntityUtils.toString(response.getEntity());System.out.println("Response: " + responseBody);response.close();} catch (Exception e) {e.printStackTrace();}}}
 

在上述代码中,HttpGet 类用于创建 GET 请求,httpClient.execute 方法用于发送请求并获取响应,EntityUtils.toString 方法用于将响应实体转换为字符串。

3. 配置与优化

  1. 连接管理

可以通过自定义 HttpHost 和 HttpConnectionConfig 来管理连接:

import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;publicclass MyService {public MyService() {PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();connectionManager.setMaxTotal(100); // 设置最大连接数connectionManager.setDefaultMaxPerRoute(20); // 设置每个路由的最大连接数CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();}}
 
  1. 请求配置

可以使用 RequestConfig 来设置请求的超时时间、重试次数等参数:

import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;publicclass MyService {private CloseableHttpClient httpClient = HttpClients.createDefault();public void callExternalApiWithConfig() {String url = "https://api.example.com/data";RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(5000) // 设置连接超时时间为 5000 毫秒.setSocketTimeout(5000) // 设置读取超时时间为 5000 毫秒
            .build();HttpGet httpGet = new HttpGet(url);httpGet.setConfig(requestConfig);try {CloseableHttpResponse response = httpClient.execute(httpGet);String responseBody = EntityUtils.toString(response.getEntity());System.out.println("Response: " + responseBody);response.close();} catch (Exception e) {e.printStackTrace();}}}
 

4. 实际案例

假设我们需要调用一个订单查询接口,获取指定订单的详细信息。接口地址为 https://api.order.com/v1/orders/{id} ,需要传递订单 ID 参数。以下是使用 HttpClient 实现的代码:

import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;publicclass OrderService {private CloseableHttpClient httpClient = HttpClients.createDefault();public void getOrderInfo(String orderId) {String url = "https://api.order.com/v1/orders/" + orderId;HttpGet httpGet = new HttpGet(url);try {CloseableHttpResponse response = httpClient.execute(httpGet);String responseBody = EntityUtils.toString(response.getEntity());System.out.println("Order Info: " + responseBody);response.close();} catch (Exception e) {e.printStackTrace();}}}

 

 

通过以上代码,我们可以使用 HttpClient 调用订单查询接口,获取指定订单的信息。

三种方式的对比与选择 

特性RestTemplateWebClientHttpClient
编程模型 阻塞式 响应式 阻塞式
性能 一般
易用性
功能特性 丰富 更丰富 非常丰富
适用场景 一般场景 高并发场景 需要高度定制化的场景

根据不同的业务场景和需求,可以选择合适的调用方式。如果项目中已经使用了 Spring Web 且对性能要求不高,可以选择 RestTemplate;如果需要处理高并发场景且对响应式编程有一定了解,可以选择 WebClient;如果需要高度定制化的请求和响应处理,可以选择 HttpClient。

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

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

相关文章

USTCPC 2025 游记

队名 合肥一中能不能多请点OI教练,二人队。队长 @包涵宇 ,省队爷。 Day -inf~0 随机写了几道有意思的 cf 。 bhy 又在做黑的插头 dp 。膜拜。 Day 1 早上被父母逼着学习文化课,结果作业做不完直接半红温状态,, 加上昨天做了 ~8h 文化课作业只完成了 1/2 ,然后直接不做了…

AI运维助手-LinuxAgent

介绍 LinuxAgent是基于LLM大模型的智能运维助手,通过接入DeepSeek API实现对Linux终端的自然语言控制,可以实现高效的运维工作。目前已经更新到2.0.5版本。 LinuxAgent能够理解用户的自然语言指令,只要描述需求,系统自动解析意图并执行,支持中文、英语等,可以理解复杂的多…

微服务Elasticsearch

Elasticsearch中倒排索引 为什么查询效率高 比如说一个商品 在一百万条数据中 你如果要搜的话 他会从一百万条数据中去寻找 比如说你要搜小米手机 但是倒排索引是这样的 //倒排 { "小米": [1], "手机": [1,2,3,4], } 他在给定的文档范围内去搜索 比如说正…

20242825 2024-2025-2 《网络攻防实践》第四周作业

@目录一. 实验内容1.1 实验内容概述1.2 实验相关知识概述二. 实验过程2.1 ARP缓存欺骗攻击2.1.1 实验环境配置2.1.2 连通性测试2.1.3 继续实验实验亮点出现问题检查问题解决问题2.2 ICMP重定向攻击2.2.1 实验环境配置2.2.2 连通性测试发现问题检查问题解决问题2.2.3 继续实验…

论文解读-Advances in 3D Generation: A Survey

论文介绍 题目: Advances in 3D Generation: A Survey 发表年份是 2024年,综述性质的文章,是看到腾讯发布了混元3D大模型所以来看看这个论文主要贡献 论文主要根据当前研究领域内不同的3D资产的生成方法进行了一个分类,将3D生成算法分为:前馈生成,基于优化的生成,基于过…

大数据技术

Hadoop Hadoop是一个能够对大量数据进行分布式处理的软件框架 HDFS ​ HDFS(Hadoop Distributed File System,Hadoop的分布式文件管理系统),是Hadoop的两大核心之一,用于管理数据和文件 Hadoop安装 ​ Hadoop可以在Window系统上运行,但其官方支持的操作系统只有Liunx,所以…

User\main.c(7): error: #5: cannot open source input file ds18b02.h: No such file or directory

报错截图解决途径 复制报错信息上网搜索,一般的解决办法:在c/c++选项中的Include Paths中包含头文件,将移植过来的代码放到指定的文件夹里,在Floder Setup中设置新移植的文件路径。很可惜我确认过我包含了头文件,但仍然报同样错误。 最后发现我代码里面是 #include"d…

Bean注入几种方式 (放入Spring容器)

目录 1、XML方式注入set方式注入构造方法注入2、注解方式注入@Component + @ComponentScan@Configuration + @Bean + @ComponentScan@Import3、实现ImportBeanDefinitionRegistrar接口 4、实现FactoryBean 5、实现BeanDefinitionRegistryPostProcessor 一、XML方式注入 在现在这…

自然资源数据要素支撑场景建设

自然资源数据要素与场景建设是推动经济社会高质量发展的重要途径。随着数字经济的快速发展,自然资源数据已成为关键的生产要素,其价值挖掘和利用成为推动经济社会发展的关键。自然资源数据要素的重要性自然资源数据要素包括地理、土地、矿产、海洋等多源数据,是支撑经济社会…

C语言分支与循环基础应用编程

实验任务1#include<stdio.h> #include<stdlib.h> #include<time.h> #define N 5int main() {int number;int i;srand(time(0));for(i=0;i<N;++i){number=rand()%100+1;printf("20490042%04d\n",number);}return 0; }问题1:生成一个1~100的随机…

NSSCTF Round#28 Team web题解

真是让人操心,但是又无法转移视线ez_ssrf 很简单的ssrf,知识点在网上搜都能搜到 payload http://node3.anna.nssctf.cn:28658@127.255.255.254/flag ez_php 第一部分有个非预期,直接/file就能出flag is_numeric绕过和md5强比较,很简单的知识点,这里就不细说了 第二部分网上…

Netty源码—4.客户端接入流程

大纲 1.关于Netty客户端连接接入问题整理 2.Reactor线程模型和服务端启动流程 3.Netty新连接接入的整体处理逻辑 4.新连接接入之检测新连接 5.新连接接入之创建NioSocketChannel 6.新连接接入之绑定NioEventLoop线程 7.新连接接入之注册Selector和注册读事件 8.注册Reactor线程…