API开发实践(三) 查询物流路径

查询物流可以使用现成的API,本文使用的快递鸟查询。

查询方法主要在两个类:errorManage、kdniaoTrackQueryAPI中

各种快递查询Api接口(快递鸟)

调用API一定要仔细阅读文档,了解编码格式、请求方式、参数设置等信息。

上代码之前先说一下数据结构:

我们想要的物流路径可由一系列地址组成,但在实际操作中还存在查询失败及没有物流信息的情况,所以还要返回一个查询状态信息。

所以选择一个能储存所需信息的最简单结构,用List结构传递即可。

规定List第一位存储Int型转状态信息,用不同数字返回不同信息。后面的位置一次存储String型地址信息。(具体在处理错误的eM方法。)

eM返回List后,在Return方法中根据第一位的状态信息编辑返回内容,同样适用List结构。

顺便一提:

快递鸟返回的数据格式是JSON格式,还需要调用org.json.*包,自己下载就行。

代码:kdniaoTrackQueryAPI类

  1 package util;
  2 import java.io.BufferedReader;
  3 import java.io.IOException;
  4 import java.io.InputStreamReader;
  5 import java.io.OutputStreamWriter;
  6 import java.io.UnsupportedEncodingException;
  7 import java.net.HttpURLConnection;
  8 import java.net.URL;
  9 import java.net.URLEncoder;
 10 import java.security.MessageDigest;
 11 import java.util.ArrayList;
 12 import java.util.HashMap;
 13 import java.util.List;
 14 import java.util.Map;
 15 import org.json.*;
 16 import java.util.regex.Matcher;
 17 import java.util.regex.Pattern;
 18
 19 public class kdniaoTrackQueryAPI {
 20     //电商ID
 21     private String EBusinessID="1287464";
 22     //电商加密私钥,快递鸟提供,注意保管,不要泄漏
 23     private String AppKey="4e92ddaa-b1b8-49d1-9261-1f5ff114b57f";
 24     //请求url
 25     private String ReqURL="http://112.74.108.55/Ebusiness/EbusinessOrderHandle.aspx";
 26
 27     //实例化
 28     public kdniaoTrackQueryAPI(){}
 29
 30     public List<String> Return(String ShipperCode,String LogisticCode) {   //公司编号和物流运单号
 31         // TODO Auto-generated method stub
 32         List<String> addresses=new ArrayList<String>();
 33         kdniaoTrackQueryAPI api = new kdniaoTrackQueryAPI();
 34         try {
 35             String result = api.getOrderTracesByJson(ShipperCode,LogisticCode);
 36             errorManage em = eM(result);
 37             if(em.getSuccess()){
 38                  addresses.add("1");
 39                  JSONObject json = new JSONObject(result);
 40                  JSONArray jsa = json.getJSONArray("Traces");
 41                      for(int i = 0;i < jsa.length();i++){
 42                          int j = 1;
 43                          JSONObject jst = jsa.getJSONObject(i);
 44                          Pattern p=Pattern.compile("(?<=【)(.*?)(?=】)");
 45                          Matcher m=p.matcher(jst.get("AcceptStation").toString());
 46                          while(m.find()&j ==1 ){
 47                              System.out.println(m.group());
 48                              String s = m.group(1);
 49                              addresses.add(s);
 50                              j++;
 51                          }
 52                      }
 53             }else{
 54                 addresses.add(0,"0");
 55                 addresses.add(1, em.getReason());
 56             }
 57         } catch (Exception e) {
 58             e.printStackTrace();
 59         }
 60         return addresses;
 61     }
 62
 63     /**
 64      * 处理没有物流信息的错误
 65      */
 66     public static errorManage eM(String result){
 67         errorManage em = new errorManage();
 68         JSONObject json = new JSONObject(result);
 69         System.out.println(json);
 70         String logcode = json.getString("LogisticCode");
 71         String shipcode = json.getString("ShipperCode");
 72         JSONArray jsa = json.getJSONArray("Traces");
 73         boolean a = json.getBoolean("Success");
 74         boolean b = !jsa.isNull(0);//如果Traces是空的,则b为false;如果Traces不空,则b为true
 75         if(a){
 76             if(json.has("State")){
 77                 int i = json.getInt("State");
 78                 if(b){
 79                     em.setSuccess(true);
 80                     em.setReason("");
 81                 }else{
 82                     if(i == 0){
 83                         em.setSuccess(false);
 84                         em.setReason("没有物流信息!您的包裹未发送或已到达目的城市!");
 85                     }else if(i == 4){
 86                         em.setSuccess(false);
 87                         em.setReason("问题件!");
 88                     }else if(i ==3){
 89                         em.setSuccess(false);
 90                         em.setReason("已签收");
 91                     }else{
 92                         em.setSuccess(false);
 93                         em.setReason("此单无物流信息!");
 94                     }
 95                 }
 96             }else if(!json.has("State")&b){
 97                 em.setSuccess(false);
 98                 em.setReason("已签收!");
 99             }else{
100                 em.setSuccess(false);
101                 em.setReason("没有订单信息,请检查您是否输入正确!");
102             }
103         }
104
105         return em;
106     }
107     /**
108      * Json方式 查询订单物流轨迹
109      * @throws Exception
110      */
111     public String getOrderTracesByJson(String expCode, String expNo) throws Exception{
112         String requestData= "{‘OrderCode‘:‘‘,‘ShipperCode‘:‘" + expCode + "‘,‘LogisticCode‘:‘" + expNo + "‘}";
113
114         Map<String, String> params = new HashMap<String, String>();
115         params.put("RequestData", urlEncoder(requestData, "UTF-8"));
116         params.put("EBusinessID", EBusinessID);
117         params.put("RequestType", "1002");
118         String dataSign=encrypt(requestData, AppKey, "UTF-8");
119         params.put("DataSign", urlEncoder(dataSign, "UTF-8"));
120         params.put("DataType", "2");
121
122         String result=sendPost(ReqURL, params);
123
124         //根据公司业务处理返回的信息......
125
126         return result;
127     }
128
129     /**
130      * XML方式 查询订单物流轨迹
131      * @throws Exception
132      */
133     public String getOrderTracesByXml() throws Exception{
134         String requestData= "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"+
135                             "<Content>"+
136                             "<OrderCode></OrderCode>"+
137                             "<ShipperCode>SF</ShipperCode>"+
138                             "<LogisticCode>589707398027</LogisticCode>"+
139                             "</Content>";
140
141         Map<String, String> params = new HashMap<String, String>();
142         params.put("RequestData", urlEncoder(requestData, "UTF-8"));
143         params.put("EBusinessID", EBusinessID);
144         params.put("RequestType", "1002");
145         String dataSign=encrypt(requestData, AppKey, "UTF-8");
146         params.put("DataSign", urlEncoder(dataSign, "UTF-8"));
147         params.put("DataType", "1");
148
149         String result=sendPost(ReqURL, params);
150
151         //根据公司业务处理返回的信息......
152
153         return result;
154     }
155
156     /**
157      * MD5加密
158      * @param str 内容
159      * @param charset 编码方式
160      * @throws Exception
161      */
162     private String MD5(String str, String charset) throws Exception {
163         MessageDigest md = MessageDigest.getInstance("MD5");
164         md.update(str.getBytes(charset));
165         byte[] result = md.digest();
166         StringBuffer sb = new StringBuffer(32);
167         for (int i = 0; i < result.length; i++) {
168             int val = result[i] & 0xff;
169             if (val <= 0xf) {
170                 sb.append("0");
171             }
172             sb.append(Integer.toHexString(val));
173         }
174         return sb.toString().toLowerCase();
175     }
176
177     /**
178      * base64编码
179      * @param str 内容
180      * @param charset 编码方式
181      * @throws UnsupportedEncodingException
182      */
183     private String base64(String str, String charset) throws UnsupportedEncodingException{
184         String encoded = base64Encode(str.getBytes(charset));
185         return encoded;
186     }
187
188     private String urlEncoder(String str, String charset) throws UnsupportedEncodingException{
189         String result = URLEncoder.encode(str, charset);
190         return result;
191     }
192
193     /**
194      * 电商Sign签名生成
195      * @param content 内容
196      * @param keyValue Appkey
197      * @param charset 编码方式
198      * @throws UnsupportedEncodingException ,Exception
199      * @return DataSign签名
200      */
201     private String encrypt (String content, String keyValue, String charset) throws UnsupportedEncodingException, Exception
202     {
203         if (keyValue != null)
204         {
205             return base64(MD5(content + keyValue, charset), charset);
206         }
207         return base64(MD5(content, charset), charset);
208     }
209
210      /**
211      * 向指定 URL 发送POST方法的请求
212      * @param url 发送请求的 URL
213      * @param params 请求的参数集合
214      * @return 远程资源的响应结果
215      */
216     private String sendPost(String url, Map<String, String> params) {
217         OutputStreamWriter out = null;
218         BufferedReader in = null;
219         StringBuilder result = new StringBuilder();
220         try {
221             URL realUrl = new URL(url);
222             HttpURLConnection conn =(HttpURLConnection) realUrl.openConnection();
223             // 发送POST请求必须设置如下两行
224             conn.setDoOutput(true);
225             conn.setDoInput(true);
226             // POST方法
227             conn.setRequestMethod("POST");
228             // 设置通用的请求属性
229             conn.setRequestProperty("accept", "*/*");
230             conn.setRequestProperty("connection", "Keep-Alive");
231             conn.setRequestProperty("user-agent",
232                     "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
233             conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
234             conn.setRequestProperty("kdniao-nocache", "true");
235             conn.connect();
236             // 获取URLConnection对象对应的输出流
237             out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
238             // 发送请求参数
239             if (params != null) {
240                   StringBuilder param = new StringBuilder();
241                   for (Map.Entry<String, String> entry : params.entrySet()) {
242                       if(param.length()>0){
243                           param.append("&");
244                       }
245                       param.append(entry.getKey());
246                       param.append("=");
247                       param.append(entry.getValue());
248                       //System.out.println(entry.getKey()+":"+entry.getValue());
249                   }
250                   //System.out.println("param:"+param.toString());
251                   out.write(param.toString());
252             }
253             // flush输出流的缓冲
254             out.flush();
255             // 定义BufferedReader输入流来读取URL的响应
256             in = new BufferedReader(
257                     new InputStreamReader(conn.getInputStream(), "UTF-8"));
258             String line;
259             while ((line = in.readLine()) != null) {
260                 result.append(line);
261             }
262         } catch (Exception e) {
263             e.printStackTrace();
264         }
265         //使用finally块来关闭输出流、输入流
266         finally{
267             try{
268                 if(out!=null){
269                     out.close();
270                 }
271                 if(in!=null){
272                     in.close();
273                 }
274             }
275             catch(IOException ex){
276                 ex.printStackTrace();
277             }
278         }
279         return result.toString();
280     }
281
282
283     private static char[] base64EncodeChars = new char[] {
284         ‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘,
285         ‘I‘, ‘J‘, ‘K‘, ‘L‘, ‘M‘, ‘N‘, ‘O‘, ‘P‘,
286         ‘Q‘, ‘R‘, ‘S‘, ‘T‘, ‘U‘, ‘V‘, ‘W‘, ‘X‘,
287         ‘Y‘, ‘Z‘, ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘,
288         ‘g‘, ‘h‘, ‘i‘, ‘j‘, ‘k‘, ‘l‘, ‘m‘, ‘n‘,
289         ‘o‘, ‘p‘, ‘q‘, ‘r‘, ‘s‘, ‘t‘, ‘u‘, ‘v‘,
290         ‘w‘, ‘x‘, ‘y‘, ‘z‘, ‘0‘, ‘1‘, ‘2‘, ‘3‘,
291         ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘+‘, ‘/‘ };
292
293     public static String base64Encode(byte[] data) {
294         StringBuffer sb = new StringBuffer();
295         int len = data.length;
296         int i = 0;
297         int b1, b2, b3;
298         while (i < len) {
299             b1 = data[i++] & 0xff;
300             if (i == len)
301             {
302                 sb.append(base64EncodeChars[b1 >>> 2]);
303                 sb.append(base64EncodeChars[(b1 & 0x3) << 4]);
304                 sb.append("==");
305                 break;
306             }
307             b2 = data[i++] & 0xff;
308             if (i == len)
309             {
310                 sb.append(base64EncodeChars[b1 >>> 2]);
311                 sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
312                 sb.append(base64EncodeChars[(b2 & 0x0f) << 2]);
313                 sb.append("=");
314                 break;
315             }
316             b3 = data[i++] & 0xff;
317             sb.append(base64EncodeChars[b1 >>> 2]);
318             sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]);
319             sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]);
320             sb.append(base64EncodeChars[b3 & 0x3f]);
321         }
322         return sb.toString();
323     }
324 }

代码:errorManage类

 1 package util;
 2
 3 public class errorManage {
 4     private boolean success;
 5     private String reason;
 6     errorManage(){
 7         this.success = true;
 8         this.reason = "";
 9     }
10     errorManage(boolean s,String r){
11         this.success = s;
12         this.reason = r;
13     }
14     public void setSuccess(boolean s){
15         this.success = s;
16     }
17     public void setReason(String r){
18         this.reason = r;
19     }
20     public boolean getSuccess(){
21         return this.success;
22     }
23     public String getReason(){
24         return this.reason;
25     }
26 }
时间: 2024-11-25 05:01:16

API开发实践(三) 查询物流路径的相关文章

API开发实践(一) 结构设计

参加了2017年的阿里云API创新大赛,自己一个人参加的第一赛段,把开发过程中的学到的知识总结一下. 我设计的API功能:用户输入自己货物的订单编号及公司编号,返回物流信息地图. 实现方法:调用两个API,一个是快递鸟快递查询API,一个是高德地图地图查询API,利用servlet处理上传的数据并返回一个HTML显示地图. 开发模式:JavaBean+servlst+html 开发工具:阿里云服务器.Tomcat.MyEclipse.org.json.jar 功能模块: 接受url请求 调用快递

API开发实践(四) 返回HTML

分为两个部分:生成HTML和返回HTML 生成HTML: 最终想要的时显示地图,不可避免的使用高德地图的API. [地图API]地址录入时如何获得准确的经纬度?淘宝收货地址详解 改变几个参数即可达到目的,很简单不讲了. 重点说说如何生成查询结果对应的HTML: 将HTML中的内容保存为String,在String格式的基础上替换关键参数,即可批量生产. 在将HTML保存为String时,因为HTML内容都是带换行缩进的,还带有许多双引号,所以直接粘贴实不可取的. 我用的方法是将内容先保存在文本中

基于天天动听API开发在线音乐查询网站

预览图 源码下载 地址:https://github.com/bajdcc/dev/tree/master/ttpod 文件夹说明: App_Code,WCF服务 Script,离线下载的celery任务配置 dl,离线下载接口 ttpod,网站主体 Bin,组件类库 实现功能 基于天天动听实现输入提示.查询功能 列表显示每条曲目的信息,自带搜索和排序功能 实现网页播放,支持大部分部分的视频与音频,并提供下载地址 适配较新版本的IE.Firefox和Chrome浏览器 支持广播,即可以远程使多个

API开发实践(二) 接受url请求

先简单理解GET请求与POST请求的区别 HTTP请求中POST与GET的区别 在浏览器地址栏输入 http://服务器地址:服务器端口/文件路径 即可访问目的文件或服务 如果带有参数就以 ?参数名=参数值[&参数名=参数值].* 的形式添加到请求中,再在服务器中用request.getParameter()方法取出. 代码:url:  http://localhost:8080/APITest/getMap.java?shipperCode="*"&logisticC

API开发第三篇:PHP的设计模式之完美的单例模式

今天来说一说单例模式. 由于我以前是做java开发的,在使用单例模式的时候,首先想到的想用饿汉式,然后发现在PHP中,有这样一个特性:因为PHP不支持在类定义时给类的成员变量赋予非基本类型的值.如表达式,new操作等等.所以了饿汉式这个就不行了.转而想要确保这个单例模式的原子性,发现PHP中也没有像JAVA中的线程安全问题.嘿嘿,你说PHP好不好?那么OK接下来就试试PHP的懒汉式单例模式了. 先不说,我先上我第一个版本的单例模式代码: // 定义私有静态变量.此种方式为:懒汉式单例(PHP中只

OWIN的理解和实践(三) –Middleware开发入门

原文:OWIN的理解和实践(三) –Middleware开发入门 上篇我们谈了Host和Server的建立,但Host和Server无法产出任何有实际意义的内容,真正的内容来自于加载于Server的Middleware,本篇我们就着重介绍下Middleware的开发入门. Middleware是什么 如果把HTTP交互理解为一次答题活动,那么Request是问题,Response就是答案,Server是课堂,Middleware就是参与者,注意我这里用的是参与而不是解答,因为我们允许有些Midd

《移动平台开发实践》第三周学习任务

目录 20189230杨静怡 2018-2019-2 <移动平台开发实践>第3周学习总结 学习<Java和Android开发学习指南(第二版)>第5.6.8.9章-- 教材学习中的问题和解决过程 代码调试中的问题和解决过程 [代码托管] statistics.sh脚本运行结果的截图 上周考试错题总结 学习进度条 参考资料 20189230杨静怡 2018-2019-2 <移动平台开发实践>第3周学习总结 学习<Java和Android开发学习指南(第二版)>

ASP.NET5+EntityFramework7开发实践(三)

1.说明 在<ASP.NET5+EntityFramework7开发实践(一)>介绍过仓储模式,只是没有在控制器中如何使用? 本章重新补充一下.注意,也会使用ASP.NET5中的依赖注入. 2.仓储模式 先看接口: 1 public interface IRoleRepository:IDisposable 2 { 3 //IEnumerable和IQueryable 4 //二者在EF都会延迟加载,不同的是: 5 //IEnumerable是数据加载到内存,刷选在内存中的数据上执行 6 //

使用GraceNote Web API开发Mac查询音乐信息应用

好久没写博客了,最近各种忙,大忙特忙,今晚难得有空,写个博客总结下最近完成的一个任务:使用GraceNote的Web API来开发一个查询音乐信息的应用,其实功能和前面的那些GraceNote SDK的博文是一样的,只是这一次不使用任何SDK,单纯的使用Web API,然后开发的平台从iOS转移到了Mac上,于是,我人生中第一个Mac App Demo就出来了. GraceNote Web API的官方资料:点击打开链接 首先看下基本的查询和响应的数据格式: 可以看到交互的形式是XML. 事实上