• 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 }
  • 相关阅读:
    ssize_t与size_t的前世今生
    jQuery 中的事件参数传递机制
    链表的container_of 疑惑
    c 语言使用疑惑小记
    IQueryFilter的WhereClause详解
    给自己鼓励...
    什么是闭包,我的理解
    WCF 第五章 行为 为服务终结点行为实现一个消息检测器
    WCF 第五章 行为 事务之事务服务行为
    WCF 第四章 绑定 wsHttpBinding
  • 原文地址:https://www.cnblogs.com/cxy2016/p/6884312.html
Copyright © 2020-2023  润新知