Java调用第三方HTTP接口:从入门到实战

✨✨ ✨这里是小韩学长 yyds 的BLOG ( 喜欢作者的点个关注吧 )

✨✨✨想要了解更多内容可以访问我的主页 小韩学长yyds-CSDN博客

目录

引言

常见方式及代码实例

[JDK 原生 HttpURLConnection](#JDK 原生 HttpURLConnection)

[Apache HttpClient](#Apache HttpClient)

[Spring RestTemplate](#Spring RestTemplate)

OkHttp

应用场景分析

支付接口调用

短信接口集成

数据获取与聚合

总结与建议


引言

在当今的软件开发领域,Java 作为一种广泛应用的编程语言,经常需要与各种外部系统进行交互。调用第三方 HTTP 接口是实现这种交互的重要方式之一,它能够帮助我们获取丰富的数据资源,整合多样化的服务,从而极大地扩展应用程序的功能边界。

比如在开发电商系统时,我们可以调用物流接口来实时跟踪商品的配送进度,调用支付接口实现安全便捷的在线支付;在开发天气预报应用时,调用天气数据接口获取最新的天气信息,为用户提供准确的气象服务。这些场景都离不开 Java 对第三方 HTTP 接口的调用。接下来,让我们深入了解 Java 调用第三方 HTTP 接口的常用方式、代码实例以及应用场景 。

常见方式及代码实例

JDK 原生 HttpURLConnection

HttpURLConnection 是 JDK 提供的用于 HTTP 请求的类,它是 URLConnection 的子类,位于java.net包中。通过它,我们可以方便地发送 HTTP 请求并处理响应 。其工作原理是基于 HTTP 协议,通过建立与服务器的 TCP 连接,按照 HTTP 协议规定的格式发送请求头和请求体,然后接收服务器返回的响应数据。

使用 HttpURLConnection 发送 GET 请求的代码示例如下:

java 复制代码
import java.io.BufferedReader;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net.URL;

public class HttpURLConnectionGetExample {

public static void main(String[] args) {

try {

// 创建URL对象

URL url = new URL("https://api.example.com/data");

// 打开连接

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

// 设置请求方法为GET

connection.setRequestMethod("GET");

// 建立连接

connection.connect();

// 获取响应码

int responseCode = connection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

// 获取响应流

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line;

StringBuilder response = new StringBuilder();

while ((line = reader.readLine()) != null) {

response.append(line);

}

reader.close();

System.out.println("Response: " + response.toString());

} else {

System.out.println("Request failed with response code: " + responseCode);

}

// 断开连接

connection.disconnect();

} catch (IOException e) {

e.printStackTrace();

}

}

}

使用 HttpURLConnection 发送 POST 请求时,除了设置请求方法为 POST,还需要设置请求头和请求体 。代码示例如下:

java 复制代码
import java.io.BufferedReader;

import java.io.DataOutputStream;

import java.io.IOException;

import java.io.InputStreamReader;

import java.net.HttpURLConnection;

import java.net.URL;

public class HttpURLConnectionPostExample {

public static void main(String[] args) {

try {

// 创建URL对象

URL url = new URL("https://api.example.com/data");

// 打开连接

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

// 设置请求方法为POST

connection.setRequestMethod("POST");

// 设置请求头

connection.setRequestProperty("Content-Type", "application/json");

// 允许输出

connection.setDoOutput(true);

// 构建请求体

String jsonInputString = "{\"key\":\"value\"}";

try (DataOutputStream wr = new DataOutputStream(connection.getOutputStream())) {

wr.writeBytes(jsonInputString);

wr.flush();

}

// 获取响应码

int responseCode = connection.getResponseCode();

if (responseCode == HttpURLConnection.HTTP_OK) {

// 获取响应流

BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));

String line;

StringBuilder response = new StringBuilder();

while ((line = reader.readLine()) != null) {

response.append(line);

}

reader.close();

System.out.println("Response: " + response.toString());

} else {

System.out.println("Request failed with response code: " + responseCode);

}

// 断开连接

connection.disconnect();

} catch (IOException e) {

e.printStackTrace();

}

}

}

Apache HttpClient

Apache HttpClient 是一个功能强大的 HTTP 客户端库,它提供了丰富的功能和灵活的配置选项,广泛应用于 Java 应用程序中。与 HttpURLConnection 相比,HttpClient 具有更好的性能和更丰富的特性,如支持连接池、请求重试、认证和代理等。

使用 HttpClient 发送 GET 请求的代码示例如下:

java 复制代码
import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.methods.CloseableHttpResponse;

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;

import java.io.IOException;

public class HttpClientGetExample {

public static void main(String[] args) {

try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

// 创建GET请求

HttpGet request = new HttpGet("https://api.example.com/data");

// 发送请求并获取响应

try (CloseableHttpResponse response = httpClient.execute(request)) {

// 获取响应状态码

int statusCode = response.getStatusLine().getStatusCode();

System.out.println("Response Status Code: " + statusCode);

// 获取响应实体

HttpEntity entity = response.getEntity();

if (entity != null) {

// 将响应实体转换为字符串

String responseBody = EntityUtils.toString(entity);

System.out.println("Response Body: " + responseBody);

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

使用 HttpClient 发送 POST 请求时,需要创建 HttpPost 对象,并设置请求体和请求头 。代码示例如下:

java 复制代码
import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.methods.CloseableHttpResponse;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.util.EntityUtils;

import java.io.IOException;

public class HttpClientPostExample {

public static void main(String[] args) {

try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

// 创建POST请求

HttpPost request = new HttpPost("https://api.example.com/data");

// 设置请求实体

String jsonPayload = "{\"key\":\"value\"}";

StringEntity entity = new StringEntity(jsonPayload);

request.setEntity(entity);

request.setHeader("Content-Type", "application/json");

// 发送请求并获取响应

try (CloseableHttpResponse response = httpClient.execute(request)) {

// 获取响应状态码

int statusCode = response.getStatusLine().getStatusCode();

System.out.println("Response Status Code: " + statusCode);

// 获取响应实体

HttpEntity responseEntity = response.getEntity();

if (responseEntity != null) {

// 将响应实体转换为字符串

String responseBody = EntityUtils.toString(responseEntity);

System.out.println("Response Body: " + responseBody);

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

在实际应用中,还可以配置 HttpClient 的连接池和请求重试机制 。例如,配置连接池:

java 复制代码
import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;

public class HttpClientPoolExample {

public static void main(String[] args) {

// 创建连接管理器

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();

// 设置最大连接数

connectionManager.setMaxTotal(100);

// 设置每个路由的最大连接数

connectionManager.setDefaultMaxPerRoute(20);

// 创建HttpClient实例

CloseableHttpClient httpClient = HttpClients.custom()

.setConnectionManager(connectionManager)

.build();

// 使用httpClient发送请求

}

}

配置请求重试机制:

java 复制代码
import org.apache.http.client.HttpRequestRetryHandler;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.protocol.HttpContext;

import java.io.IOException;

import java.io.InterruptedIOException;

import java.net.UnknownHostException;

public class HttpClientRetryExample {

public static void main(String[] args) {

// 创建请求重试处理器

HttpRequestRetryHandler retryHandler = (exception, executionCount, context) -> {

if (executionCount >= 3) {

// 如果重试次数达到3次,不再重试

return false;

}

if (exception instanceof InterruptedIOException) {

// 超时异常,不再重试

return false;

}

if (exception instanceof UnknownHostException) {

// 未知主机异常,不再重试

return false;

}

// 其他异常,进行重试

return true;

};

// 创建HttpClient实例

CloseableHttpClient httpClient = HttpClients.custom()

.setRetryHandler(retryHandler)

.build();

// 使用httpClient发送请求

}

}

Spring RestTemplate

RestTemplate 是 Spring 框架提供的用于访问 RESTful 服务的客户端类,它简化了与 RESTful API 的交互过程,提供了一系列便捷的方法来发送 HTTP 请求并处理响应 。RestTemplate 在 Spring 应用中常用于微服务之间的通信、调用第三方 RESTful 接口等场景。

使用 RestTemplate 发送 GET 请求获取对象的代码示例如下:

java 复制代码
import org.springframework.http.ResponseEntity;

import org.springframework.web.client.RestTemplate;

public class RestTemplateGetExample {

public static void main(String[] args) {

RestTemplate restTemplate = new RestTemplate();

String url = "https://api.example.com/data/{id}";

// 发送GET请求并获取响应实体

ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, 1);

if (response.getStatusCode().is2xxSuccessful()) {

System.out.println("Response: " + response.getBody());

} else {

System.out.println("Request failed with status code: " + response.getStatusCode());

}

}

}

使用 RestTemplate 发送 POST 请求的代码示例如下:

java 复制代码
import org.springframework.http.HttpEntity;

import org.springframework.http.HttpHeaders;

import org.springframework.http.MediaType;

import org.springframework.http.ResponseEntity;

import org.springframework.web.client.RestTemplate;

public class RestTemplatePostExample {

public static void main(String[] args) {

RestTemplate restTemplate = new RestTemplate();

String url = "https://api.example.com/data";

// 设置请求头

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_JSON);

//构建请求体

String jsonRequest = "{\"key\":\"value\"}";

HttpEntity<String> entity = new HttpEntity<>(jsonRequest, headers);

// 发送POST请求并获取响应实体

ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);

if (response.getStatusCode().is2xxSuccessful()) {

System.out.println("Response: " + response.getBody());

} else {

System.out.println("Request failed with status code: " + response.getStatusCode());

}

}

}

除了 GET 和 POST 请求,RestTemplate 还支持 PUT、DELETE 等其他 HTTP 方法 。例如,发送 PUT 请求:

java 复制代码
import org.springframework.http.HttpEntity;

import org.springframework.http.HttpHeaders;

import org.springframework.http.MediaType;

import org.springframework.web.client.RestTemplate;

public class RestTemplatePutExample {

public static void main(String[] args) {

RestTemplate restTemplate = new RestTemplate();

String url = "https://api.example.com/data/{id}";

// 设置请求头

HttpHeaders headers = new HttpHeaders();

headers.setContentType(MediaType.APPLICATION_JSON);

// 构建请求体

String jsonRequest = "{\"key\":\"newValue\"}";

HttpEntity<String> entity = new HttpEntity<>(jsonRequest, headers);

// 发送PUT请求

restTemplate.put(url, entity, 1);

System.out.println("PUT request sent successfully");

}

}

发送 DELETE 请求:

java 复制代码
import org.springframework.web.client.RestTemplate;

public class RestTemplateDeleteExample {

public static void main(String[] args) {

RestTemplate restTemplate = new RestTemplate();

String url = "https://api.example.com/data/{id}";

// 发送DELETE请求

restTemplate.delete(url, 1);

System.out.println("DELETE request sent successfully");

}

}

在处理响应结果时,可以通过 ResponseEntity 对象获取响应状态码、响应头和响应体等信息。同时,RestTemplate 在请求过程中可能会抛出各种异常,如 HttpClientErrorException(客户端错误,如 400、401 等)、HttpServerErrorException(服务器端错误,如 500、503 等),需要进行适当的异常处理 。例如:

java 复制代码
import org.springframework.http.ResponseEntity;

import org.springframework.web.client.HttpClientErrorException;

import org.springframework.web.client.HttpServerErrorException;

import org.springframework.web.client.RestTemplate;

public class RestTemplateExceptionExample {

public static void main(String[] args) {

RestTemplate restTemplate = new RestTemplate();

String url = "https://api.example.com/data/{id}";

try {

ResponseEntity<String> response = restTemplate.getForEntity(url, String.class, 1);

if (response.getStatusCode().is2xxSuccessful()) {

System.out.println("Response: " + response.getBody());

}

} catch (HttpClientErrorException e) {

System.out.println("Client error: " + e.getStatusCode());

e.printStackTrace();

} catch (HttpServerErrorException e) {

System.out.println("Server error: " + e.getStatusCode());

e.printStackTrace();

}

}

}

OkHttp

OkHttp 是一个高效的 HTTP 客户端,适用于 Android 和 Java 应用程序。它支持同步和异步 HTTP 请求,提供了简洁的 API 和强大的功能,如拦截器、连接池、缓存等。OkHttp 的高效性体现在它的连接池复用机制、请求和响应的高效处理,以及对 HTTP/2 协议的支持,能够大大减少网络请求的时间和资源消耗。

使用 OkHttp 发送同步 GET 请求的代码示例如下:

java 复制代码
import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

import java.io.IOException;

public class OkHttpSyncGetExample {

public static void main(String[] args) {

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()

.url("https://api.example.com/data")

.build();

try (Response response = client.newCall(request).execute()) {

if (response.isSuccessful()) {

String responseBody = response.body().string();

System.out.println("Response: " + responseBody);

} else {

System.out.println("Request failed with response code: " + response.code());

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

使用 OkHttp 发送异步 GET 请求时,通过 enqueue 方法将请求加入队列,并通过回调函数处理响应 。代码示例如下:

java 复制代码
import okhttp3.Callback;

import okhttp3.OkHttpClient;

import okhttp3.Request;

import okhttp3.Response;

import java.io.IOException;

public class OkHttpAsyncGetExample {

public static void main(String[] args) {

OkHttpClient client = new OkHttpClient();

Request request = new Request.Builder()

.url("https://api.example.com/data")

.build();

client.newCall(request).enqueue(new Callback() {

@Override

public void onFailure(okhttp3.Call call, IOException e) {

e.printStackTrace();

}

@Override

public void onResponse(okhttp3.Call call, Response response) throws IOException {

if (response.isSuccessful()) {

String responseBody = response.body().string();

System.out.println("Response: " + responseBody);

} else {

System.out.println("Request failed with response code: " + response.code());

}

}

});

}

}

OkHttp 还支持配置缓存和拦截器。配置缓存可以减少重复的网络请求,提高应用的性能 。示例代码如下:

java 复制代码
import okhttp3.Cache;

import okhttp3.OkHttpClient;

import java.io.File;

import java.io.IOException;

public class OkHttpCacheExample {

public static void main(String[] args) {

// 设置缓存目录和缓存大小

File cacheDirectory = new File("cache");

int cacheSize = 10 * 1024 * 1024; // 10MB

Cache cache = new Cache(cacheDirectory, cacheSize);

OkHttpClient client = new OkHttpClient.Builder()

.cache(cache)

.build();

// 使用client发送请求

}

}

拦截器可以用于添加请求头、日志记录、请求重试等功能 。例如,添加一个日志拦截器:

java 复制代码
import okhttp3.*;

import java.io.IOException;

public class OkHttpInterceptorExample {

public static void main(String[] args) {

HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {

@Override

public void log(String message) {

System.out.println(message);

}

});

loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient client = new OkHttpClient.Builder()

.addInterceptor(loggingInterceptor)

.build();

// 使用client发送请求

}

}

应用场景分析

支付接口调用

在电商系统中,支付功能是核心环节之一。以常见的微信支付和支付宝支付为例,其调用流程通常包括以下关键步骤:

  1. 生成订单:用户在电商平台选择商品并确认购买后,系统生成订单信息,包括订单号、商品详情、价格等。
  2. 调用支付接口:电商平台后端使用 Java 调用第三方支付接口,将订单信息发送给支付平台。在这个过程中,需要根据支付平台的要求构造请求参数,如订单金额、订单号、商品描述等,并按照特定的签名规则生成签名,以确保请求的安全性和完整性 。
  3. 支付页面展示:支付平台验证订单信息无误后,返回一个包含支付方式的页面链接或二维码。电商平台将这个链接或二维码展示给用户,用户可以选择合适的支付方式(如银行卡支付、余额支付等)进行支付。
  4. 支付结果处理:用户完成支付操作后,支付平台会将支付结果异步通知给电商平台。电商平台需要编写相应的回调接口来接收支付结果通知,并根据通知中的支付状态(如支付成功、支付失败、支付处理中)更新订单状态,同时为用户提供相应的提示信息 。

以使用 Apache HttpClient 调用支付宝支付接口为例,代码示例如下:

java 复制代码
import org.apache.http.HttpEntity;

import org.apache.http.HttpResponse;

import org.apache.http.client.methods.CloseableHttpResponse;

import org.apache.http.client.methods.HttpPost;

import org.apache.http.entity.StringEntity;

import org.apache.http.impl.client.CloseableHttpClient;

import org.apache.http.impl.client.HttpClients;

import org.apache.http.util.EntityUtils;

import java.io.IOException;

import java.util.HashMap;

import java.util.Map;

public class AlipayPaymentExample {

public static void main(String[] args) {

try (CloseableHttpClient httpClient = HttpClients.createDefault()) {

// 支付宝支付接口URL

String url = "https://openapi.alipay.com/gateway.do";

// 构造请求参数

Map<String, String> params = new HashMap<>();

params.put("app_id", "your_app_id");

params.put("method", "alipay.trade.page.pay");

params.put("format", "JSON");

params.put("charset", "UTF-8");

params.put("sign_type", "RSA2");

params.put("timestamp", "2024-10-01 12:00:00");

params.put("version", "1.0");

params.put("biz_content", "{\"out_trade_no\":\"202410010001\",\"total_amount\":\"100.00\",\"subject\":\"商品购买\",\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

// 生成签名

String sign = generateSign(params, "your_private_key");

params.put("sign", sign);

// 创建POST请求

HttpPost request = new HttpPost(url);

// 设置请求实体

StringEntity entity = new StringEntity(buildQuery(params), "UTF-8");

request.setEntity(entity);

request.setHeader("Content-Type", "application/x-www-form-urlencoded");

// 发送请求并获取响应

try (CloseableHttpResponse response = httpClient.execute(request)) {

// 获取响应状态码

int statusCode = response.getStatusLine().getStatusCode();

System.out.println("Response Status Code: " + statusCode);

// 获取响应实体

HttpEntity responseEntity = response.getEntity();

if (responseEntity != null) {

// 将响应实体转换为字符串

String responseBody = EntityUtils.toString(responseEntity);

System.out.println("Response Body: " + responseBody);

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

// 生成签名的方法

private static String generateSign(Map<String, String> params, String privateKey) {

// 签名生成逻辑,这里省略具体实现

return "generated_sign";

}

// 构建请求参数的方法

private static String buildQuery(Map<String, String> params) {

StringBuilder query = new StringBuilder();

for (Map.Entry<String, String> entry : params.entrySet()) {

if (query.length() > 0) {

query.append("&");

}

query.append(entry.getKey()).append("=").append(entry.getValue());

}

return query.toString();

}

}

在处理支付结果回调时,需要在 Spring Boot 项目中创建一个 Controller 来接收回调请求,并进行验签和订单状态更新等操作 。示例代码如下:

java 复制代码
import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RestController;

@RestController

public class AlipayCallbackController {

@PostMapping("/alipay/callback")

public String alipayCallback(@RequestBody String callbackData) {

// 验签逻辑,验证回调数据的真实性

boolean isValid = verifySign(callbackData, "alipay_public_key");

if (isValid) {

// 解析回调数据

// 根据回调数据中的支付状态更新订单状态

updateOrderStatus(callbackData);

return "success";

} else {

return "fail";

}

}

// 验签方法

private boolean verifySign(String callbackData, String alipayPublicKey) {

// 验签逻辑,这里省略具体实现

return true;

}

// 更新订单状态方法

private void updateOrderStatus(String callbackData) {

// 解析callbackData获取订单号和支付状态

// 根据订单号和支付状态更新数据库中的订单状态

}

}

短信接口集成

在用户注册、找回密码等场景中,短信接口发挥着重要作用。以用户注册场景为例,当用户在应用中填写注册信息并提交后,后端系统会调用短信接口向用户输入的手机号码发送验证码。用户收到验证码后,在规定时间内输入验证码进行验证,验证通过后完成注册流程 。

使用 Java 调用短信接口的代码示例如下,这里以使用阿里云短信服务为例:

java 复制代码
import com.aliyuncs.DefaultAcsClient;

import com.aliyuncs.IAcsClient;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;

import com.aliyuncs.exceptions.ClientException;

import com.aliyuncs.profile.DefaultProfile;

import com.aliyuncs.profile.IClientProfile;

public class SmsSenderExample {

public static void main(String[] args) {

// 初始化acsClient,暂不支持region化

IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", "your_access_key_id", "your_access_key_secret");

try {

DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", "Dysmsapi", "dysmsapi.aliyuncs.com");

IAcsClient acsClient = new DefaultAcsClient(profile);

// 组装请求对象-具体描述见控制台-文档部分内容

SendSmsRequest request = new SendSmsRequest();

// 必填:待发送手机号

request.setPhoneNumbers("13800138000");

// 必填:短信签名-可在短信控制台中找到

request.setSignName("你的短信签名");

// 必填:短信模板-可在短信控制台中找到

request.setTemplateCode("你的短信模板CODE");

// 可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为

request.setTemplateParam("{\"name\":\"用户姓名\",\"code\":\"123456\"}");

// 选填-上行短信扩展码(无特殊需求用户请忽略此字段)

// request.setSmsUpExtendCode("90997");

// 发起访问请求

SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);

if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {

System.out.println("短信发送成功");

} else {

System.out.println("短信发送失败,错误码:" + sendSmsResponse.getCode() + ",错误信息:" + sendSmsResponse.getMessage());

}

} catch (ClientException e) {

e.printStackTrace();

}

}

}

在处理短信接口的响应时,需要根据响应结果判断短信是否发送成功。如果发送失败,需要根据错误码和错误信息进行相应的处理,如记录日志、重试发送等 。例如:

java 复制代码
if (sendSmsResponse.getCode() != null && sendSmsResponse.getCode().equals("OK")) {

System.out.println("短信发送成功");

} else {

System.out.println("短信发送失败,错误码:" + sendSmsResponse.getCode() + ",错误信息:" + sendSmsResponse.getMessage());

// 记录日志

log.error("短信发送失败,错误码:{},错误信息:{}", sendSmsResponse.getCode(), sendSmsResponse.getMessage());

// 重试发送逻辑,这里可以设置重试次数和重试间隔时间

int retryCount = 3;

for (int i = 0; i < retryCount; i++) {

try {

SendSmsResponse retryResponse = acsClient.getAcsResponse(request);

if (retryResponse.getCode() != null && retryResponse.getCode().equals("OK")) {

System.out.println("短信重试发送成功");

break;

} else {

System.out.println("短信重试发送失败,错误码:" + retryResponse.getCode() + ",错误信息:" + retryResponse.getMessage());

log.error("短信重试发送失败,错误码:{},错误信息:{}", retryResponse.getCode(), retryResponse.getMessage());

// 等待一段时间后重试

Thread.sleep(5000);

}

} catch (ClientException | InterruptedException e) {

e.printStackTrace();

}

}

}

数据获取与聚合

以获取天气预报数据为例,我们可以调用第三方天气接口来获取指定城市的天气信息。假设我们使用 OpenWeatherMap 接口,首先需要在其官网注册账号并获取 API Key。然后,通过 Java 代码发送 HTTP 请求获取天气数据,并对返回的 JSON 数据进行解析和处理 。

使用 Spring RestTemplate 调用 OpenWeatherMap 接口获取天气预报数据的代码示例如下:

java 复制代码
import org.springframework.http.ResponseEntity;

import org.springframework.web.client.RestTemplate;

public class WeatherDataFetcher {

public static void main(String[] args) {

RestTemplate restTemplate = new RestTemplate();

String apiKey = "your_api_key";

String city = "Beijing";

String url = "http://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=" + apiKey + "&units=metric";

// 发送GET请求获取天气数据

ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

if (response.getStatusCode().is2xxSuccessful()) {

String jsonResponse = response.getBody();

// 解析JSON数据

parseWeatherData(jsonResponse);

} else {

System.out.println("Request failed with status code: " + response.getStatusCode());

}

}

// 解析天气数据的方法

private static void parseWeatherData(String jsonResponse) {

// 使用JSON解析库(如Jackson或Gson)解析JSON数据

// 提取需要的天气信息,如温度、湿度、天气状况等

// 这里以Gson为例

com.google.gson.JsonObject jsonObject = new com.google.gson.JsonParser().parse(jsonResponse).getAsJsonObject();

double temperature = jsonObject.get("main").getAsJsonObject().get("temp").getAsDouble();

int humidity = jsonObject.get("main").getAsJsonObject().get("humidity").getAsInt();

String weatherDescription = jsonObject.get("weather").getAsJsonArray().get(0).getAsJsonObject().get("description").getAsString();

System.out.println("City: Beijing");

System.out.println("Temperature: " + temperature + " °C");

System.out.println("Humidity: " + humidity + " %");

System.out.println("Weather: " + weatherDescription);

}

}

获取到天气数据后,可以将这些数据整合到应用程序的页面中展示给用户,如在 Web 应用中通过前端模板引擎(如 Thymeleaf、Freemarker)将天气信息渲染到 HTML 页面上,或者在移动应用中通过相应的界面组件展示天气数据 。在实际应用中,还可以对获取到的数据进行缓存处理,减少频繁的接口调用,提高应用的性能和响应速度 。例如,使用 Spring Cache 框架对天气数据进行缓存:

java 复制代码
import org.springframework.cache.annotation.Cacheable;

import org.springframework.http.ResponseEntity;

import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;

@Service

public class WeatherService {

private static final String API_KEY = "your_api_key";

private static final String BASE_URL = "http://api.openweathermap.org/data/2.5/weather";

private final RestTemplate restTemplate;

public WeatherService(RestTemplate restTemplate) {

this.restTemplate = restTemplate;

}

@Cacheable(value = "weatherData", key = "#city")

public String getWeatherData(String city) {

String url = BASE_URL + "?q=" + city + "&appid=" + API_KEY + "&units=metric";

ResponseEntity<String> response = restTemplate.getForEntity(url, String.class);

if (response.getStatusCode().is2xxSuccessful()) {

return response.getBody();

} else {

throw new RuntimeException("Failed to fetch weather data for " + city);

}

}

}

在上述代码中,@Cacheable注解表示该方法的返回值会被缓存起来。当再次调用getWeatherData方法时,如果缓存中已经存在对应城市的天气数据,则直接从缓存中获取,而不会再次调用接口获取数据 。这样可以有效地减少对第三方接口的调用次数,提高系统的性能和稳定性 。

总结与建议

在 Java 开发中,调用第三方 HTTP 接口是一项常见且重要的任务。通过本文的介绍,我们了解了 JDK 原生 HttpURLConnection、Apache HttpClient、Spring RestTemplate 和 OkHttp 这几种常用的调用方式 。每种方式都有其独特的特点和适用场景:

  • JDK 原生 HttpURLConnection:是 JDK 自带的 HTTP 请求类,使用简单,无需引入额外依赖。但功能相对有限,代码编写较为繁琐,在处理复杂请求和高并发场景时性能表现不佳。适用于对功能和性能要求不高,且项目依赖简洁性要求较高的简单场景 。
  • Apache HttpClient:功能强大,支持连接池、请求重试、认证和代理等高级功能,性能较好,适用于对 HTTP 请求功能要求全面,需要处理复杂业务逻辑和高并发场景的应用 。
  • Spring RestTemplate:基于 Spring 框架,与 Spring 生态系统集成紧密,在 Spring 应用中使用方便,代码简洁。适用于 Spring 项目中微服务之间的通信以及调用第三方 RESTful 接口的场景 。
  • OkHttp:高效且功能丰富,支持同步和异步请求,提供了简洁的 API 和强大的功能,如拦截器、连接池、缓存等。特别适用于对性能要求较高,尤其是在 Android 应用开发中以及需要处理大量网络请求的场景 。

在实际开发中,我们应根据项目的具体需求、技术架构和性能要求等因素,综合考虑选择合适的调用方式。同时,为了提高代码的可维护性和复用性,建议将接口调用逻辑封装成独立的工具类或服务 。在处理接口调用过程中的异常时,要进行全面且细致的异常处理,确保系统的稳定性和可靠性 。此外,随着技术的不断发展和演进,我们还应持续关注新的 HTTP 客户端库和技术,不断探索和优化接口调用的实现方式,以提升应用程序的性能和用户体验 。

相关推荐
RainbowSea14 分钟前
130道基础OJ编程题之: 78~88
java
松树戈23 分钟前
IDEA Commit 模态提交界面关闭VS开启对比
java·ide·intellij-idea
谦行27 分钟前
前端视角 Java Web 入门手册 4.4:Web 开发基础—— Listener
java·后端
今天也想MK代码27 分钟前
rust编程实战:实现3d粒子渲染wasm
开发语言·rust·wasm
结衣结衣.36 分钟前
【Qt】自定义信号和槽函数
开发语言·c++·qt·c++11
jk_10138 分钟前
MATLAB中strip函数用法
java·服务器·数据库
一弓虽1 小时前
maven学习
java·学习·github·maven
忍者算法1 小时前
在 Linux 下,服务器如何知道某个 TCP 连接来了消息? 这就涉及 IO 事件通知机制!
websocket·网络协议·tcp/ip·http·信息与通信
24k小善1 小时前
Flink Forward Asia 2024 大会 内容整理
java·大数据·flink
xiaozaq1 小时前
在Eclipse中安装Lombok插件
java·python·eclipse