欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java 对接快递100 实现快递实时查询 (自动识别快递公司)

程序员文章站 2024-03-26 13:16:53
...

一、相关资料

快递100 API官网: https://api.kuaidi100.com/home
·

注意事项

必须先进行企业注册才可以使用

Java 对接快递100 实现快递实时查询 (自动识别快递公司)
·

需要用到的接口

Java 对接快递100 实现快递实时查询 (自动识别快递公司)

·

查询费用说明

查询类接口按单收费,一个自然月内同一个运单多次查询只收一次费用。

Java 对接快递100 实现快递实时查询 (自动识别快递公司)

二、代码部分

目录结构
Java 对接快递100 实现快递实时查询 (自动识别快递公司)

1、http 调用 KuaiDi100Util

package com.ws.ldy.others.kuaidi.kuaidi100.util;

import com.alibaba.fastjson.JSON;
import com.ws.ldy.others.kuaidi.kuaidi100.entity.KuaiDiCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 顺丰快递 Api 接口对接, 官网文档-零担下单: https://freight.sf-express.com/api/api.html#id=30
 * <P>
 * 请求头必须添加: "Content-type","application/x-www-form-urlencoded;charset=UTF-8”
 *
 * </P>
 * @author wangsong
 * @mail aaa@qq.com
 * @date 2020/9/9 0009 9:38
 * @version 1.0.0
 */
@SuppressWarnings("all")
@Component
@Slf4j
public class KuaiDi100Util {

    @Autowired
    private RestTemplate restTemplate;
    /**
     * 智能识别接口
     * NUM =单号
     * KEY =授权码
     */
    private static final String AUTONUMBER_AUTO_URL = "http://www.kuaidi100.com/autonumber/auto?num=NUM&key=KEY";
    /**
     * 快递100查询快递请求接口(post)
     */
    private static final String POLL_QUERY_URL = "https://poll.kuaidi100.com/poll/query.do";


    // 授权码,授权码,请到快递100页面申请企业版接口获取
    private static final String KEY = "vkvhbTZJ1059";
    private static final String CUSTOMER = "0953C663278B625ED2FB94AF1F3A02D6";
    private static final String SIGN = "0953C663278B625ED2FB94AF1F3A02D6";
    // sign  签名, 用于验证身份, 按param + key + customer 的顺序进行MD5加密(注意加密后字符串一定要转大写), 不需要加上“+”号


    /**
     * 快递100智能识别快递编号
     * @author wangsong
     * @author requestCreate 下单参数
     * @date 2020/9/15 0015 15:42
     * @return void
     * @version 1.0.0
     */
    public List<KuaiDiCode> findKuaiDiCode(String orderId) {
        String url = AUTONUMBER_AUTO_URL.replace("NUM", orderId).replace("KEY", KEY);
        // 发送快递参数处理
        MultiValueMap<String, Object> sendBody = new LinkedMultiValueMap<>();
        sendBody.add("num", orderId);
        sendBody.add("key", KEY);
        //设置请求头参数
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-type", "application/x-www-form-urlencoded");
        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(sendBody, headers);
        ResponseEntity<String> result = restTemplate.postForEntity(url, formEntity, String.class);
        List<KuaiDiCode> kuaiDiCode = new ArrayList<>();
        if (result.getBody() != null && result.getBody().length() > 0) {
            ArrayList body = JSON.parseObject(result.getBody(), ArrayList.class);
            body.forEach(i -> kuaiDiCode.add(JSON.parseObject(JSON.toJSONString(i), KuaiDiCode.class)));
        }
        return kuaiDiCode;
    }


    /**
     *  快递100 物流查询
     * @param com 快递公司编码
     * @param num 快递单号
     * @return SFReturnData
     */
    public String findOrder(String num, String com) {
        Map<String, String> param = new HashMap<>();
        param.put("com", com);//快递公司编码
        param.put("num", num);//快递单号
        //
        String mgsData = JSON.toJSONString(param);
        // 发送快递参数处理
        MultiValueMap<String, Object> sendBody = new LinkedMultiValueMap<>();
        sendBody.add("customer", CUSTOMER);                          // 授权码,请到快递100页面申请企业版接口获取
        sendBody.add("sign", genDigest(mgsData, KEY, CUSTOMER));     // 数字签名
        sendBody.add("param", mgsData);                            // 业务数据报文
        //设置请求头参数
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-type", "application/x-www-form-urlencoded");
        //发送请求
        HttpEntity<MultiValueMap<String, Object>> formEntity = new HttpEntity<>(sendBody, headers);
        ResponseEntity<String> result = restTemplate.postForEntity(POLL_QUERY_URL, formEntity, String.class);
        //
       // SFReturnData sfReturnData = JSON.parseObject(result.getBody(), SFReturnData.class);
        return result.getBody();
    }


    /**
     * 业务数据加密  -->   param + key + customer 的顺序进行MD5加密(注意加密后字符串一定要转大写)
     * @param timestamp
     * @param mgsData
     * @param md5key
     * @return
     * @throws Exception
     */
    private String genDigest(String mgsData, String key, String customer) {
        return DigestUtils.md5Hex(mgsData + key + customer).toUpperCase();
    }
}

2、业务提供 KuaiDi100Service

/**
 * 快递100 相关操作
 * @author wangsong
 * @mail aaa@qq.com
 * @date 2020/9/16 0016 10:26
 * @version 1.0.0
 */
public interface KuaiDi100Service {


    /**
     * 获取快递信息
     * @param orderId
     */
    public String findOrder(String orderId);

    /**
     * 获取快递公司编号信息
     * @param orderId
     * @return
     */
    public List<KuaiDiCode> findKuaiDiCode(String orderId);
}

3、业务提供 KuaiDi100ServiceImpl

package com.ws.ldy.others.kuaidi.kuaidi100.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ws.ldy.config.error.ErrorException;
import com.ws.ldy.others.kuaidi.kuaidi100.entity.KuaiDiCode;
import com.ws.ldy.others.kuaidi.kuaidi100.service.KuaiDi100Service;
import com.ws.ldy.others.kuaidi.kuaidi100.util.KuaiDi100Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 快递100
 * @author wangsong
 * @mail aaa@qq.com
 * @date 2020/9/16 0016 10:27
 * @version 1.0.0
 */
@Service
public class KuaiDi100ServiceImpl implements KuaiDi100Service {

    @Autowired
    private KuaiDi100Util kuaiDi100Util;


    @Override
    public String findOrder(String orderId) {
        //获取快递编码
        List<KuaiDiCode> kuaiDiCodeList = findKuaiDiCode(orderId);
        if (kuaiDiCodeList.size() == 0) {
            throw new ErrorException(10099, "无法识别该快递单号");
        }
        String orderJson = null;
        // 遍历快递公司: 找找时间立即跳出
        for (KuaiDiCode kuaiDiCode : kuaiDiCodeList) {
            // 没有找到: {"result":false,"returnCode":"500","message":"查询无结果,请隔段时间再查"}
            orderJson = kuaiDi100Util.findOrder(orderId, kuaiDiCode.getComCode());
            JSONObject jsonObject = JSON.parseObject(orderJson);
            // 当没有找到快递, 会出现result=false,找到了物流,没有result字段
            Boolean result = (Boolean) jsonObject.get("result");
            if (result == null) {
                break;
            }
        }
        //判断是否找到物流信息
        JSONObject jsonObject = JSON.parseObject(orderJson);
        Boolean result = (Boolean) jsonObject.get("result");
        if (result != null && !result) {
            throw new ErrorException(10099, "查询无结果,请隔段时间再查");
        }
        return orderJson;
    }

    @Override
    public List<KuaiDiCode> findKuaiDiCode(String orderId) {
        List<KuaiDiCode> kuaiDiCode = kuaiDi100Util.findKuaiDiCode(orderId);
        return kuaiDiCode;
    }
}

4、返回数据 KuaiDiCode

package com.ws.ldy.others.kuaidi.kuaidi100.entity;

import lombok.Data;
import lombok.ToString;

import java.time.LocalDateTime;

/**
 * 快递100 智能识别返回结果 List<KuaiDiCode 按相似度排序(高的在前)
 * @author wangsong
 * @mail aaa@qq.com
 * @date 2020/9/16 0016 13:45
 * @version 1.0.0
 */
@Data
@ToString
public class KuaiDiCode {

    private String comCode;
    private String id;
    private Integer noCount;
    private String noPre;
    private LocalDateTime startTime;

}

5、测试接口 KuaiDi100Controller

package com.ws.ldy.others.kuaidi.kuaidi100.controller;

import com.ws.ldy.common.result.R;
import com.ws.ldy.others.kuaidi.kuaidi100.entity.KuaiDiCode;
import com.ws.ldy.others.kuaidi.kuaidi100.service.KuaiDi100Service;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/kuaidi100/")
@Api(value = "KuaiDi100Controller", tags = "v-1.3 -- 快递100")
public class KuaiDi100Controller {

    @Autowired
    private KuaiDi100Service kuaiDi100Service;

    @ApiOperation(value = "输入快递号智能识别快递公司", notes = "按相似度排序,相似度越高越靠前")
    @RequestMapping(value = "/findKuaiDiCode", method = RequestMethod.GET)
    public R<List<KuaiDiCode>> findKuaiDiCode(String orderId) {
        return R.success(kuaiDi100Service.findKuaiDiCode(orderId));
    }


    @ApiOperation(value = "根据快递单号查询物流信息", notes = "" +
            "\r\n 1、自动识别单号" +
            "\r\n 2、返回参数查看:https://api.kuaidi100.com/help/doc/?code=5f0ffb5ebc8da837cbd8aefc&openKey=%E5%AE%9E%E6%97%B6%E5%BF%AB%E9%80%92%E6%9F%A5%E8%AF%A2#part2" +
            "")
    @RequestMapping(value = "/findOrder", method = RequestMethod.GET)
    public R<String> findOrder(String orderId) {
        return R.success(kuaiDi100Service.findOrder(orderId));
    }
}

三、测试

测试接口

Java 对接快递100 实现快递实时查询 (自动识别快递公司)

json 网转换查看返回数据

Java 对接快递100 实现快递实时查询 (自动识别快递公司)
·

  • 个人开源项目(通用后台管理系统)–> https://gitee.com/wslxm/spring-boot-plus2 , 喜欢的可以看看

  • 本文到此结束,如果觉得有用,动动小手点赞或关注一下呗,将不定时持续更新更多的内容…,感谢大家的观看!