在 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

相关推荐

  • C语言中的操作符(Operators)对数据进行运算的符号

    C语言中的操作符(Operators)是对数据进行运算的符号,分为多种类型,支持从基本算术到复杂的逻辑操作。以下是C语言操作符的详解: 1. 算术操作符(Arithmetic Operators) 用于执行基本数学运算: 示例: 2. 关系操作符(Relational Operators) 用于比较两个值,结果为布尔值: 示例: 3. 逻辑操作符(Logic…

    2024年11月22日
    00
  • uniapp基于vue3,element plus组件库以及axios通讯开发

    在 uniapp 前端开发中,使用 Vue3、Element Plus 组件库和 Axios 进行通讯是一种常见的组合。下面是一个简单的步骤和实践指南,帮助你更好地使用这些工具进行开发。1. 安装和配置 Vue3 和 Element Plus首先,确保你已经安装了 uniapp 项目,并且设置好相关依赖。在项目中,安装 Element Plus 组件库以便在…

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

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

    2024年12月2日
    00
  • 锁策略和优化是并发编程 synchronized 的优化,JVM 与编译器的锁优化

    锁策略和优化是并发编程中的重要话题,特别是在 Java 中,synchronized 作为基本的内置锁机制,得到了多层次的优化。在 JVM 和编译器层面,也有多种优化策略以提升锁的性能。 1. 锁策略:不同场景下的锁机制选择 2. synchronized 的优化 2.1 早期问题 在 Java 1.5 之前,synchronized 的实现依赖重量级锁,直…

    2024年11月24日
    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
  • 在 Windows 上使用 PyCharm 进行远程开发并连接到 Spark 进行 PySpark 开发

    在 Windows 上使用 PyCharm 进行远程开发并连接到 Spark 进行 PySpark 开发,通常涉及以下几个步骤:1. 设置 PyCharm 环境首先,需要安装 PyCharm,并确保你使用的是专业版(Professional),因为它支持远程开发。确保 Python 已经安装,并配置好虚拟环境。2. 配置远程开发环境在 Windows 上使用…

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

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

    2024年11月25日
    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中 ArrayList 和 LinkedList 实现 List 接口类

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

    2024年12月2日
    00
  • 使用 Redis 和 Spring Cache 实现基于注解的缓存功能

    Spring Cache 提供了一种简单的方法来通过注解对方法的返回结果进行缓存。结合 Redis,可以构建一个高效的分布式缓存解决方案。以下是详细实现步骤: 1. 引入必要的依赖在 pom.xml 文件中添加以下依赖(适用于 Spring Boot 项目): 2. 配置 Redis在 application.yml 或 application.proper…

    2024年12月1日
    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
  • 实现微信支付提现api接口教程

    微信支付的提现功能,通常是通过调用 企业付款到零钱 API 或 企业付款到银行卡 API 来实现的。以下是如何使用微信支付提现 API 的详细教程,包括其前置条件、接口调用以及注意事项。 1. 准备工作 1.1. 开通微信支付商户号 1.2. 配置证书 将这些文件保存在你的服务器上,用于发起 HTTPS 请求。 1.3. 获取 API 密钥 2. 企业付款到…

    2024年11月24日
    00
  • 在 Linux 系统上配置 Hadoop 环境,包括创建 hadoop 用户、更新 apt、安装 SSH 和配置 Java 环境

    以下是详细的步骤,用于在 Linux 系统上配置 Hadoop 环境,包括创建 hadoop 用户、更新 apt、安装 SSH 和配置 Java 环境。 1. 创建 Hadoop 用户创建一个名为 hadoop 的新用户: 根据提示设置密码和用户信息。 将 hadoop 用户添加到 sudo 组(可选): 切换到 hadoop 用户: 2. 更新 APT 包…

    2024年12月1日
    00
  • 在 Nuxt.js 应用中,webpack 的 compile 事件钩子构建过程

    在 Nuxt.js 应用中,webpack 的 compile 事件钩子通常用于在构建过程中处理或监听 Webpack 编译的状态。webpack 是 Nuxt.js 中的核心构建工具之一,而 Nuxt.js 本身是基于 Webpack 配置的,允许你通过扩展 Webpack 配置来进行自定义。要使用 webpack 的 compile 事件钩子,首先你需要…

    2024年11月29日
    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

发表回复

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

联系我们

在线咨询: QQ交谈

邮件:723923060@qq.com

关注微信