一、接口概述京东开放平台API体系接口名称功能说明应用场景jd.item.get获取单个商品详情商品信息同步、详情展示jd.item.search关键词搜索商品选品、比价系统jd.item.sku获取SKU信息库存管理、价格监控jd.item.price实时价格查询动态定价、促销监控jd.item.comment商品评价获取口碑分析、选品参考item_get接口核心价值┌─────────────────────────────────────────┐ │ 京东商品详情数据维度 │ ├─────────────────────────────────────────┤ │ 基础信息标题、副标题、品牌、类目 │ │ 销售信息价格、促销、库存、销量 │ │ 图文内容主图、详情图、视频、360°展示 │ │ 规格信息SKU矩阵、属性组合、重量尺寸 │ │ 服务信息物流、售后、质保、发票 │ │ 店铺信息店铺评分、资质、客服 │ │ 评价数据好评率、标签、晒单 │ └─────────────────────────────────────────┘二、接口技术规格属性值接口名称jd.item.get/item_get协议HTTPS/REST请求方式GET/POST数据格式JSON字符编码UTF-8认证方式OAuth 2.0 AppKey/Secret签名频率限制5000次/天基础版可申请提升请求参数Data Builder public class JdItemGetRequest { /** 商品SKU ID京东商品唯一标识 */ NotBlank(message SKU ID不能为空) private String skuId; /** 是否需要实时价格默认true */ Builder.Default private Boolean needPrice true; /** 是否需要库存信息默认true */ Builder.Default private Boolean needStock true; /** 是否需要促销信息默认true */ Builder.Default private Boolean needPromotion true; /** 是否需要评价数据默认false节省流量 */ Builder.Default private Boolean needComments false; /** 是否需要详情HTML默认false数据量大 */ Builder.Default private Boolean needDetailHtml false; /** 指定返回字段减少数据传输 */ private String fields; /** 版本号默认2.0 */ Builder.Default private String version 2.0; }三、核心代码实现1. 配置类package com.example.jd.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; Data Component ConfigurationProperties(prefix jd.open) public class JdOpenConfig { /** AppKey */ private String appKey; /** AppSecret */ private String appSecret; /** 接入方式sandbox/production */ private String env sandbox; /** 网关地址 */ private String gatewayUrl https://api.jd.com/routerjson; /** 沙箱地址 */ private String sandboxUrl https://gw.api.sandbox.jd.com/routerjson; /** 默认超时秒 */ private Integer timeout 30; /** 连接池大小 */ private Integer poolSize 20; public String getActualGatewayUrl() { return sandbox.equals(env) ? sandboxUrl : gatewayUrl; } }2. 签名工具类京东TOP协议package com.example.jd.util; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.*; Slf4j Component public class JdSignUtil { private static final DateTimeFormatter TIMESTAMP_FORMATTER DateTimeFormatter.ofPattern(yyyy-MM-dd HH:mm:ss); /** * 构建通用请求参数 */ public MapString, String buildCommonParams(String appKey, String method) { MapString, String params new HashMap(); params.put(app_key, appKey); params.put(method, method); params.put(v, 2.0); params.put(format, json); params.put(timestamp, LocalDateTime.now().format(TIMESTAMP_FORMATTER)); params.put(sign_method, md5); return params; } /** * 生成签名京东TOP协议 * 规则按参数名ASCII排序拼接成字符串首尾加SecretMD5加密 */ public String generateSign(MapString, String params, String appSecret) { // 1. 过滤空值和sign字段 MapString, String filtered new HashMap(); for (Map.EntryString, String entry : params.entrySet()) { String key entry.getKey(); String value entry.getValue(); if (value ! null !value.isEmpty() !sign.equals(key)) { filtered.put(key, value); } } // 2. 按ASCII排序 ListString keys new ArrayList(filtered.keySet()); Collections.sort(keys); // 3. 拼接字符串 StringBuilder sb new StringBuilder(); sb.append(appSecret); // 开头加Secret for (String key : keys) { sb.append(key).append(filtered.get(key)); } sb.append(appSecret); // 结尾加Secret // 4. MD5加密转大写 return md5(sb.toString()).toUpperCase(); } private String md5(String str) { try { MessageDigest md MessageDigest.getInstance(MD5); byte[] bytes md.digest(str.getBytes(StandardCharsets.UTF_8)); StringBuilder sb new StringBuilder(); for (byte b : bytes) { String hex Integer.toHexString(b 0xFF); if (hex.length() 1) { sb.append(0); } sb.append(hex); } return sb.toString(); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(MD5加密失败, e); } } }3. API客户端package com.example.jd.client; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.example.jd.config.JdOpenConfig; import com.example.jd.util.JdSignUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.hc.client5.http.classic.methods.HttpPost; import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.core5.http.HttpEntity; import org.apache.hc.client5.http.config.RequestConfig; import org.apache.hc.core5.http.NameValuePair; import org.apache.hc.core5.http.io.entity.EntityUtils; import org.apache.hc.core5.http.message.BasicNameValuePair; import org.apache.hc.core5.util.Timeout; import org.springframework.stereotype.Component; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; Slf4j Component RequiredArgsConstructor public class JdApiClient { private final JdOpenConfig config; private final JdSignUtil signUtil; private final CloseableHttpClient httpClient; public JdApiClient(JdOpenConfig config, JdSignUtil signUtil) { this.config config; this.signUtil signUtil; // 配置连接池和超时 RequestConfig requestConfig RequestConfig.custom() .setConnectTimeout(Timeout.ofSeconds(config.getTimeout())) .setResponseTimeout(Timeout.ofSeconds(config.getTimeout())) .build(); this.httpClient HttpClients.custom() .setDefaultRequestConfig(requestConfig) .setMaxConnTotal(config.getPoolSize()) .setMaxConnPerRoute(config.getPoolSize()) .build(); } /** * 执行API调用 */ public JSONObject execute(String method, MapString, String bizParams) { try { // 1. 构建公共参数 MapString, String params signUtil.buildCommonParams( config.getAppKey(), method); // 2. 添加业务参数JSON格式 if (bizParams ! null !bizParams.isEmpty()) { params.put(360buy_param_json, JSON.toJSONString(bizParams)); } // 3. 生成签名 String sign signUtil.generateSign(params, config.getAppSecret()); params.put(sign, sign); // 4. 构建HTTP请求 HttpPost httpPost new HttpPost(config.getActualGatewayUrl()); ListNameValuePair formParams new ArrayList(); for (Map.EntryString, String entry : params.entrySet()) { formParams.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); } httpPost.setEntity(new UrlEncodedFormEntity(formParams, StandardCharsets.UTF_8)); // 5. 执行请求 log.debug(调用京东API: method{}, params{}, method, params); try (CloseableHttpResponse response httpClient.execute(httpPost)) { HttpEntity entity response.getEntity(); String result EntityUtils.toString(entity, StandardCharsets.UTF_8); log.debug(API响应: {}, result); JSONObject jsonResult JSON.parseObject(result); // 6. 检查错误 if (jsonResult.containsKey(error_response)) { JSONObject error jsonResult.getJSONObject(error_response); String code error.getString(code); String msg error.getString(zh_desc); throw new JdApiException(code, msg); } return jsonResult; } } catch (Exception e) { log.error(调用京东API失败: method{}, method, e); throw new RuntimeException(京东API调用失败: e.getMessage(), e); } } }4. 商品服务层核心package com.example.jd.service; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.example.jd.client.JdApiClient; import com.example.jd.config.JdOpenConfig; import com.example.jd.model.*; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; Slf4j Service RequiredArgsConstructor public class JdItemService { private static final String API_METHOD jd.item.get; private static final String CACHE_NAME jd:item; private final JdApiClient apiClient; private final JdOpenConfig config; /** * 获取商品详情带缓存 */ Cacheable(value CACHE_NAME, key #skuId, unless #result null) public JdItemDetail getItemDetail(String skuId) { return getItemDetail(skuId, JdItemGetRequest.builder().build()); } /** * 获取商品详情自定义参数 */ public JdItemDetail getItemDetail(String skuId, JdItemGetRequest request) { log.info(获取京东商品详情, skuId: {}, skuId); try { // 构建业务参数 MapString, String bizParams new HashMap(); bizParams.put(skuId, skuId); // 可选字段控制 if (!request.getNeedPrice()) { bizParams.put(fields, basic,sku,shop); // 排除价格 } // 调用API JSONObject response apiClient.execute(API_METHOD, bizParams); // 解析响应 JSONObject result response.getJSONObject(API_METHOD.replace(., _) _responce); if (result null) { result response.getJSONObject(jingdong_item_get_responce); } if (result null || result.getJSONObject(item) null) { throw new RuntimeException(商品不存在或已下架); } JSONObject itemJson result.getJSONObject(item); return parseItemDetail(itemJson); } catch (Exception e) { log.error(获取商品详情失败, skuId: {}, skuId, e); throw new RuntimeException(获取商品详情失败: e.getMessage()); } } /** * 批量获取商品详情 */ public ListJdItemDetail getItemDetailsBatch(ListString skuIds) { return skuIds.parallelStream() .map(skuId - { try { return getItemDetail(skuId); } catch (Exception e) { log.error(批量获取失败, skuId: {}, skuId, e); return null; } }) .filter(Objects::nonNull) .collect(Collectors.toList()); } /** * 解析商品详情JSON */ private JdItemDetail parseItemDetail(JSONObject json) { JdItemDetail item new JdItemDetail(); // 基础信息 item.setSkuId(json.getString(skuId)); item.setSpuId(json.getString(spuId)); item.setName(json.getString(name)); item.setSubTitle(json.getString(subTitle)); item.setBrandName(json.getString(brandName)); item.setBrandId(json.getString(brandId)); item.setCategoryId(json.getString(catId)); item.setCategoryName(json.getString(category)); // 价格信息 PriceInfo priceInfo new PriceInfo(); priceInfo.setOriginalPrice(json.getBigDecimal(marketPrice)); priceInfo.setCurrentPrice(json.getBigDecimal(jdPrice)); priceInfo.setPlusPrice(json.getBigDecimal(plusPrice)); // Plus会员价 priceInfo.setPromotionPrice(json.getBigDecimal(pPrice)); // 促销价 // 计算折扣 if (priceInfo.getOriginalPrice() ! null priceInfo.getCurrentPrice() ! null priceInfo.getOriginalPrice().compareTo(BigDecimal.ZERO) 0) { priceInfo.setDiscountRate(priceInfo.getCurrentPrice() .divide(priceInfo.getOriginalPrice(), 2, BigDecimal.ROUND_HALF_UP)); } item.setPriceInfo(priceInfo); // 库存信息 StockInfo stockInfo new StockInfo(); stockInfo.setStockState(json.getInteger(stockState)); // 33-现货 34-无货 40-可配货 stockInfo.setStockStateName(json.getString(stockStateName)); stockInfo.setStockNum(json.getInteger(stockNum)); stockInfo.setIsStock(json.getBoolean(isStock)); item.setStockInfo(stockInfo); // 图片信息 Images images new Images(); images.setMainImage(json.getString(image)); images.setImageList(json.getList(imageList, String.class)); images.setDetailImages(json.getList(detailImages, String.class)); images.setVideoUrl(json.getString(videoUrl)); item.setImages(images); // SKU规格 if (json.containsKey(skuInfo)) { JSONObject skuJson json.getJSONObject(skuInfo); SkuInfo skuInfo new SkuInfo(); skuInfo.setSkuId(skuJson.getString(skuId)); skuInfo.setSkuName(skuJson.getString(skuName)); // 规格属性 ListSkuProp props new ArrayList(); if (skuJson.containsKey(propCodeList)) { JSONArray propArray skuJson.getJSONArray(propCodeList); for (int i 0; i propArray.size(); i) { JSONObject prop propArray.getJSONObject(i); props.add(SkuProp.builder() .propId(prop.getString(propId)) .propName(prop.getString(propName)) .propValue(prop.getString(propValue)) .build()); } } skuInfo.setProps(props); item.setSkuInfo(skuInfo); } // 店铺信息 ShopInfo shopInfo new ShopInfo(); shopInfo.setShopId(json.getString(shopId)); shopInfo.setShopName(json.getString(shopName)); shopInfo.setShopScore(json.getBigDecimal(shopScore)); shopInfo.setShopLevel(json.getString(shopLevel)); item.setShopInfo(shopInfo); // 服务信息 ServiceInfo serviceInfo new ServiceInfo(); serviceInfo.setIsSelfSupport(json.getBoolean(isSelf)); // 是否自营 serviceInfo.setIsGlobalPurchase(json.getBoolean(isGlobalPurchase)); // 是否全球购 serviceInfo.setIsFresh(json.getBoolean(isFresh)); // 是否生鲜 serviceInfo.setIsSevenDayReturn(json.getBoolean(is7ToReturn)); // 7天无理由 item.setServiceInfo(serviceInfo); // 销售数据 SalesData salesData new SalesData(); salesData.setCommentCount(json.getInteger(commentCount)); salesData.setGoodRate(json.getBigDecimal(goodRate)); salesData.setSalesCount(json.getInteger(salesCount)); item.setSalesData(salesData); // 物流信息 item.setWeight(json.getBigDecimal(weight)); item.setProductArea(json.getString(productArea)); // 产地 // 时间戳 item.setFetchTime(LocalDateTime.now()); return item; } }5. 数据模型类package com.example.jd.model; import com.alibaba.fastjson2.annotation.JSONField; import lombok.Builder; import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; Data public class JdItemDetail { /** 基础信息 */ private String skuId; // SKU ID private String spuId; // SPU ID private String name; // 商品名称 private String subTitle; // 副标题 private String brandName; // 品牌名 private String brandId; // 品牌ID private String categoryId; // 类目ID private String categoryName; // 类目名称 /** 价格信息 */ private PriceInfo priceInfo; /** 库存信息 */ private StockInfo stockInfo; /** 图片信息 */ private Images images; /** SKU规格 */ private SkuInfo skuInfo; /** 店铺信息 */ private ShopInfo shopInfo; /** 服务信息 */ private ServiceInfo serviceInfo; /** 销售数据 */ private SalesData salesData; /** 物流信息 */ private BigDecimal weight; // 重量(kg) private String productArea; // 产地 /** 元数据 */ JSONField(serialize false) private LocalDateTime fetchTime; // 子类定义 Data public static class PriceInfo { private BigDecimal originalPrice; // 市场价 private BigDecimal currentPrice; // 京东价 private BigDecimal plusPrice; // Plus会员价 private BigDecimal promotionPrice; // 促销价 private BigDecimal discountRate; // 折扣率 } Data public static class StockInfo { private Integer stockState; // 库存状态码 private String stockStateName; // 库存状态名 private Integer stockNum; // 库存数量 private Boolean isStock; // 是否有库存 } Data public static class Images { private String mainImage; // 主图 private ListString imageList; // 图片列表 private ListString detailImages; // 详情图 private String videoUrl; // 视频地址 } Data public static class SkuInfo { private String skuId; private String skuName; private ListSkuProp props; // 规格属性 } Data Builder public static class SkuProp { private String propId; private String propName; private String propValue; } Data public static class ShopInfo { private String shopId; private String shopName; private BigDecimal shopScore; // 店铺评分 private String shopLevel; // 店铺等级 } Data public static class ServiceInfo { private Boolean isSelfSupport; // 京东自营 private Boolean isGlobalPurchase; // 全球购 private Boolean isFresh; // 生鲜 private Boolean isSevenDayReturn; // 7天无理由 } Data public static class SalesData { private Integer commentCount; // 评价数 private BigDecimal goodRate; // 好评率 private Integer salesCount; // 销量 } }四、API响应示例成功响应{ jingdong_item_get_responce: { item: { skuId: 100012043978, spuId: 100009077475, name: Apple iPhone 15 Pro Max (256GB) 蓝色钛金属, subTitle: 支持移动联通电信5G 双卡双待手机, brandName: Apple, brandId: 15126, catId: 9987,653,655, category: 手机通讯手机5G手机, marketPrice: 9999.00, jdPrice: 8999.00, plusPrice: 8899.00, pPrice: 8799.00, stockState: 33, stockStateName: 现货, stockNum: 5000, isStock: true, image: https://img10.360buyimg.com/n1/...jpg, imageList: [ https://img10.360buyimg.com/n1/...jpg, https://img10.360buyimg.com/n1/...jpg ], shopId: 1000000127, shopName: 京东自营, shopScore: 9.8, isSelf: true, isGlobalPurchase: false, is7ToReturn: true, commentCount: 500000, goodRate: 0.98, weight: 0.221, productArea: 中国, skuInfo: { skuId: 100012043978, skuName: 256GB 蓝色钛金属, propCodeList: [ { propId: 100004, propName: 机身颜色, propValue: 蓝色钛金属 }, { propId: 100005, propName: 存储容量, propValue: 256GB } ] } } } }错误响应{ error_response: { code: 100, zh_desc: 商品不存在或已下架, en_desc: Item not found } }五、使用示例Controller层package com.example.jd.controller; import com.example.jd.model.JdItemDetail; import com.example.jd.model.JdItemGetRequest; import com.example.jd.service.JdItemService; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; import java.util.List; RestController RequestMapping(/api/jd/item) RequiredArgsConstructor public class JdItemController { private final JdItemService itemService; /** * 获取商品详情 * GET /api/jd/item/100012043978 */ GetMapping(/{skuId}) public JdItemDetail getItem(PathVariable String skuId) { return itemService.getItemDetail(skuId); } /** * 批量获取商品详情 * POST /api/jd/item/batch */ PostMapping(/batch) public ListJdItemDetail getItemsBatch(RequestBody ListString skuIds) { return itemService.getItemDetailsBatch(skuIds); } /** * 获取商品详情自定义参数 * GET /api/jd/item/100012043978?needPricefalseneedStocktrue */ GetMapping(/{skuId}/custom) public JdItemDetail getItemCustom( PathVariable String skuId, RequestParam(defaultValue true) Boolean needPrice, RequestParam(defaultValue true) Boolean needStock) { JdItemGetRequest request JdItemGetRequest.builder() .needPrice(needPrice) .needStock(needStock) .build(); return itemService.getItemDetail(skuId, request); } }六、进阶应用场景1. 价格监控与预警Service public class JdPriceMonitorService { Autowired private JdItemService itemService; Autowired private AlertService alertService; /** * 价格监控任务 */ Scheduled(fixedRate 3600000) // 每小时 public void monitorPriceChanges() { ListMonitoredItem items monitorRepository.findAll(); items.parallelStream().forEach(item - { try { JdItemDetail current itemService.getItemDetail(item.getSkuId()); BigDecimal currentPrice current.getPriceInfo().getCurrentPrice(); // 价格变动检测 BigDecimal changeRate currentPrice.subtract(item.getLastPrice()) .divide(item.getLastPrice(), 4, RoundingMode.HALF_UP); if (changeRate.abs().compareTo(new BigDecimal(0.05)) 0) { alertService.sendPriceAlert(PriceAlert.builder() .skuId(item.getSkuId()) .name(current.getName()) .oldPrice(item.getLastPrice()) .newPrice(currentPrice) .changeRate(changeRate) .type(changeRate.signum() 0 ? 涨价 : 降价) .build()); } // 库存预警 if (!current.getStockInfo().getIsStock()) { alertService.sendStockAlert(StockAlert.builder() .skuId(item.getSkuId()) .name(current.getName()) .message(商品已断货) .build()); } // 更新记录 item.setLastPrice(currentPrice); item.setLastCheckTime(LocalDateTime.now()); monitorRepository.save(item); } catch (Exception e) { log.error(监控失败: {}, item.getSkuId(), e); } }); } }2. 竞品分析与选品Service public class JdCompetitorAnalysisService { /** * 竞品分析 */ public CompetitorReport analyzeCompetitor(String skuId) { JdItemDetail item itemService.getItemDetail(skuId); return CompetitorReport.builder() .skuId(skuId) .name(item.getName()) .pricePosition(analyzePricePosition(item)) .competitiveIndex(calculateCompetitiveIndex(item)) .marketGap(identifyMarketGap(item)) .suggestedPricing(generatePricingSuggestion(item)) .build(); } /** * 计算竞争力指数 */ private double calculateCompetitiveIndex(JdItemDetail item) { double score 0; // 价格竞争力30% if (item.getPriceInfo().getDiscountRate() ! null) { score item.getPriceInfo().getDiscountRate().doubleValue() * 0.3; } // 口碑竞争力30% if (item.getSalesData().getGoodRate() ! null) { score item.getSalesData().getGoodRate().doubleValue() * 0.3; } // 库存竞争力20% score (item.getStockInfo().getIsStock() ? 1.0 : 0.0) * 0.2; // 自营背书20% score (item.getServiceInfo().getIsSelfSupport() ? 1.0 : 0.5) * 0.2; return score; } }3. 与ERP/电商系统对接Service public class JdErpIntegrationService { /** * 同步商品到ERP */ public void syncToErp(String skuId) { JdItemDetail jdItem itemService.getItemDetail(skuId); // 转换为ERP商品模型 ErpProduct erpProduct ErpProduct.builder() .externalSkuId(jdItem.getSkuId()) .externalSpuId(jdItem.getSpuId()) .name(jdItem.getName()) .brand(jdItem.getBrandName()) .categoryPath(jdItem.getCategoryName()) .purchasePrice(jdItem.getPriceInfo().getCurrentPrice()) .suggestedRetailPrice(jdItem.getPriceInfo().getOriginalPrice()) .weight(jdItem.getWeight()) .origin(jdItem.getProductArea()) .mainImage(jdItem.getImages().getMainImage()) .specifications(convertSpecs(jdItem.getSkuInfo())) .supplierType(jdItem.getServiceInfo().getIsSelfSupport() ? JD_SELF : JD_POP) .build(); erpProductService.saveOrUpdate(erpProduct); } }七、关键注意事项注意点解决方案频率限制本地缓存队列削峰避免触发限流数据一致性京东价格实时变动关键场景需实时查询SKU vs SPU京东以SKU为最小单位注意区分自营vsPOP自营商品API数据更完整POP店铺数据可能缺失区域库存库存分仓需指定地区查询促销复杂性价格可能含多重促销需解析promotion字段八、配置示例application.ymljd: open: app-key: ${JD_APP_KEY} app-secret: ${JD_APP_SECRET} env: production # sandbox/production gateway-url: https://api.jd.com/routerjson sandbox-url: https://gw.api.sandbox.jd.com/routerjson timeout: 30 pool-size: 20 spring: cache: type: redis redis: time-to-live: 600000 # 10分钟缓存