大家好,我是小悟。
京东联盟开放平台是京东集团旗下的电商广告联盟平台,主要业务模式为CPS(按成交订单支付佣金),个人开发者可通过社交APP、聊天工具等进行推广并赚取佣金。
平台依托京东的海量商家和大数据能力,提供精准的营销解决方案。
下面将实现SpringBoot接入京东联盟开放平台,包括环境准备、核心步骤、代码实现和注意事项。
一、前期准备:注册与配置
1、注册京东开放平台账号:
访问京东开放平台官网,完成个人实名认证。
在开发者中心创建应用,填写使用场景(如“商品推广工具”),平台将审核技术能力与业务匹配度。
审核通过后,获取 AppKey(应用标识)和 AppSecret(签名密钥),这两个参数是API调用的核心凭证。
2、开发环境准备:
技术栈:SpringBoot 2.7+、JDK 8+、Maven 3.6+。
依赖:在 pom.xml 中添加必要的依赖(HTTP客户端、JSON处理工具等)。
<dependencies>
<!-- SpringBoot Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- HTTP客户端 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<!-- 签名工具 -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
3、配置参数:
在 application.yml 中配置京东联盟参数(参考实际项目的配置方式):
jd:
union:
app-key: "你的AppKey"
app-secret: "你的AppSecret"
api-url: "https://api.jd.com/routerjson"
# 联盟商品ID示例:动态字符串如 "VgDXlT9hVVVmDDiCbofTFhV7_VIfTFhV7VVyGGPNs"[citation:6]
二、核心步骤:接口调用与实现
接入流程主要包括:签名生成 → 请求发送 → 数据解析 → 业务处理。下面以查询商品详情接口(jd.union.open.goods.detail.query)为例,分步说明。
步骤1:签名生成
京东API要求对所有请求参数进行签名验证,推荐使用更安全的 HMAC-SHA256算法。签名步骤如下:
1、将所有请求参数(除 sign 外)按ASCII码升序排序。
2、将排序后的参数键值对拼接成字符串
(格式:key1=value1&key2=value2),并进行URL编码。
3、使用 AppSecret 对拼接字符串进行HMAC-SHA256加密,结果转为大写作为最终签名。
SpringBoot代码实现:
import org.springframework.stereotype.Component;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
@Component
public class JdSignatureUtil {
/**
* 生成京东API签名(HMAC-SHA256)
* @param params 请求参数Map(需包含app_key、method、timestamp等公共参数)
* @param appSecret 应用密钥
* @return 大写签名字符串
*/
public static String generateSign(Map<String, String> params, String appSecret) {
try {
// 1. 参数按ASCII升序排序
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
// 2. 拼接键值对(URL编码)
StringBuilder signStr = new StringBuilder();
for (String key : keys) {
if ("sign".equals(key)) continue; // 签名参数不参与签名
String value = params.get(key);
signStr.append(key)
.append("=")
.append(URLEncoder.encode(value, StandardCharsets.UTF_8.name()))
.append("&");
}
if (signStr.length() > 0) {
signStr.deleteCharAt(signStr.length() - 1); // 移除最后一个"&"
}
// 3. HMAC-SHA256加密
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(secretKeySpec);
byte[] hash = mac.doFinal(signStr.toString().getBytes(StandardCharsets.UTF_8));
// 4. 转为大写十六进制
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().toUpperCase();
} catch (Exception e) {
throw new RuntimeException("生成签名失败: " + e.getMessage(), e);
}
}
}
步骤2:发送HTTP请求
京东联盟API统一通过 api.jd.com/routerjson 地址调用,支持POST/GET方式。以下封装一个通用的请求工具类:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
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 com.fasterxml.jackson.databind.ObjectMapper;
import java.util.*;
@Component
public class JdApiClient {
@Value("${jd.union.app-key}")
private String appKey;
@Value("${jd.union.app-secret}")
private String appSecret;
@Value("${jd.union.api-url}")
private String apiUrl;
private final ObjectMapper objectMapper = new ObjectMapper();
/**
* 调用京东联盟API
* @param method 接口方法名(如 jd.union.open.goods.detail.query)
* @param bizParams 业务参数(如商品ID、场景ID等)
* @return API响应结果(JSON字符串)
*/
public String callApi(String method, Map<String, String> bizParams) {
try {
// 1. 构建公共参数
Map<String, String> params = new HashMap<>();
params.put("app_key", appKey);
params.put("method", method);
params.put("timestamp", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
params.put("format", "json");
params.put("v", "1.0");
if (bizParams != null) {
params.putAll(bizParams); // 添加业务参数
}
// 2. 生成签名
String sign = JdSignatureUtil.generateSign(params, appSecret);
params.put("sign", sign);
// 3. 发送POST请求
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
HttpPost httpPost = new HttpPost(apiUrl);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
// 构建表单参数
List<String> paramList = new ArrayList<>();
for (Map.Entry<String, String> entry : params.entrySet()) {
paramList.add(entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8.name()));
}
StringEntity entity = new StringEntity(String.join("&", paramList), StandardCharsets.UTF_8);
httpPost.setEntity(entity);
// 4. 解析响应
String response = EntityUtils.toString(httpClient.execute(httpPost).getEntity(), StandardCharsets.UTF_8);
return response;
}
} catch (Exception e) {
throw new RuntimeException("调用京东API失败: " + e.getMessage(), e);
}
}
}
步骤3:处理联盟商品ID
2025年联盟商品ID升级为动态字符串格式
(如 VgDXlT9hVVVmDDiCbofTFhV7_VIfTFhV7VVyGGPNs),由A段(动态变化)和B段(相对稳定)组成,需配合场景ID(sceneId)使用。常规推广场景使用 sceneId=1,比价场景使用 sceneId=2。
ID解析工具类:
@Component
public class UnionIdParser {
/**
* 解析联盟商品ID
* @param unionId 动态ID(格式:A段_B段)
* @return 解析结果,包含A段、B段和有效性标志
*/
public Map<String, Object> parseUnionId(String unionId) {
Map<String, Object> result = new HashMap<>();
if (unionId == null || !unionId.contains("_") || unionId.length() > 50) {
result.put("isValid", false);
result.put("error", "无效的联盟商品ID格式");
return result;
}
String[] segments = unionId.split("_", 2);
result.put("fullId", unionId);
result.put("aSegment", segments[0]); // 动态部分
result.put("bSegment", segments[1]); // 稳定部分(用于商品去重)
result.put("isValid", true);
return result;
}
}
步骤4:完整接口调用示例(查询商品详情)
创建SpringBoot Controller 或 Service 调用商品详情接口:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.*;
@RestController
@RequestMapping("/api/jd")
public class JdUnionController {
@Autowired
private JdApiClient jdApiClient;
@Autowired
private UnionIdParser unionIdParser;
/**
* 查询商品详情(联盟接口)
* @param unionId 联盟商品ID(动态字符串)
* @param sceneId 场景ID(默认1-常规推广)
* @return 商品详情JSON
*/
@GetMapping("/goods/detail")
public String getGoodsDetail(@RequestParam String unionId,
@RequestParam(defaultValue = "1") String sceneId) {
// 1. 验证联盟ID格式
Map<String, Object> idInfo = unionIdParser.parseUnionId(unionId);
if (!Boolean.TRUE.equals(idInfo.get("isValid"))) {
return "{"error": "联盟商品ID格式无效"}";
}
// 2. 构建业务参数
Map<String, String> bizParams = new HashMap<>();
bizParams.put("unionId", unionId);
bizParams.put("sceneId", sceneId);
// fields参数:指定返回字段(减少数据传输)[citation:5]
bizParams.put("fields", "skuId,title,price,stock,shopName,originalPrice,specs");
// 3. 调用API
String response = jdApiClient.callApi("jd.union.open.goods.detail.query", bizParams);
// 4. 可在此添加业务处理(如解析JSON、存储数据库等)
// 示例:解析价格和库存
try {
Map<String, Object> data = new ObjectMapper().readValue(response, Map.class);
// 根据实际响应结构提取数据(通常嵌套在"data"字段下)
System.out.println("API响应: " + data);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
步骤5:接收京东推送(如订单通知)
京东联盟可能向你的服务器推送订单成交等异步通知(Webhook),你需要提供公网可访问的API接口。以下是一个接收推送的示例:
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@RestController
public class JdWebhookController {
@Value("${jd.union.app-secret}")
private String appSecret;
/**
* 接收京东推送(如订单成交通知)
* 注意:需配置公网域名(如使用Ngrok或云服务器)[citation:2]
* @param request HTTP请求(包含签名参数)
* @return 固定格式响应[citation:2]
*/
@PostMapping("/jd/webhook/order")
public Map<String, Object> handleOrderWebhook(HttpServletRequest request) {
try {
// 1. 获取参数(京东推送参数包含:app_key、method、sign、timestamp等)[citation:2]
String appKey = request.getParameter("app_key");
String sign = request.getParameter("sign");
String timestamp = request.getParameter("timestamp");
// 业务参数(如订单信息)可能通过360buy_param_json传递[citation:2]
String bizJson = request.getParameter("360buy_param_json");
// 2. 签名验证(防止伪造请求)
Map<String, String> params = new HashMap<>();
for (String key : request.getParameterMap().keySet()) {
if (!"sign".equals(key)) {
params.put(key, request.getParameter(key));
}
}
boolean isValid = JdSignatureUtil.generateSign(params, appSecret).equals(sign);
if (!isValid) {
throw new RuntimeException("签名验证失败");
}
// 3. 处理业务逻辑(如解析订单、发送邮件通知等[citation:9])
System.out.println("收到京东推送: " + bizJson);
// 示例:发送邮件通知(可参考实际项目[citation:9])
// emailService.sendOrderNotification(bizJson);
// 4. 返回成功响应(格式必须符合京东要求[citation:2])
return Map.of(
"reponse", Map.of(
"code", "0000",
"data", true,
"uuid", UUID.randomUUID().toString()
)
);
} catch (Exception e) {
return Map.of(
"reponse", Map.of(
"code", "5000",
"errMsg", "处理失败: " + e.getMessage(),
"uuid", UUID.randomUUID().toString()
)
);
}
}
}
三、注意事项
错误处理:
签名错误(返回码1001):检查参数排序、URL编码和AppSecret是否正确。
频率超限:实现动态限流(如缓冲30%空间)。
性能优化:
缓存策略:使用Redis缓存商品静态信息(如标题、品牌),设置5分钟过期。
字段筛选:始终通过 fields 参数指定所需字段,减少网络传输。
实时性处理:京东API价格更新延迟≤3秒,库存≤15秒,适合实时监控场景。
安全与合规:
敏感信息:AppSecret 必须存储在服务器环境变量或配置中心,禁止硬编码在代码中。
推送接口:接收京东推送的服务器需配置HTTPS,并使用签名验证确保安全性。
四、总结
接入京东联盟开放平台,核心在于签名生成、API调用和数据处理。流程上,需要先完成实名认证并获取AppKey/AppSecret。
开发时,应用层面,可利用商品详情接口构建推广工具,或通过订单推送实现自动化通知,采用缓存、限流策略提升性能。
通过以上步骤,开发者可快速搭建一个京东联盟集成应用,实现商品推广、订单跟踪等功能。
谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。
您的一键三连,是我更新的最大动力,谢谢
山水有相逢,来日皆可期,谢谢阅读,我们再会
我手中的金箍棒,上能通天,下能探海