在 Spring Boot 中实现 Callback 回调的常用方法

Spring Boot 中实现 Callback(回调) 通常用于处理外部系统调用你的服务接口。例如,当一个第三方服务完成某项操作后通知你的应用完成结果。以下是实现回调的完整流程:

1. 回调的基本流程

  1. 注册回调地址
    • 第三方服务需要知道你的回调 URL,你需要向第三方注册一个 URL。
    • 例如:https://yourdomain.com/callback.
  2. 实现回调接口
    • 创建一个控制器处理第三方服务的回调请求。
    • 通常是 POSTGET 方法。
  3. 验证请求(可选):
    • 验证请求的合法性,确保回调确实来自第三方服务。
    • 可以使用签名验证、白名单 IP、Token 等方法。
  4. 处理回调数据
    • 接收并解析回调数据。
    • 根据业务逻辑更新系统状态。
  5. 返回响应
    • 返回第三方服务指定的响应,通常是 200 OK 或其他业务约定的格式。

2. 示例代码

2.1 创建回调接口

假设第三方服务会通过 POST 请求回调数据到 /callback,并发送如下 JSON 数据:

{
  "orderId": "123456",
  "status": "COMPLETED",
  "signature": "abcdef123456"
}

实现代码如下:

import org.springframework.web.bind.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Map;

@RestController
@RequestMapping("/callback")
public class CallbackController {

    private static final Logger logger = LoggerFactory.getLogger(CallbackController.class);

    @PostMapping
    public String handleCallback(@RequestBody Map<String, Object> payload) {
        // 日志打印回调数据
        logger.info("Received callback: {}", payload);

        // 提取回调参数
        String orderId = (String) payload.get("orderId");
        String status = (String) payload.get("status");
        String signature = (String) payload.get("signature");

        // 验证签名 (示例,可替换为实际验证逻辑)
        if (!isValidSignature(payload, signature)) {
            logger.warn("Invalid signature for callback with orderId: {}", orderId);
            return "Invalid signature";
        }

        // 处理业务逻辑
        if ("COMPLETED".equals(status)) {
            logger.info("Order {} completed successfully!", orderId);
            // 更新订单状态,执行其他逻辑
        }

        // 返回响应
        return "Callback received successfully!";
    }

    private boolean isValidSignature(Map<String, Object> payload, String signature) {
        // 模拟签名验证逻辑,可替换为真实的验证算法
        String expectedSignature = "abcdef123456"; // 示例签名
        return expectedSignature.equals(signature);
    }
}

2.2 注册回调 URL

向第三方服务提供回调地址,例如:

https://yourdomain.com/callback

2.3 配置 Web 应用

确保你的 Spring Boot 应用可以接收到外部请求:

  1. 配置 application.ymlapplication.properties 中的服务器端口和上下文路径:
server:
  port: 8080

如果应用部署在防火墙后,确保端口 8080 可访问,或者通过 Nginx 反向代理将流量引导到 /callback

3. 验证回调请求

为了安全性,回调接口通常需要验证请求来源的合法性。常见验证方法:

3.1 签名验证

  • 第三方服务发送回调请求时,会包含一个签名字段。
  • 你可以通过回调数据和预共享的密钥生成签名,并与回调请求中的签名对比。

示例签名生成:

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SignatureUtils {

    public static String generateSignature(String data, String secretKey) throws NoSuchAlgorithmException {
        String input = data + secretKey;
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] hash = md.digest(input.getBytes(StandardCharsets.UTF_8));
        StringBuilder hexString = new StringBuilder();
        for (byte b : hash) {
            String hex = Integer.toHexString(0xff & b);
            if (hex.length() == 1) hexString.append('0');
            hexString.append(hex);
        }
        return hexString.toString();
    }
}

3.2 IP 白名单

  • 检查回调请求的来源 IP 是否在允许范围内:
@RequestHeader("X-Forwarded-For") String ipAddress

通过拦截器或过滤器限制允许的 IP。

4. 返回第三方约定的响应

根据第三方的需求,返回特定的响应格式。例如:

  • 如果回调成功,需要返回:json复制代码
{ "status": "success", "message": "OK" }

修改代码如下:

@PostMapping
public Map<String, String> handleCallback(@RequestBody Map<String, Object> payload) {
    // 处理逻辑
    Map<String, String> response = new HashMap<>();
    response.put("status", "success");
    response.put("message", "OK");
    return response;
}

5. 测试回调接口

5.1 使用 Postman

  1. 打开 Postman,创建一个新的 POST 请求。
  2. 设置 URL 为 http://localhost:8080/callback
  3. 在 Body 中选择 raw,内容类型为 JSON,输入测试数据:
{
  "orderId": "123456",
  "status": "COMPLETED",
  "signature": "abcdef123456"
}

4. 点击发送,检查接口是否返回预期响应。

5.2 使用模拟工具

  • 如果第三方未提供实际回调,可以使用工具(如 BeeceptorNgrok)模拟回调请求。

6. 总结

  • 回调接口的核心是接收外部服务的数据并处理。
  • 安全性是实现回调接口的关键,推荐使用签名验证、IP 白名单等方法保护接口。
  • 测试时确保网络配置正确,验证接口能够正常接收和处理回调请求。

发布者:myrgd,转载请注明出处:https://www.object-c.cn/4512

Like (0)
Previous 2024年11月24日 下午9:55
Next 2024年11月24日 下午10:09

相关推荐

  • 使用 CLion 编写 C51 (即8051微控制器) 程序时,遇到 sbit 相关报错

    在使用 CLion 编写 C51 (即8051微控制器) 程序时,遇到 sbit 相关报错,通常是因为 CLion 默认并不支持8051的特殊语法和寄存器定义方式。sbit 是 C51 编译器中的一个关键字,用来将一个单独的位(bit)映射到特定的硬件寄存器或端口引脚。常见的报错及解决方法sbit 语法问题: CLion 本身不支持 C51 特有的语法,sb…

    2024年11月27日
    00
  • Docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像方法

    使用 Docker 快速部署 Nginx、Redis、MySQL、Tomcat 以及制作镜像 通过 Docker,开发者可以快速部署和管理各种服务。本文介绍如何快速使用 Docker 部署 Nginx、Redis、MySQL 和 Tomcat,以及如何制作自定义镜像。 1. Docker 基础准备 安装 Docker 如果还未安装 Docker,可按照以下步…

    2024年11月26日
    00
  • 在使用 uni-app 开发小程序或移动端应用时 title image失效问题

    在使用 uni-app 开发小程序或移动端应用时,若发现 分享的标题(title) 和 图片(image) 配置无效,可能是由于配置错误、平台限制或代码逻辑问题。以下是排查和解决问题的详细指南: 1. 确保正确使用分享 API onShareAppMessage(自定义转发) 确保在 pages 的页面代码中正确使用了 onShareAppMessage 方…

    2024年11月25日
    00
  • Java 8 到 Java 17 的升级涉及一些关键变化

    JDK 8 升级到 JDK 17 指南Java 8 到 Java 17 的升级涉及一些关键变化,包括语言特性、API 更新和性能改进。以下是一些升级要点:语法和语言特性:记录类(Record Class):Java 14 引入了记录类,提供了一种简化创建不可变数据对象的方式。密封类(Sealed Classes):Java 15 引入了密封类,允许开发者限制…

    2024年11月27日
    00
  • 在 .NET 8 框架中使用 Web API 项目并通过引用 SqlSugar ORM 来操作数据库

    在 .NET 8 框架中使用 Web API 项目并通过引用 SqlSugar ORM 来操作数据库,可以遵循以下步骤: 1. 准备工作确保已安装 .NET 8 SDK 和 SqlSugar NuGet 包。创建或打开现有的 Web Core API 项目。安装 SqlSugar NuGet 包: 2. 配置 SqlSugar在 Web API 项目中配置 …

    2024年11月27日
    00
  • Python 的 json模块序列化数据从文件里读取出来或存入文件

    Python 的 json 模块用于处理 JSON 格式的数据,可以将 JSON 数据与 Python 数据结构之间相互转换。以下是具体用法,包括从文件读取 JSON 数据以及将数据写入文件: 1. 将 JSON 数据从文件中读取到 Python 数据结构 代码示例: 解析过程: 2. 将 Python 数据结构写入到文件中(序列化为 JSON) 代码示例:…

    2024年11月26日
    00
  • pywebview 页面请求数据总是报错:TypeError: Cannot read properties of undefined (reading ‘api’)

    pywebview 中的 TypeError: Cannot read properties of undefined (reading ‘api’) 错误通常意味着 JavaScript 代码试图访问一个未定义的对象或属性(如 api)。这种问题通常出现在 Python 与前端 JavaScript 交互时,可能是由于以下原因:可能的原因及解决方法:Jav…

    2024年11月27日
    00
  • 在使用 VS Code 和 Keil 协同开发 STM32 程序

    在使用 VS Code 和 Keil 协同开发 STM32 程序时,可以利用 Keil 强大的编译器 和 VS Code 的高效代码编辑功能,结合起来提高开发效率。以下是实现协同开发的详细步骤: 前置准备安装 Keil确保已安装 Keil MDK-ARM,并配置好开发环境。Keil 下载地址:Keil 官方网站安装 VS Code下载并安装最新版本的 VS …

    2024年12月1日
    00
  • java算法— 动态规划之斐波那契数列模型

    斐波那契数列是动态规划中一个经典的模型,其递推关系简单易懂,非常适合作为入门练习。斐波那契数列的定义如下: 在 Java 中,可以通过递归、带记忆化的递归、迭代和优化空间复杂度的方式实现斐波那契数列。 1. 递归实现 最直观的实现,但存在大量重复计算,时间复杂度为 O(2n)。 2. 带记忆化的递归 通过一个数组存储已计算的值,避免重复计算,时间复杂度降为 …

    2024年11月21日
    00
  • 理解 HTML、HTML5 和 “H5” 区别的重要性

    HTML & HTML5 & H5 的区别在构建现代网页时,理解 HTML、HTML5 和 “H5” 的区别是非常重要的。以下是它们的概念和主要区别: 1. HTML(超文本标记语言)定义HTML 是 HyperText Markup Language 的缩写,即超文本标记语言,用于定义网页内容的结构和含义。特性提供基…

    2024年12月2日
    00
  • 在Java中 ArrayList 和 LinkedList 实现 List 接口类

    在Java中,ArrayList 和 LinkedList 都是实现了 List 接口的类,但它们在底层实现和使用场景上有显著的区别。以下是它们的主要区别: 1. 底层实现ArrayList基于动态数组实现。元素是连续存储的,每个元素都可以通过索引直接访问。LinkedList基于双向链表实现。每个元素由节点(Node)存储,节点包含数据和前后节点的引用。 …

    2024年12月2日
    00
  • 在使用 Kettle 9.1 连接 MySQL 时,遇到错误提示 Connection failed. Verify all connection parameters and confirm that the appropriate driver is installed.

    在使用 Kettle 9.1 连接 MySQL 时,遇到错误提示 Connection failed. Verify all connection parameters and confirm that the appropriate driver is installed. 通常是由于以下几个原因导致的: 1. MySQL 驱动未正确配置Kettle 需要…

    2024年11月27日
    00
  • 在使用 HBase 时,遇到 Unable to find region for 错误问题

    在使用 HBase 时,遇到 Unable to find region for 错误通常是由于以下几个原因引起的:HBase RegionServer 未启动或无法连接表的 Region 分布信息不一致Zookeeper 配置问题客户端连接配置问题HBase 版本不兼容下面是一些常见的原因和解决办法:1. 确保 HBase 服务正常运行首先检查你的 HBa…

    2024年11月29日
    00
  • 通过 PHP 读取微软邮箱(Outlook/Office 365 邮箱)

    通过 PHP 读取微软邮箱(Outlook/Office 365 邮箱)邮件,通常需要使用 Microsoft Graph API,因为微软逐步淘汰了基于用户名和密码的 IMAP/SMTP 方式。Microsoft Graph API 支持 OAuth2.0 认证,可以安全地访问和管理用户邮件。 以下是实现读取微软邮箱邮件的完整示例。 实现步骤 1. 准备工…

    2024年11月25日
    00
  • 多方面的优化包括启动时间、React Native 速度提升 550% 运行时性能以及渲染效率的提升

    React Native 速度提升 550% 可能涉及多方面的优化,包括启动时间、运行时性能以及渲染效率的提升。这通常是通过框架改进、代码优化和工程实践的结合来实现的。以下是实现 React Native 性能大幅提升的一些关键方法和策略: 1. 启动时间优化 1.1 减少 JS Bundle 大小 1.2 预加载资源 1.3 使用优化的原生模块 2. 渲染…

    2024年12月7日
    00

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信