首页 > 其他分享 >快速集成快递物流轨迹查询功能

快速集成快递物流轨迹查询功能

时间:2022-09-06 17:33:48浏览次数:90  
标签:集成 轨迹 string System 快递 using webRe public

前沿

近年来,随着互联网的发展,各个行业都在用新的技术、新的观念为自己的发展打下坚实的基础,如今网络已经渗透到了人们的日常生活中,网上购物成了大家喜爱的方式。各类商城、APP、小程序等应用不断涌现,涉及各行各业,都在争抢成为人们网上购物的载体。网上购物物流是必不可少的一环,这些应用是如何解决物流信息系统化的,让消费者方便快捷的了解物品的实时轨迹信息和系统内部流程无阻碍自动流转?我认为有两种途径可达成,第一种是自建物流体系,逐个跟物流公司对接,设计符合自身的产品解决问题,这种方案的优点是灵活性非常高,高度契合公司系统,缺点也很明显,每家公司接口标准都不一样,需要懂物流的人抽象设计,接入难度大、耗时长、成本高、后期的维护成本也高。第二种是找一家第三方聚合物流平台接入即可,如:快递鸟、快递100、快递网等。物流平台对物流和电商两端的需求研究更深入,产品设计得更简单,对接更快捷,更重要的一点是只需一次接入即可使用平台支持的所有快递物流公司,开发周期短,后期维护成本低,缺点是这些平台都是标准接口,灵活性稍低,接口调用量大时需支付接口调用服务费,各家平台的收费标准都不一样,可登录其官网了解详情,下面为大家介绍如何接入快递鸟快递物流查询API。

应用场景

综合类电商平台、垂直类电商平台、小程序、ERP系统、工具等应用都可使用。

如电商平台在订单管理页面可查看物流轨迹信息

小程序通过扫码查看快递行踪

接入步骤

申请账号-->获取用户ID和Key-->申请开通套餐-->按要求对接,联调测试-->正式投产

1、申请账号和开通套餐

访问快递鸟注册页面进行账号注册,按页面提示,完成账号注册和完善资料,账号注册成功后可在用户中心查看获得用户ID和Key,同时在用户中心顶部点击申请开通套餐,这样子对接前期准备工作就完成了,使用ID和Key即可进行调用。

2、技术对接

访问快递鸟文档中心下载技术对接文档,快递鸟产品很多,选择适合自己的产品,根据文档参数对接即可。需要注意的是,对接过程如果遇到签名校验不过的问题,这时可查看生成验签的方式是否与文档一致,生成的验签是否存在大小写的问题,快递鸟的验签生成方式为:(请求内容(未编码)+ApiKey)进行MD5加密,然后Base64编码,最后进行URL(utf-8)编码。好了,不啰嗦了,直接上代码,如需对接的产品与示例不同只需更改requestType和应用级参数即可。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace KuaiDiChaXun
{
    /// <summary>
    /// 快递查询处理类
    /// </summary>
    public class KuaiDiChaXunBLL
    {
        #region 固定参数,实际项目中可写在配置文件中,方便修改
        string url = "https://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";//请求url,正式环境
        string eBusinessID = "1257157";//用户ID,此ID仅作演示使用,实际调用需换成自己的ID,登录快递鸟官网会员中心获取
        string apiKey = "F201358A-513B-4237-98D6-67DE7EA75BA3";//用户秘钥,此秘钥仅作演示使用,实际调用需换成自己的秘钥,登录快递鸟官网会员中心获取        
        #endregion

        /// <summary>
        /// 查询快递路由轨迹
        /// </summary>
        /// <param name="shipperCode">快递公司编码</param>
        /// <param name="waybillCode">运单号</param>
        /// <param name="phoneNo">收/寄件人手机号后4位,SF必填</param>
        /// <returns></returns>
        public string SearchRoute(string shipperCode, string waybillCode, string phoneNo)
        {
            if (string.IsNullOrEmpty(shipperCode))
            {
                return "请输入快递公司编码";
            }
            if (string.IsNullOrEmpty(waybillCode))
            {
                return "请输入运单号";
            }
            if (string.IsNullOrEmpty(phoneNo) && shipperCode == "SF")
            {
                return "SF必填收/寄件人手机号后4位";
            }
            string result = string.Empty;
            //组装应用级参数,此Demo使用最少参数,更多参数参考技术文档
            string requestData = "{'ShipperCode':'" + shipperCode + "','LogisticCode':'" + waybillCode + "'}";
            if (shipperCode == "SF")//顺丰需收/寄件人手机号后4位
            {
                requestData = "{'ShipperCode':'" + shipperCode + "','LogisticCode':'" + waybillCode + "','CustomerName':'" + phoneNo + "'}";
            }
            //把(jsonStr+APIKey)进行MD5加密
            string md5Str = MD5(requestData + apiKey, "UTF-8");
            //把md5Str 进行Base64编码
            string base64Str = base64(md5Str, "UTF-8");
            //进行URL编码 (utf-8),最终得到签名串
            string dataSign = HttpUtility.UrlEncode(base64Str, Encoding.UTF8);
            //请求接口指令
            string cmd = "8001";
            //组装系统级参数
            string postData = "RequestData=" + HttpUtility.UrlEncode(requestData, Encoding.UTF8) + "&EBusinessID=" + eBusinessID + "&RequestType="+ cmd + "&DataSign=" + dataSign + "&DataType=2";
            //发起请求
            HttpHelper helper = new HttpHelper();
            HttpRequestEntity response = helper.Request(url, postData);
            if (response.IsSuccess == 0)
            {
                result = response.ResponseContent;
                //拿到结果后进行后续业务操作
            }
            else
            {
                result = "请求异常";
                //记录错误信息及后续业务补偿
            }
            return result;
        }

        ///<summary>
        /// 字符串MD5加密
        ///</summary>
        ///<param name="str">要加密的字符串</param>
        ///<param name="charset">编码方式</param>
        ///<returns>密文</returns>
        public string MD5(string str, string charset)
        {
            byte[] buffer = Encoding.GetEncoding(charset).GetBytes(str);
            try
            {
                System.Security.Cryptography.MD5CryptoServiceProvider check;
                check = new System.Security.Cryptography.MD5CryptoServiceProvider();
                byte[] somme = check.ComputeHash(buffer);
                string ret = "";
                foreach (byte a in somme)
                {
                    if (a < 16)
                        ret += "0" + a.ToString("X");
                    else
                        ret += a.ToString("X");
                }
                return ret.ToLower();
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// base64编码
        /// </summary>
        /// <param name="str">内容</param>
        /// <param name="charset">编码方式</param>
        /// <returns></returns>
        public string base64(string str, string charset)
        {
            return Convert.ToBase64String(Encoding.GetEncoding(charset).GetBytes(str));
        }
    }
}

HTTP封装类代码:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace KuaiDiChaXun
{
    public class HttpHelper : IDisposable
    {
        private bool _disposable = false;
        /// <summary>
        /// 请求编码格式默认utf-8;
        /// </summary>
        public Encoding HtmlEncoding = Encoding.UTF8;
        /// <summary>
        /// 请求时间
        /// </summary>
        public int Timeout = 5000;

        public CookieContainer Cookies = null;
        /// <summary>
        /// 是否记录Cookies
        /// </summary>
        public bool IsRecordCookie = false;

        public string ContentType = "application/x-www-form-urlencoded";

        public string AcceptLanguage = "en-US, en; q=0.8, zh-Hans-CN; q=0.5, zh-Hans; q=0.3";

        public string KeepAlive = "Keep-Alive";

        public string Accept = "*/*";

        private const string UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.10240";
        
        public HttpHelper()
        {
            //允许最大连接数
            ServicePointManager.DefaultConnectionLimit = 512;
        }        

        /// <summary>
        /// 基本请求方法
        /// </summary>
        /// <param name="requestType"></param>
        /// <param name="url"></param>
        /// <param name="requestData"></param>
        /// <returns></returns>
        private HttpRequestEntity BaseRequest(RequestType requestType, string url, string requestData)
        {
            var result = new HttpRequestEntity { IsSuccess = 0 };

            if (string.IsNullOrEmpty(url))
                throw new ArgumentNullException("请求Url不能为空值");

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();            
            HttpStatusCode statusCode = HttpStatusCode.OK;
            if (IsRecordCookie)
                Cookies = new CookieContainer();
            Stream requestStream = null;
            StreamReader streamReader = null;

            HttpWebRequest webRe = null;
            HttpWebResponse webPos = null;
            try
            {
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    webRe = WebRequest.Create(url) as HttpWebRequest;
                    webRe.ProtocolVersion = HttpVersion.Version10;
                }
                else
                {
                    webRe = (HttpWebRequest)WebRequest.Create(url);
                }

                webRe.Headers.Add("Accept-Language", AcceptLanguage);
                webRe.Headers.Add("Keep-Alive", KeepAlive);
                webRe.UserAgent = UserAgent;
                webRe.Accept = Accept;
                webRe.Timeout = Timeout;
                webRe.ReadWriteTimeout = Timeout;
                webRe.CookieContainer = Cookies;

                if (requestType == RequestType.Post)
                {
                    webRe.ContentType = string.Format("{0}; {1}", ContentType, HtmlEncoding.BodyName);
                    byte[] datas = HtmlEncoding.GetBytes(requestData);
                    webRe.Method = "POST";
                    webRe.ContentLength = datas.Length;
                    webRe.MaximumResponseHeadersLength = -1;
                    requestStream = webRe.GetRequestStream();
                    requestStream.Write(datas, 0, datas.Length);
                    requestStream.Flush();
                    requestStream.Close();
                }
                else
                    webRe.Method = "GET";

                webPos = (HttpWebResponse)webRe.GetResponse();                
                statusCode = webPos.StatusCode;
                result.ResponseLength = webPos.ContentLength;
                result.ResponseEncodingName = webPos.ContentEncoding;

                requestStream = webPos.GetResponseStream();
                if (webPos.StatusCode == HttpStatusCode.OK)
                {
                    result.IsSuccess = 0;

                    if (requestStream != null)
                    {
                        streamReader = new StreamReader(requestStream, HtmlEncoding);
                        result.ResponseContent = streamReader.ReadToEnd();
                    }
                }
            }
            catch (Exception ex)
            {
                result.IsSuccess = 1;
                result.ResponseContent = ex.Message;
            }
            finally
            {
                if (requestStream != null)
                {
                    requestStream.Close();
                    requestStream.Dispose();
                }

                if (streamReader != null)
                {
                    streamReader.Close();
                    streamReader.Dispose();
                }

                webRe.Abort();
                if (webPos != null)
                    webPos.Close();

            }
            stopwatch.Stop();
            double elapseTime = stopwatch.Elapsed.TotalMilliseconds;//计算请求耗时
            return result;
        }

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true; //总是接受  
        }

        /// <summary>
        /// Get请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <returns></returns>
        public HttpRequestEntity Request(string url)
        {
            return BaseRequest(RequestType.Get, url, string.Empty);
        }

        /// <summary>
        /// Post请求
        /// </summary>
        /// <param name="url">请求地址Url</param>
        /// <param name="requestData">请求内容参数</param>
        /// <returns></returns>
        public HttpRequestEntity Request(string url, string requestData)
        {
            return BaseRequest(RequestType.Post, url, requestData);
        }

        ~HttpHelper()
        {
            Dispose(false);
        }

        #region IDisposable 成员

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (this._disposable)
                return;

            if (disposing)
            {

            }

            _disposable = true;
        }

        #endregion
    }

    /// <summary>
    /// HttpHelper请求方式
    /// </summary>
    public enum RequestType
    {
        /// <summary>
        /// Get请求
        /// </summary>
        Get,
        /// <summary>
        /// Post请求
        /// </summary>
        Post
    }

    /// <summary>
    /// HttpHelper请求时返回实体
    /// </summary>
    public class HttpRequestEntity
    {
        /// <summary>
        /// 请求是否成功 0-成功(返回Http状态码200) 1-失败(出现异常)
        /// </summary>
        public int IsSuccess { get; set; }
        /// <summary>
        /// 请求返回内容
        /// </summary>
        public string ResponseContent { get; set; }
        /// <summary>
        /// 请求返回内容长度
        /// </summary>
        public long ResponseLength { get; set; }
        /// <summary>
        /// 请求返回编码类型
        /// </summary>
        public string ResponseEncodingName { get; set; }
    }
}

调用示例代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace KuaiDiChaXun
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                Console.WriteLine("请输入快递公司编码");
                string shipperCode = Console.ReadLine();

                Console.WriteLine("请输入运单号");
                string waybillCode = Console.ReadLine();

                Console.WriteLine("请输入收/寄件人手机号后4位,SF必填");
                string phone = Console.ReadLine();

                KuaiDiChaXunBLL bll = new KuaiDiChaXunBLL();
                string result = bll.SearchRoute(shipperCode, waybillCode, phone);
                Console.WriteLine("执行结果如下:");
                Console.WriteLine(result);
                Console.WriteLine("------------------");
                Console.WriteLine("------本次查询结束,按任意键继续,退出请输入exit------------");
                string cmd = Console.ReadLine().ToLower();
                if (cmd == "exit")
                {
                    return;
                }
            }
        }
    }
}

运行查看效果

以上是接入快递鸟快递查询接口示例代码,源码下载


如果对您有帮助劳烦帮忙点个赞,收藏关注一下,可以相互学习共同进步。

标签:集成,轨迹,string,System,快递,using,webRe,public
From: https://www.cnblogs.com/huaxiaorui/p/16662542.html

相关文章

  • Spring Boot集成Dubbo
    SpringBoot集成Dubbo分布式框架项目结构接口工程:存放实体bean和业务接口服务提供者:业务接口的实现类并将服务暴露且注册到注册中心,调用数据持久层添加依赖(dubbo、注册......
  • Jenkins持续集成.NET项目(SVN+MSBuild)
    一、安装Jenkins和MSBuild工具官网下载最新版Jenkins (Jenkins运行需要JDK环境,需要提前配置JDK1.8及以上版本),安装完成后,在浏览器打开http://localhost:8080/(默认端口为8......
  • 开源:Taurus.MVC-Java 版本框架 (支持javax.servlet.*和jakarta.servlet.*双系列,内集成
    版本说明:因为之前有了Taurus.MVC-DotNet版本框架,因此框架标了-Java后缀。.Net 版本:开源文章:开源:Taurus.MVC-DotNet版本框架(支持.NETCore系列,内集成微服务服务端......
  • 数据变更白屏化利器-推送轨迹上线
    作者:子葵背景Zookeeper可作为注册配置中心,选主,分布式锁等多种场景,随着业务规模的扩大,业务之间的依赖关系逐渐变得复杂,在这种复杂的场景下如果遇到变更推送相关问题,排查......
  • 通用mapper集成示例
    目录插件介绍项目结构导入pom依赖配置文件通用Mapper:分页插件:注意事项(默认是不用加的):测试脚手架项目配置easyCodeIDEA插件自动生成xml文件,开发效率简直无敌插件介绍......
  • linux 通过nslcd ldap协议集成 windows AD
    方案一1.nslcd配置uri:windowsAD的ip,389为ldap协议的端口base:指定根ou或者cncat/etc/nslcd.conf#/etc/nslcd.conf#nslcdconfigurationfile.Seenslcd.con......
  • 使用 Django 集成 vue 到一个服务器上,还是 Django 和 vue 分开部署
    Django+Vue的项目,实际部署的时候,使用Django集成vue到一个服务器上,还是Django和vue分开部署?目前在架构选择,基本上定了Django+Vue但是实际部署的时候,就有两种......
  • ubuntu20.04无法正确识别Intel Corporation UHD Graphics 630集成显卡的问题
    我的电脑硬件配置:CPU:Intel®Core™[email protected]×12显卡:MesaIntel®UHDGraphics630(CFLGT2)最开始我安装的是ubuntu22.04,显卡的识别没问题,双......
  • SpringBoot集成Dubbo和Zookeeper
    15、SpringBoot集成Dubbo和Zookeeper15.1、分布式理论什么是分布式系统?在《分布式系统原理与范型》一书中有如下定义:“分布式系统是若干独立计算机的集合,这些计算机对......
  • jmeter-11-Ant接口自动化及持续集成整合
    前言重要的事情说三遍:仓库放在最后!!!仓库放在最后!!!仓库放在最后!!!PPLJmeter简介:整合Jmeter+Ant只需要通过简式配置或直接运行,让你不需要再多关心如何配置,一站式进行自动化......