API开发实践 查询物流路径

Posted 知止

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }

 

以上是关于API开发实践 查询物流路径的主要内容,如果未能解决你的问题,请参考以下文章

API开发实践 结构设计

物流即使查询API - JAVA篇

国内主流快递物流查询API接口测评对比

如何最快实现物流即使查询功能-物流轨迹查询API

快递鸟物流查询接口API调用代码示例

中通快递-单号查询接口-物流路由跟踪信息快递鸟api对接教程