在 Spring Boot 中实现 Callback(回调) 通常用于处理外部系统调用你的服务接口。例如,当一个第三方服务完成某项操作后通知你的应用完成结果。以下是实现回调的完整流程:
1. 回调的基本流程
- 注册回调地址:
- 第三方服务需要知道你的回调 URL,你需要向第三方注册一个 URL。
- 例如:
https://yourdomain.com/callback
.
- 实现回调接口:
- 创建一个控制器处理第三方服务的回调请求。
- 通常是
POST
或GET
方法。
- 验证请求(可选):
- 验证请求的合法性,确保回调确实来自第三方服务。
- 可以使用签名验证、白名单 IP、Token 等方法。
- 处理回调数据:
- 接收并解析回调数据。
- 根据业务逻辑更新系统状态。
- 返回响应:
- 返回第三方服务指定的响应,通常是
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 应用可以接收到外部请求:
- 配置
application.yml
或application.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
- 打开 Postman,创建一个新的
POST
请求。 - 设置 URL 为
http://localhost:8080/callback
。 - 在 Body 中选择
raw
,内容类型为JSON
,输入测试数据:
{
"orderId": "123456",
"status": "COMPLETED",
"signature": "abcdef123456"
}
4. 点击发送,检查接口是否返回预期响应。
5.2 使用模拟工具
- 如果第三方未提供实际回调,可以使用工具(如 Beeceptor 或 Ngrok)模拟回调请求。
6. 总结
- 回调接口的核心是接收外部服务的数据并处理。
- 安全性是实现回调接口的关键,推荐使用签名验证、IP 白名单等方法保护接口。
- 测试时确保网络配置正确,验证接口能够正常接收和处理回调请求。
发布者:myrgd,转载请注明出处:https://www.object-c.cn/4512