阿里云网站备案多久隆尧企业做网站
阿里云网站备案多久,隆尧企业做网站,网站建设执行力,linux wordpress配置要实现Java系统与云洋聚合跑腿系统的无缝对接#xff0c;需基于云洋提供的开放API完成认证鉴权、订单推送、状态同步、异常处理等核心流程。以下是技术实现方案#xff0c;涵盖对接架构、关键代码示例及异常处理机制。一、对接架构设计1. 系统交互流程mermaidsequenceDiagram…要实现Java系统与云洋聚合跑腿系统的无缝对接需基于云洋提供的开放API完成认证鉴权、订单推送、状态同步、异常处理等核心流程。以下是技术实现方案涵盖对接架构、关键代码示例及异常处理机制。一、对接架构设计1.系统交互流程mermaidsequenceDiagram participant Java系统 participant 云洋API网关 participant 云洋调度系统 participant 骑手端 Java系统-云洋API网关: 1. 获取Access TokenOAuth2.0 云洋API网关--Java系统: 返回Token Java系统-云洋API网关: 2. 创建跑腿订单POST /api/v1/orders 云洋API网关-云洋调度系统: 3. 订单分发给骑手 云洋调度系统--骑手端: 4. 推送订单 骑手端--云洋调度系统: 5. 更新订单状态接单/取件/送达 云洋调度系统-云洋API网关: 6. 状态回调通知 云洋API网关-Java系统: 7. Webhook回调订单状态2.技术组件选型HTTP客户端OkHttp异步非阻塞或Spring RestTemplate签名工具HmacSHA256生成API请求签名异步通知Netty处理云洋Webhook回调熔断降级Hystrix或Resilience4j防止调用云洋API超时阻塞二、核心对接实现1.认证鉴权OAuth2.0云洋通常采用AppKey AppSecret生成签名示例代码java// 生成API请求签名HmacSHA256 public String generateSign(String appSecret, MapString, String params) { // 1. 参数按字典序排序 String sortedParams params.entrySet().stream() .sorted(Map.Entry.comparingByKey()) .map(e - e.getKey() e.getValue()) .collect(Collectors.joining()); // 2. 拼接AppSecret String signString appSecret sortedParams appSecret; // 3. HmacSHA256加密 try { Mac sha256 Mac.getInstance(HmacSHA256); sha256.init(new SecretKeySpec(appSecret.getBytes(), HmacSHA256)); byte[] hash sha256.doFinal(signString.getBytes()); return Base64.getEncoder().encodeToString(hash); } catch (Exception e) { throw new RuntimeException(签名生成失败, e); } } // 获取Access Token public String getAccessToken(String appKey, String appSecret) { String url https://api.yunyang.com/oauth/token; MapString, String params new HashMap(); params.put(app_key, appKey); params.put(timestamp, String.valueOf(System.currentTimeMillis())); params.put(sign, generateSign(appSecret, params)); // 发送POST请求 OkHttpClient client new OkHttpClient(); RequestBody body RequestBody.create( MediaType.parse(application/x-www-form-urlencoded), params.entrySet().stream() .map(e - e.getKey() e.getValue()) .collect(Collectors.joining()) ); Request request new Request.Builder() .url(url) .post(body) .build(); try (Response response client.newCall(request).execute()) { JSONObject json new JSONObject(response.body().string()); return json.getString(access_token); } catch (IOException e) { throw new RuntimeException(获取Token失败, e); } }2.创建跑腿订单java// 调用云洋API创建订单 public String createOrder(String accessToken, OrderRequest request) { String url https://api.yunyang.com/api/v1/orders; // 构建请求体示例为JSON格式 JSONObject json new JSONObject(); json.put(order_no, request.getOrderNo()); // 商户订单号 json.put(service_type, request.getServiceType()); // 跑腿类型代购/代办/即时送 json.put(pickup_address, request.getPickupAddress()); json.put(delivery_address, request.getDeliveryAddress()); json.put(goods_info, request.getGoodsInfo()); // 商品描述 json.put(expect_time, request.getExpectTime()); // 期望送达时间 // 添加签名云洋可能要求签名包含Token MapString, String signParams new HashMap(json.toMap()); signParams.put(access_token, accessToken); signParams.put(sign, generateSign(appSecret, signParams)); // 发送请求 OkHttpClient client new OkHttpClient(); RequestBody body RequestBody.create( MediaType.parse(application/json), json.toString() ); Request req new Request.Builder() .url(url) .post(body) .addHeader(Authorization, Bearer accessToken) .build(); try (Response response client.newCall(req).execute()) { JSONObject result new JSONObject(response.body().string()); if (result.getInt(code) ! 200) { throw new RuntimeException(创建订单失败: result.getString(message)); } return result.getString(order_id); // 返回云洋订单ID } catch (IOException e) { throw new RuntimeException(调用云洋API失败, e); } }3.处理Webhook回调云洋会通过Webhook推送订单状态变更需实现签名验证java// 验证Webhook签名 public boolean verifyWebhookSign(HttpServletRequest request, String appSecret) { String sign request.getHeader(X-Yunyang-Sign); String timestamp request.getHeader(X-Yunyang-Timestamp); String nonce request.getHeader(X-Yunyang-Nonce); // 1. 获取请求体需先读取BodySpring中需用过滤器缓存 String body getRequestBody(request); // 自定义方法读取请求体 // 2. 按云洋规则拼接字符串 String stringToSign timestamp nonce body appSecret; // 3. 生成本地签名 String localSign DigestUtils.sha256Hex(stringToSign); // Apache Commons Codec return Objects.equals(sign, localSign); } // Webhook处理端点Spring MVC PostMapping(/api/yunyang/webhook) public ResponseEntity? handleWebhook(HttpServletRequest request) { try { if (!verifyWebhookSign(request, appSecret)) { return ResponseEntity.status(403).body(签名验证失败); } // 解析云洋推送的数据 String body getRequestBody(request); JSONObject json new JSONObject(body); String eventType json.getString(event_type); // 订单状态变更事件 String orderId json.getString(order_id); // 更新本地订单状态 if (ORDER_ACCEPTED.equals(eventType)) { orderService.updateStatus(orderId, OrderStatus.RIDER_ACCEPTED); } else if (ORDER_PICKED_UP.equals(eventType)) { orderService.updateStatus(orderId, OrderStatus.PICKED_UP); } // ...其他状态处理 return ResponseEntity.ok(success); } catch (Exception e) { log.error(处理Webhook失败, e); return ResponseEntity.status(500).body(处理失败); } }三、关键注意事项1.幂等性处理云洋可能重复推送Webhook需通过订单ID 状态变更时间戳去重示例Redis存储已处理的状态变更记录Key为order:${orderId}:status2.异常重试机制对云洋API调用失败的情况如网络超时使用指数退避重试java// 使用Resilience4j重试 RetryConfig config RetryConfig.custom() .maxAttempts(3) .waitDuration(Duration.ofSeconds(2)) .build(); SupplierString supplier Retry.decorateSupplier( config, () - createOrder(accessToken, request) ); try { String orderId supplier.get(); } catch (Exception e) { // 触发降级逻辑如切换至备用跑腿平台 }3.对账机制每日定时任务比对本地订单与云洋订单状态差异项自动报警示例SQLsqlSELECT local.order_no FROM local_orders local LEFT JOIN yunyang_orders yy ON local.order_no yy.merchant_order_no WHERE local.status ! yy.status OR yy.order_id IS NULL;四、云洋API对接常见问题问题解决方案签名失败检查时间戳是否在云洋允许的偏差范围内通常±5分钟订单状态不同步启用云洋的主动查询接口如GET /api/v1/orders/{orderId}作为补充骑手联系不上用户在创建订单时传递用户联系方式的加密字段云洋可能提供脱敏处理方案费用结算差异定期导出云洋账单与本地订单金额比对差异项人工核查五、总结通过Java实现与云洋聚合跑腿系统的对接核心步骤包括OAuth2.0认证获取Access Token签名算法确保请求合法性异步Webhook处理订单状态变更熔断重试保障高可用性建议封装云洋API调用为独立的SDK模块对外提供统一接口如YunyangClient.createOrder()降低业务系统与第三方平台的耦合度。