java查询顺丰路由(物流详情)信息

(参考了 https://www.cnblogs.com/lihao1017/p/17361972.html 这篇文章)

最终返回的参数如图:
在这里插入图片描述
写一下自己的笔记~

1.先在“顺丰开放平台”注册账号并进行实名认证

顺丰开放平台:https://open.sf-express.com/
不会的还可以跟着教程去操作,非常详细
在这里插入图片描述
认证成功后可以得到 顾客编码、沙箱验证码、生产校验码:
在这里插入图片描述

2.去业务中心创建开发者应用并测试以及上线

在这里插入图片描述
创建自己的应用,然后点进去关联API
选择自己需要的API 这里我只需要查询物流的信息,于是只需要关联“路由查询接口”
在这里插入图片描述
然后点后面的“测试”,注意不要自己去点到那个测试页面进行测试,一定是从这里点进去!
在这里插入图片描述

测试的那个校验码就是你的沙箱校验码,请求参数就用它默认的参数不用改
参数就用它默认的参数,不用改

测试好了之后也要记得回到上面那个地方还要测试一遍,记得也是从后面那个测试按钮点进去,后面这一遍测试的校验码是生产校验码了
最后还要回到这个地方,点击“上线”,这样你的接口就可以用了
【!!!注意,如果没有点击上线的话,接口会报没有权限!】
上线之后是这样的:
在这里插入图片描述
至此,这里就配置好了,接下来准备自己的项目部分

3.下载SDK,然后将jar包导进自己的项目里

SDK下载地址:https://open.sf-express.com/developSupport/976720?activeIndex=399112
直接下载最新版本就行
然后打开下载下来的压缩包,点进去找到里面的jar包,导进自己的项目里
在这里插入图片描述
将jar包导进项目的方法可参考:https://blog.youkuaiyun.com/m0_73900214/article/details/131400180
这一步也可以替换成引入依赖:

        <!--顺丰-->
        <dependency>
            <groupId>com.sf.csim</groupId>
            <artifactId>SF-CSIM-EXPRESS-SDK</artifactId>
            <version>0.0.1</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/SF-CSIM-EXPRESS-SDK-V2.1.7.jar</systemPath>
        </dependency>

4.开始写代码

1.顺丰配置类

/**
 * @author 
 * @date 
 * @desc 顺丰快递 丰桥接口配置类
 */
@Data
public class ShunFengConfig {
    public static String CLIENT_CODE = "";  //此处替换为您在丰桥平台获取的顾客编码
    public static String CHECK_WORD = "";//生产校验码
    public static String CHECK_WORD_BOX = "";//沙箱校验码

    //沙箱环境的地址 -PRO
    public static String CALL_URL_BOX = "https://sfapi-sbox.sf-express.com/std/service";
    //生产环境的地址 -PRO
    public static String CALL_URL_PROD = "https://sfapi.sf-express.com/std/service";
}

2.核心业务代码

/**
     * 查询顺丰路由信息
     * @param id 顺丰快递单号
     * @param phone 收件人手机号后四位
     * @return
     * @throws UnsupportedEncodingException
     */
    public JSONObject sfRoutes(String id, String phone) throws UnsupportedEncodingException {
        IServiceCodeStandard standardService = ExpressServiceCodeEnum.EXP_RECE_SEARCH_ROUTES;//查路由

        // set common header
        Map<String, String> params = new HashMap<String, String>();
        String timeStamp = String.valueOf(System.currentTimeMillis());
        String msgData ="{\"trackingType\":1,\"trackingNumber\":[\""+id+"\"],\"checkPhoneNo\":\""+phone+"\"}";//无月结卡号通过运单和手机后4位即可
        params.put("partnerID", ShunFengConfig.CLIENT_CODE);  // 顾客编码 ,对应丰桥上获取的clientCode
        params.put("requestID", UUID.randomUUID().toString().replace("-", ""));
        params.put("serviceCode",standardService.getCode());// 接口服务码
        params.put("timestamp", timeStamp);
        params.put("msgData", msgData);
        params.put("msgDigest", CallExpressServiceTools.getMsgDigest(msgData,timeStamp,ShunFengConfig.CHECK_WORD));

        long startTime = System.currentTimeMillis();

        log.debug("====调用实际请求:" + params);
        String result = HttpClientUtil.post(ShunFengConfig.CALL_URL_PROD, params);

        log.debug("====调用丰桥的接口服务代码:" + (standardService.getCode()) + " 接口耗时:"+ (System.currentTimeMillis()-startTime)+"====");
        log.debug("===调用地址 ==="+ShunFengConfig.CALL_URL_PROD);
        log.debug("===顾客编码 ==="+ShunFengConfig.CLIENT_CODE);
        log.debug("===返回结果:" +result);
        JSONObject apiResultData = JSONUtil.parseObj(JSONUtil.parseObj(result).get("apiResultData"));
        if(!apiResultData.getBool("success")){
            throw new BizException(ResultStatus.Common.ERROR_ADD_FAIL);
        }
        JSONObject resultMsgData = JSONUtil.parseObj(apiResultData.get("msgData"));
        JSONArray routeResps = JSONUtil.parseArray(resultMsgData.get("routeResps"));
        JSONObject routeRespsObj = routeResps.getJSONObject(0);
        return routeRespsObj;
    }

3.接口调用

    @ApiOperation(value = "获取顺丰快递物流")
    @PostMapping("/sfRoutes")
    public JSONObject sfRoutes(@RequestBody QuerySfRoutesReq req) throws UnsupportedEncodingException {
        return service.sfRoutes(req.getTrackingNumber(), req.getPhone());
    }
@Data
public class QuerySfRoutesReq {

    @ApiModelProperty("快递单号")
    private String trackingNumber;
    @ApiModelProperty("手机号码后四位")
    private String phone;
}

4.测试
在这里插入图片描述
搞定!

<think>好的,我现在需要帮助用户用Java实现定时获取顺丰物流路由信息。首先,用户提到了定时任务和API调用,所以我得考虑这两部分怎么结合。 用户的需求是定时获取物流信息Java中常用的定时任务框架有Spring的@Scheduled注解、Quartz等。Spring的@Scheduled比较简单,适合快速集成,可能用户会更倾向于这个选择。所以首先确定使用Spring的定时任务。 接下来是调用顺丰的API。用户需要示例代码,所以得先确认顺丰是否提供公开的物流查询API。根据用户提供的引用[1],里面提到有很多API接口,可能包括快递查询。但顺丰的API通常需要授权,比如API key或者商户认证,所以用户可能需要先注册顺丰开放平台账号,获取必要的认证信息。 假设用户已经注册并获取了API key和客户编码,接下来需要构造请求。顺丰的API可能有特定的参数要求,比如运单号、时间戳、数字签名等。数字签名部分可能需要按照顺丰的文档生成,通常是用MD5或者SHA对参数进行加密。 然后,发送HTTP请求。Java中常用的有HttpClient或者OkHttp,这里示例中使用HttpClient比较合适。需要处理GET或POST请求,顺丰的API可能要求POST方式,传递JSON或表单数据。 接收响应后,解析JSON数据。使用Jackson或者Gson库来处理JSON,提取物流路由信息。 在代码示例中,需要包含定时任务的配置,比如在Spring Boot中启用定时任务,然后编写一个方法,使用@Scheduled注解设置执行频率。在方法内部,调用API并处理响应。 还要考虑异常处理,比如网络问题、API限制、数据解析错误等,确保程序稳定性。日志记录也很重要,方便排查问题。 最后,提醒用户注意事项,比如API调用频率限制、参数的正确性、安全存储密钥等。可能还需要提供顺丰开放平台的文档链接,方便用户查阅具体参数和认证方式。 现在组织代码结构,先写定时任务的配置类,再写API调用的服务类,处理请求和响应。示例代码需要简洁,关键部分如签名生成和HTTP请求要清晰,用户可以根据实际情况调整参数和逻辑。</think>### 分步解答 #### 1. 获取顺丰物流API权限 - 注册顺丰开放平台账号,获取`API Key`和`客户编码`(参考顺丰开放平台文档) - 开通物流路由查询接口权限(例如`EXP_RECE_SEARCH_ROUTES`) #### 2. Java定时任务实现 ##### 2.1 添加依赖(Maven) ```xml <!-- Spring Boot定时任务 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <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> <version>2.13.3</version> </dependency> ``` ##### 2.2 定时任务配置类 ```java @Configuration @EnableScheduling public class SchedulerConfig { // 定时任务已启用 } ``` ##### 2.3 核心服务类 ```java @Service public class SfExpressService { private static final String API_URL = "https://sfapi.sf-express.com/service/router"; private static final String API_KEY = "your_api_key"; private static final String CUSTOMER_CODE = "your_customer_code"; @Scheduled(fixedRate = 60000) // 每分钟执行一次 public void queryExpressRoutes() { String trackingNumber = "SF1234567890"; Map<String, String> params = buildRequestParams(trackingNumber); String response = sendPostRequest(API_URL, params); processResponse(response); } private Map<String, String> buildRequestParams(String trackingNumber) { Map<String, String> params = new HashMap<>(); params.put("method", "EXP_RECE_SEARCH_ROUTES"); params.put("customerCode", CUSTOMER_CODE); params.put("waybillNo", trackingNumber); params.put("requestTime", String.valueOf(System.currentTimeMillis())); params.put("msgData", generateMsgData(trackingNumber)); params.put("checkCode", generateCheckCode(params)); return params; } private String generateCheckCode(Map<String, String> params) { // 根据顺丰规则生成签名(示例为MD5加密) String original = params.get("msgData") + API_KEY + params.get("requestTime"); return DigestUtils.md5Hex(original); } private String generateMsgData(String trackingNumber) { // 构建JSON格式消息体 return "{\"trackingNumber\":\"" + trackingNumber + "\"}"; } private String sendPostRequest(String url, Map<String, String> params) { try (CloseableHttpClient httpClient = HttpClients.createDefault()) { HttpPost httpPost = new HttpPost(url); List<NameValuePair> formParams = params.entrySet().stream() .map(e -> new BasicNameValuePair(e.getKey(), e.getValue())) .collect(Collectors.toList()); httpPost.setEntity(new UrlEncodedFormEntity(formParams, "UTF-8")); try (CloseableHttpResponse response = httpClient.execute(httpPost)) { return EntityUtils.toString(response.getEntity()); } } catch (IOException e) { throw new RuntimeException("API请求失败", e); } } private void processResponse(String jsonResponse) { try { ObjectMapper mapper = new ObjectMapper(); JsonNode root = mapper.readTree(jsonResponse); if (root.path("success").asBoolean()) { JsonNode routes = root.path("routes"); routes.forEach(this::parseRouteInfo); } } catch (JsonProcessingException e) { System.err.println("响应解析失败:" + e.getMessage()); } } private void parseRouteInfo(JsonNode node) { String time = node.path("time").asText(); String description = node.path("description").asText(); System.out.println(time + " - " + description); } } ``` #### 3. 注意事项 1. 需要替换`API_KEY`和`CUSTOMER_CODE`为实际值 2. 签名生成规则请以顺丰官方文档为准[^1] 3. 建议添加重试机制和异常处理 4. 注意API调用频率限制(参考顺丰API文档) 5. 敏感信息建议使用配置中心管理[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值