java 开发与快递鸟对接的推送接口

最近公司需要跟快递鸟进行对接,使用快递鸟的API来查询商城的物流信息,在此记录一下,自己跟快递鸟对接的过程吧,如果有那些不对的地方请指出,觉得可以的话转载记得表明出处哦,毕竟原创不易,谢谢啦

下面是快递鸟公司的文档,demo下载和调试地址,一定要记得先注册账号实名完得到EBusinessID 和AppKey


快递鸟沙箱调试地址:http://www.kdniao.com/UserCenter/v2/SandBox/Index.aspx
快递鸟技术文档地址:http://www.kdniao.com/file/快递鸟接口技术文档v5.20.pdf
快递鸟demo下载地址:http://www.kdniao.com/documents-demo

  • 下面是我对接快递鸟的工具类KDNUtils (包含即时查询物流信息,订阅物流信息)
package cn.demo.project.util;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.json.JSONArray;
import org.json.JSONException;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;/*** 快递鸟接口对接** @author m*/
public class KDNUtils {/*** 电商ID*/private String EBusinessID = "请到快递鸟官网申请http://www.kdniao.com/ServiceApply.aspx";/*** 电商加密私钥,快递鸟提供,注意保管,不要泄漏*/private String AppKey = "请到快递鸟官网申请http://www.kdniao.com/ServiceApply.aspx";/*** 快递鸟物流轨迹即时查询接口请求url*/private String ReqURL = "http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx";/*** 快递鸟订阅推送测试请求url*///private String dingyueURL = "http://testapi.kdniao.com:8081/api/dist";/*** 快递鸟订阅推送正式请求url** @param args*/private String dingyueURL = "http://api.kdniao.com/api/dist";//DEMOpublic static void main(String[] args) {KdniaoTrackQueryAPI api = new KdniaoTrackQueryAPI();try {//即时查询//String result = api.getOrderTracesByJson("YTO", "4236260290247");//订阅String result = api.orderTracesSubByJson("YTO", "4236260290247");System.out.print(result);} catch (Exception e) {e.printStackTrace();}}/*** Json方式  物流信息订阅** @throws Exception*/public String orderTracesSubByJson(String expCode, String expNo) throws Exception {String requestData = "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";Map<String, String> params = new HashMap<>(16);params.put("RequestData", urlEncoder(requestData, "UTF-8"));params.put("EBusinessID", EBusinessID);params.put("RequestType", "1008");String dataSign = encrypt(requestData, AppKey, "UTF-8");params.put("DataSign", urlEncoder(dataSign, "UTF-8"));params.put("DataType", "2");String result = sendPost(dingyueURL, params);Object parse = JSON.parse(result);//根据公司业务处理返回的信息......return result;}/*** Json方式 查询订单物流轨迹** @throws Exception*/public String getOrderTracesByJson(String expCode, String expNo) throws Exception {String requestData = "{'OrderCode':'','ShipperCode':'" + expCode + "','LogisticCode':'" + expNo + "'}";Map<String, String> params = new HashMap<>(16);params.put("RequestData", urlEncoder(requestData, "UTF-8"));params.put("EBusinessID", EBusinessID);params.put("RequestType", "1002");String dataSign = encrypt(requestData, AppKey, "UTF-8");params.put("DataSign", urlEncoder(dataSign, "UTF-8"));params.put("DataType", "2");String result = sendPost(ReqURL, params);//根据公司业务处理返回的信息......return result;}/*** MD5加密** @param str     内容* @param charset 编码方式* @throws Exception*/@SuppressWarnings("unused")private String MD5(String str, String charset) throws Exception {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes(charset));byte[] result = md.digest();StringBuffer sb = new StringBuffer(32);for (int i = 0; i < result.length; i++) {int val = result[i] & 0xff;if (val <= 0xf) {sb.append("0");}sb.append(Integer.toHexString(val));}return sb.toString().toLowerCase();}/*** base64编码** @param str     内容* @param charset 编码方式* @throws UnsupportedEncodingException*/private String base64(String str, String charset) throws UnsupportedEncodingException {String encoded = base64Encode(str.getBytes(charset));return encoded;}@SuppressWarnings("unused")private String urlEncoder(String str, String charset) throws UnsupportedEncodingException {String result = URLEncoder.encode(str, charset);return result;}/*** 电商Sign签名生成** @param content  内容* @param keyValue Appkey* @param charset  编码方式* @return DataSign签名* @throws UnsupportedEncodingException ,Exception*/@SuppressWarnings("unused")private String encrypt(String content, String keyValue, String charset) throws UnsupportedEncodingException, Exception {if (keyValue != null) {return base64(MD5(content + keyValue, charset), charset);}return base64(MD5(content, charset), charset);}/*** 向指定 URL 发送POST方法的请求** @param url    发送请求的 URL* @param params 请求的参数集合* @return 远程资源的响应结果*/@SuppressWarnings("unused")private String sendPost(String url, Map<String, String> params) {OutputStreamWriter out = null;BufferedReader in = null;StringBuilder result = new StringBuilder();try {URL realUrl = new URL(url);HttpURLConnection conn = (HttpURLConnection) realUrl.openConnection();// 发送POST请求必须设置如下两行conn.setDoOutput(true);conn.setDoInput(true);// POST方法conn.setRequestMethod("POST");// 设置通用的请求属性conn.setRequestProperty("accept", "*/*");conn.setRequestProperty("connection", "Keep-Alive");conn.setRequestProperty("user-agent","Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");conn.connect();// 获取URLConnection对象对应的输出流out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");// 发送请求参数if (params != null) {StringBuilder param = new StringBuilder();for (Map.Entry<String, String> entry : params.entrySet()) {if (param.length() > 0) {param.append("&");}param.append(entry.getKey());param.append("=");param.append(entry.getValue());//System.out.println(entry.getKey()+":"+entry.getValue());}//System.out.println("param:"+param.toString());out.write(param.toString());}// flush输出流的缓冲out.flush();// 定义BufferedReader输入流来读取URL的响应in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));String line;while ((line = in.readLine()) != null) {result.append(line);}} catch (Exception e) {e.printStackTrace();}//使用finally块来关闭输出流、输入流finally {try {if (out != null) {out.close();}if (in != null) {in.close();}} catch (IOException ex) {ex.printStackTrace();}}return result.toString();}private static char[] base64EncodeChars = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','I', 'J', 'K', 'L', 'M', 'N', 'O', 'P','Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X','Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f','g', 'h', 'i', 'j', 'k', 'l', 'm', 'n','o', 'p', 'q', 'r', 's', 't', 'u', 'v','w', 'x', 'y', 'z', '0', '1', '2', '3','4', '5', '6', '7', '8', '9', '+', '/'};public static String base64Encode(byte[] data) {StringBuffer sb = new StringBuffer();int len = data.length;int i = 0;int b1, b2, b3;while (i < len) {b1 = data[i++] & 0xff;if (i == len) {sb.append(base64EncodeChars[b1 >>> 2]);sb.append(base64EncodeChars[(b1 & 0x3) << 4]);sb.append("==");break;}b2 = data[i++] & 0xff;if (i == len) {sb.append(base64EncodeChars[b1 >>> 2]);sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);sb.append("=");break;}b3 = data[i++] & 0xff;sb.append(base64EncodeChars[b1 >>> 2]);sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);sb.append(base64EncodeChars[b3 & 0x3f]);}return sb.toString();}public JSONObject getJSONParam(HttpServletRequest request) {JSONObject jsonParam = null;try {// 获取输入流BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));// 写入数据到StringBuilderStringBuilder sb = new StringBuilder();String line;while ((line = streamReader.readLine()) != null) {sb.append(line);}jsonParam = JSONObject.parseObject(sb.toString());// 直接将json信息打印出来if (null != jsonParam) {System.out.println(jsonParam.toJSONString());}} catch (Exception e) {e.printStackTrace();}return jsonParam;}/*** @param returnJson 解析json数据* @throws JSONException*/public void parseJson(String returnJson) throws JSONException {org.json.JSONObject obj = new org.json.JSONObject(returnJson);// 存放着订阅的多个订单信息JSONArray array = obj.getJSONArray("Data");for (int i = 0; i < array.length(); i++) {org.json.JSONObject json = array.getJSONObject(i);// 订单号String LogisticCode = json.getString("LogisticCode");// 快递公司编号String ShipperCode = json.getString("ShipperCode");//快递轨迹JSONArray traces = json.getJSONArray("Traces");//将接收到的信息按照公司的业务进行处理.....System.out.println("LogisticCode" + LogisticCode);System.out.println("ShipperCode" + ShipperCode);System.out.println("traces" + traces);}}/*** @param response 返回信息给快递鸟公司*/public void returnMessageToKuaiDiNiao(HttpServletResponse response) {try {PrintWriter out = response.getWriter();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");org.json.JSONObject obj = new org.json.JSONObject();obj.put("EBusinessID", EBusinessID);obj.put("UpdateTime", sdf.format(new Date()));obj.put("Success", true);obj.put("Reason", "");out.write(obj.toString());out.flush();out.close();} catch (Exception e) {e.printStackTrace();}}
}
  • 这是我的处理快递鸟推送物流消息的Controller
package cn.demo.project.controller;import cn.miaomaokao.project.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;/*** 快递鸟Controller** @author m*/
@Slf4j
@Controller
@RequestMapping(value = "/kdn")
public class KDNController {/*** 快递鸟物流推送 回调** @param RequestData 推送信息* @param requestType 推送类型 101,102为推送类型 101为普通版 102为增值版(充钱系列)* @param DataSign* @param response    响应* @throws IOException IO异常*/@PostMapping(value = "/callback", produces = "application/json;charset=UTF-8")public void push(String RequestData, String requestType, String DataSign, HttpServletResponse response) throws IOException {String responseResult = "{\"EBusinessID\":\"1603095\",\"UpdateTime\":\"2019-11-27 16:26:11\",\"Success\":true,\"Reason\":\"\"}";if (StringUtils.isEmpty(RequestData)) {log.info("RequestData为空");}//具体操作根据自身业务来,但记住,5s内必须给快递鸟发送相应,否则他会判断推送失败log.info("RequestData:{}", RequestData);log.info("requestType:{}", requestType);log.info("DataSign:{}", DataSign);//无论如何发送相应给快递鸟response.getWriter().write(responseResult);}}
  • 这是我回调的结果

    注意:回调地址如果使用ip+端口+请求时,要在前面加上http://,否则将不会回调成功!!!!我之前就吃了这个亏!!

对了,友情提示一下,免费版的一天只能订阅100次物流,而且仅支持申通、中通、圆通快递查询(客服跟我说的),业务场景比这个大的小伙伴就充钱吧

觉得还可以的话可以的话点个赞呗

java 开发与快递鸟对接的推送接口相关推荐

  1. java 百度api接口开发_百度熊掌号使用Java工具类对接API推送接口进行文章推送实例详解...

    对于java程序员来说,自己运维的百度熊掌号当然得使用java的方式去每天推送文章了.目前,百度推出了百度熊掌号服务.旨在更好的为站长服务.那么百度熊掌号如何通过推送API接口实现自动文章推送呢? 第 ...

  2. 微信小程序推送消息java开发_干货 | 微信小程序推送消息简单Demo

    在开始前,你需要准备:注册微信小程序 一个简单的springBoot 项目 微信开发者工具 正式 微信小程序发送消息主要通过WxMaTemplateMessage 类来推送 public class ...

  3. Java开发微信小程序订阅消息推送

    使用到开源工具WxJava 这里环境使用到springboot 框架,废话不多说直接上干货. pom.xml引用 <!-- https://mvnrepository.com/artifact/ ...

  4. Java如何接入快递鸟单号查询接口物流API

    Java怎么写物流接口,怎么接入物流接口,如何根据单号查询物流跟踪的详细信息 需求 根据用户输入的订单号,我们的后台识别订单号并根据快递鸟查询快递Api接口,实现自动查询的功能 demo实例 本人自己 ...

  5. 快递鸟API单号查询接口Java开发调用源码

    快递鸟是专业的第三方物流数据服务商,国家高新技术企业,已先后完成四轮融资,一直专注于企业级物流API技术研发和打通物流各节点信息服务,致力于成为全球最大的物流信息枢纽中心,为零售电商企业级提供标准的物 ...

  6. 常用快递单号物流查询接口通用API(JAVA快递鸟对接)

    快递查询接口通用API是给发货电商用来实现查询快递物流轨迹功能的,接口对接前要先到快递鸟网站申请接口秘钥和APIKEY 快递API的应用场景与用途 最常见的应用场景如下: (1)电商网站:例如B2C. ...

  7. Java企业微信开发-企业微信所有类型消息推送封装

    企业微信开发第一步获取AccessToken,企业微信的AccessToken和公众号的不一样,企业微信所有接口调用只需要一个AccessToken,而公众号授权和jssdk是分开的 一.获取企业微信 ...

  8. 简单快递鸟单号识别查询接口API/插件开发使用

    快递接口/插件是电商网站和系统商用来实现查询快递功能的主要方法,就类似淘宝京东查询物流轨迹一样,嵌入到自己系统里. 现在有好几家公司都提供集成的接口,就是对接或嵌入一次,就能查询多家快递公司信息.比较 ...

  9. 快递鸟电子面单打印接口demo-可返回电子面单模板

    接口支持的消息接收方式:HTTPPOST 请求方法的编码格式(utf-8):"application/x-www-form-urlencoded;charset=utf-8" 请求 ...

最新文章

  1. iPhone 14 与iPhone 13
  2. JFinal配合Shiro权限控制在FreeMarker模板引擎中控制到按钮粒度的使用
  3. Android中使用WebView加载本地html并支持运行JS代码和支持缩放
  4. golang文件操作:打开关闭文件,带缓冲区的读文件
  5. HihoCoder#1051:补提交卡
  6. zookeeper集群安装部署
  7. 计算器排html页面,简易计算器html页面代码
  8. nodejs实战案例(Express框架+mongoDB)——(15)——爬虫功能
  9. 使用电脑端360安全卫士时,不小心在加速球点击自动清理残留进程,每次打开相关进程都会自动清理 - 解决方案
  10. 最新版24H全自动在线要饭系统全开源源码
  11. 学习笔记03_测试用例
  12. linux中怎么粘贴复制文件路径,如何在Linux中复制文件和目录
  13. 美国人口普查年收入情况分析
  14. Eclipse的各种查找,类的查找,方法查找快捷键
  15. [渝粤教育] 中原科技学院 管理学原理 参考 资料
  16. 科恩第一章Friday, October 29, 2021 10:13 AM
  17. Chrome浏览器屏蔽百度推广
  18. JS实现数字自动转换人民币金额(自动格式化输入的数字/千位分隔符)
  19. python笔试编程题_Python自动化测试笔试面试时常见的编程题
  20. 深度神经网络为什么有效,神经网络处理什么问题

热门文章

  1. Win11更新卡在0%怎么办 Win11更新卡在0%解决方法
  2. 视频教程-Spring框架快速入门到精通-Java
  3. 10分钟用Flutter写出摸鱼桌面版App
  4. inux学习笔记:14-1.rpm包
  5. 灵动微MM32F3277可用于替换意法半导体STM32F103
  6. 大地坐标系到站心坐标系(ENU)坐标转换(提供QT和JAVA源码)
  7. R语言(数据读写操作)
  8. 策略梯度与A2C算法
  9. Vert.x(vertx)入门资料
  10. java 生成hprof,java – -XX:HeapDumpOnOutOfMemoryError未在OOM中创建hprof文件