【第三方API】順豐API調用總結-java

一、獲取顧客編碼及校驗碼

   https://qiao.sf-express.com/index.html 豐橋系統中申請api接口,獲得url(調用地址)、clientCode(顧客編碼)、checkword(校驗碼)。

    url:http://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService

二、XML報文說明

    1.請求XML報文:

    service 屬性定義“服務名”;Head元素定義“顧客編碼”

<Request service="服務名" lang="zh-CN">
<Head>顧客編碼</Head>
<Body>請求數據XML</Body>

    2.響應XML報文:

     Head元素值爲“OK”或“ERR”;OK代表交易成功,ERR代表發生系統或業務異常,交易失敗;對於批量交易場景,只能爲成功/失敗,無部分成功/部分失敗

<Response service="服務名">
<Head>OK|ERR</HEAD>
<Body>正常響應數據XML</Body>
<ERROR code="NNNN">錯誤詳細信息</ERROR>

三、API接口詳情

    1.下訂單接口(OrderService):

    ①客戶系統向順豐下發訂單 ②爲訂單分配運單號

/**
 * 獲取順豐下訂單接口xml
 * @param params
 * @return
 */
private String getOrderServiceRequestXml(Map<String,String> params){
    //訂單號
    String orderNo = params.get("orderNo");
    //收件人
    String receiverName = params.get("receiverName");
    //收件人電話
    String receiverMobile = params.get("receiverMobile");
    //收件人詳細地址
    String receiverAddress = params.get("address");
    //商品名稱
    String commodityName = params.get("commodityName");
    //商品數量
    String orderNum = params.get("orderNum");


    StringBuilder strBuilder = new StringBuilder();
    strBuilder.append("<Request service='OrderService' lang='zh-CN'>");
    strBuilder.append("<Head>" + clientCode + "</Head>");
    strBuilder.append("<Body>");
    strBuilder.append("<Order").append(" ");
    strBuilder.append("orderid='" + orderNo.toString().trim() + "" + "'").append(" ");
    //返回順豐運單號
    strBuilder.append("is_gen_bill_no='1'").append(" ");
    //寄件方信息
    strBuilder.append("j_company='" + j_company + "'").append(" ");
    strBuilder.append("j_contact='" + j_contact + "'").append(" ");
    strBuilder.append("j_tel='" + j_tel + "'").append(" ");
    strBuilder.append("j_address='" + j_province+j_city+j_county+j_address + "'").append(" ");
    //收件方信息
    strBuilder.append("d_company='" + d_company + "'").append(" ");
    strBuilder.append("d_contact='" + receiverName.toString().trim() + "'").append(" ");
    strBuilder.append("d_tel='" + receiverMobile.toString().trim() + "'").append(" ");
    strBuilder.append("d_address='" + receiverAddress.toString().trim() + "'").append(" ");
    strBuilder.append(" > ");
    //貨物信息
    strBuilder.append("<Cargo").append(" ");
    strBuilder.append("name='" + commodityName + "'").append(" ");
    strBuilder.append("count='" + orderNum.toString() + "'").append(" ");
    strBuilder.append("unit='雙'").append(">");
    strBuilder.append("</Cargo>");

    strBuilder.append("</Order>");
    strBuilder.append("</Body>");
    strBuilder.append("</Request>");

    return strBuilder.toString();
}


    2.訂單結果查詢接口(OrderSearchService):

      因Internet環境下,網絡不是絕對可靠,用戶系統下訂單到順豐後,不一定可以收到順豐系統返回的數據,此接口用於在未收到返回數據時,查詢下訂單(含篩選)接口客戶訂單當前的處理情況。重複下單時可調用此接口查詢下單順豐單號

/**
 * 獲取順豐訂單結果查詢接口xml
 * @param params
 * @return
 */
private String getOrderSearchServiceRequestXml(Map<String,String> params){
    String orderNo = params.get("orderNo");
    StringBuilder strBuilder = new StringBuilder();
    strBuilder.append("<Request service='OrderSearchService' lang='zh-CN'>");
    strBuilder.append("<Head>" + clientCode + "</Head>");
    strBuilder.append("<Body>");
    strBuilder.append("<OrderSearch").append(" ");
    strBuilder.append("orderid='" + orderNo.toString().trim() + "" + "'").append(" > ");
    strBuilder.append("</OrderSearch>");
    strBuilder.append("</Body>");
    strBuilder.append("</Request>");
    return strBuilder.toString();
}

    3.路由查詢接口(RouteService):

      支持兩類查詢方式:①根據順豐運單號查詢 ②根據客戶訂單號查詢 

/**
 * 獲取順豐路由查詢接口xml
 * @param params
 * @return
 */
private String getRouteServiceRequestXml(Map<String,String> params){
    String orderNo = params.get("orderNo");
    StringBuilder strBuilder = new StringBuilder();
    strBuilder.append("<Request service='RouteService' lang='zh-CN'>");
    strBuilder.append("<Head>" + clientCode + "</Head>");
    strBuilder.append("<Body>");
    strBuilder.append("<RouteRequest").append(" ");
    strBuilder.append("tracking_type='2'").append(" ");
    strBuilder.append("tracking_number='" + orderNo.toString().trim() + "" + "'").append(" >");
    strBuilder.append("</RouteRequest>");
    strBuilder.append("</Body>");
    strBuilder.append("</Request>");
    return strBuilder.toString();
}

三、API接口調用

    ①把XML報文與checkword前後連接

    ②把連接後的字符串做MD5編碼

    ③把MD5編碼後的數據進行Base64編碼,此時編碼後的字符串即爲校驗碼

//接口url
@Value("${express.sf.url}")
private String url = "http://bsp-oisp.sf-express.com/bsp-oisp/sfexpressService"
/**
 * 順豐接口
 * @param params
 * @param type  1-下訂單接口  2-訂單結果查詢接口 3-路由查詢接口
 * @return
 */
@Override
public SfExpressResponse sfExpressMethod(Map<String,String> params, int type) throws Exception{
    logger.info("進入順豐接口:params={},type={}", JSONObject.toJSONString(params),type);
    if (type < 1){
        logger.warn("調用接口類型傳錯");
        return null;
    }
    String requestXml = "";
    String methodName = "";
    if (type == 1){
        //1.獲取下單xml
        requestXml = getOrderServiceRequestXml(params);
        methodName = "orderSerivce";
    } else if (type == 2){
        //1.獲取訂單結果查詢xml
        requestXml = getOrderSearchServiceRequestXml(params);
        methodName = "orderSearchService";
    } else if (type == 3){
        //1.獲取訂單物流路由
        requestXml = getRouteServiceRequestXml(params);
        methodName = "routeService";
    }
    //2.xml+checkword
    String verifyCode = requestXml + checkword;
    //3.MD5加密 + Base64編碼
    MessageDigest md5 = MessageDigest.getInstance("MD5");
    md5.update(verifyCode.getBytes("utf8"));
    verifyCode = Base64Util.encode(md5.digest());
    //4.post 請求
    Map<String, Object> toHttpParams = new HashMap<>();
    toHttpParams.put("xml",requestXml);
    toHttpParams.put("verifyCode",verifyCode);
    logger.info("請求順豐接口"+methodName, toHttpParams.toString());
    String resultStr = HttpExtUtil.doPost(url, toHttpParams);
    logger.info("請求順豐接口"+methodName+",result="+resultStr);
    SfExpressResponse response = (SfExpressResponse) 
                                               XMLUtil.convertToObject(SfExpressResponse.class,resultStr);
    return response;
}

四、響應XML解析

    綜合三個接口的response xml,將SfExpressResponse定義如下(樹狀結構對象):

/**
 * 順豐接口response對象
 * author: jing.mn
 * date: 2018/4/9 16:17
 * copyright wonhigh.net.cn
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Response")
public class SfExpressResponse implements Serializable {

    private static final long serialVersionUID = 1L;
    //響應狀態
    @XmlElement(name = "Head")
    private String Head;
    //響應失敗原因
    @XmlElement(name = "ERROR")
    private ERROR ERROR;
    //響應結果
    @XmlElement(name = "Body")
    private Body Body;


    @XmlAccessorType(XmlAccessType.NONE)
    public static class ERROR {
        @XmlAttribute(name = "code")
        private String code;
        @XmlValue
        private String text;

        public String getCode() {
            return code;
        }

        public void setCode(String code) {
            this.code = code;
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }
    }

    @XmlAccessorType(XmlAccessType.NONE)
    public static class Body {
        @XmlElement(name = "OrderResponse")
        private OrderResponse OrderResponse;

        @XmlElement(name = "RouteResponse")
        private RouteResponse RouteResponse;

        public SfExpressResponse.OrderResponse getOrderResponse() {
            return OrderResponse;
        }

        public void setOrderResponse(SfExpressResponse.OrderResponse orderResponse) {
            OrderResponse = orderResponse;
        }

        public SfExpressResponse.RouteResponse getRouteResponse() {
            return RouteResponse;
        }

        public void setRouteResponse(SfExpressResponse.RouteResponse routeResponse) {
            RouteResponse = routeResponse;
        }

    }

    @XmlRootElement(name="OrderResponse")
    @XmlAccessorType(XmlAccessType.NONE)
    public static class OrderResponse {
        //訂單號
        @XmlAttribute(name = "orderid")
        private String orderId;
        //運單號
        @XmlAttribute(name = "mailno")
        private String mailNo;
        //原寄地區域代碼(可用於順豐電子運單標籤打印)
        @XmlAttribute(name = "origincode")
        private String originCode;
        //目的地區域代碼(可用於順豐電子運單標籤打印)
        @XmlAttribute(name = "destcode")
        private String destCode;
        //篩單結果:1:人工確認 2:可收派 3:不可以收派
        @XmlAttribute(name = "filter_result")
        private String filterResult;


        public String getOrderId() {
            return orderId;
        }

        public void setOrderId(String orderId) {
            this.orderId = orderId;
        }

        public String getMailNo() {
            return mailNo;
        }

        public void setMailNo(String mailNo) {
            this.mailNo = mailNo;
        }

        public String getOriginCode() {
            return originCode;
        }

        public void setOriginCode(String originCode) {
            this.originCode = originCode;
        }

        public String getDestCode() {
            return destCode;
        }

        public void setDestCode(String destCode) {
            this.destCode = destCode;
        }

        public String getFilterResult() {
            return filterResult;
        }

        public void setFilterResult(String filterResult) {
            this.filterResult = filterResult;
        }
    }

    @XmlRootElement(name="RouteResponse")
    @XmlAccessorType(XmlAccessType.NONE)
    public static class RouteResponse {
        //運單號
        @XmlAttribute(name = "mailno")
        private String mailNo;
        //路由
        @XmlElement(name = "Route")
        private List<Route> Route ;

        public String getMailNo() {
            return mailNo;
        }

        public void setMailNo(String mailNo) {
            this.mailNo = mailNo;
        }

        public List<SfExpressResponse.Route> getRoute() {
            return Route;
        }

        public void setRoute(List<SfExpressResponse.Route> route) {
            Route = route;
        }
    }

    @XmlRootElement(name="Route")
    @XmlAccessorType(XmlAccessType.NONE)
    public static class Route {
        //路由節點發生的時間
        @XmlAttribute(name = "accept_time")
        private String acceptTime;

        //路由節點具體描述
        @XmlAttribute(name = "remark")
        private String remark;

        //路由節點操作碼
        @XmlAttribute(name = "opcode")
        private String opcode;

        public String getAcceptTime() {
            return acceptTime;
        }

        public void setAcceptTime(String acceptTime) {
            this.acceptTime = acceptTime;
        }

        public String getRemark() {
            return remark;
        }

        public void setRemark(String remark) {
            this.remark = remark;
        }

        public String getOpcode() {
            return opcode;
        }

        public void setOpcode(String opcode) {
            this.opcode = opcode;
        }
    }

    public String getHead() {
        return Head;
    }

    public void setHead(String head) {
        Head = head;
    }

    public SfExpressResponse.ERROR getERROR() {
        return ERROR;
    }

    public void setERROR(SfExpressResponse.ERROR ERROR) {
        this.ERROR = ERROR;
    }

    public SfExpressResponse.Body getBody() {
        return Body;
    }

    public void setBody(SfExpressResponse.Body body) {
        Body = body;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章