接入百度LBS服務的那些「坑」,你踩過嗎?

說起百度地圖,國人可是無人不知無人不曉的,就連幼童和老人都知道打開百度地圖來搜索目的地和導航路線,可見百度地圖在採集路網數據、更新路況實時情況上是多麼的準確和及時。

關於百度地圖的詳細講解,大家可以移步到百度百科,上面對其有詳細的說明。

接入百度LBS服務的那些「坑」,你踩過嗎?

作為國內第二大地圖廠商,百度地圖這幾年發展迅猛,在LBS服務上更是加快了前行的腳步,所以一些第三方公司為了加快自己在地圖和LBS方面的發展,都會選擇接入百度地圖、高德地圖或騰訊地圖的服務,這樣可以最簡單最快的深耕自己細分領域的業務,畢竟是「專業的人幹專業的事兒」。

接入百度LBS服務的那些「坑」,你踩過嗎?

首先先給一下百度地圖支持的接入服務全景圖,從前端H5,安卓和IOS SDK到後端的Web API一應俱全。本文主要講一下如何接入百度地圖服務,主要涉及到前端、後端(Java)的詳細配置,並以代碼來詳細介紹下後端接入百度地圖Web API的流程。

接入百度LBS服務的那些「坑」,你踩過嗎?

控制檯創建應用

用百度賬號登錄後,進入到百度地圖開發平臺的控制檯界面,在裡面點擊創建應用,就會彈出下圖中的頁面,填入應用名稱,選擇好自己的應用類型(

H5選瀏覽器端,Android選Android SDK,IOS選IOS SDK,服務端選服務端,微信小程序就選微信小程序),啟用服務會根據自己選的應用類型不同,動態展示出對應的服務項目,比如默認是服務端,下面就列出了服務端提供的服務列表。

接入百度LBS服務的那些「坑」,你踩過嗎?

下面就是給個應用類型下,相對應的地圖服務項目,大家可以根據自己實際的業務需求選擇合適的服務項目。

接入百度LBS服務的那些「坑」,你踩過嗎?

創建好應用後,就可以在查看應用中看到新建好的應用,而且會給每個應用分配一個AK,用來控制訪問應用,但需要注意的是之前申請的AK是可以直接用來訪問應用中的API接口的,但現在百度升級了校驗機制後,需要再拿一個SK來做一下複雜的生產sn的過程,稍後我會詳細講解下代碼。

接入百度LBS服務的那些「坑」,你踩過嗎?

下面是我們項目中創建的應用,可以看出有安卓、iOS和Java後端,大家根據實際需求創建即可,當然每個項目都是收費的。

接入百度LBS服務的那些「坑」,你踩過嗎?

應用接入服務

下面我就以一個「地址檢索」的接口為例詳細說下Java後端如何接入地址服務。

1. 仔細查看後端API,確定「地址檢索」服務API是哪個?

經過確認,地址檢索的Web API接口為行政區劃區域檢索接口,姓名Url為:

http://api.map.baidu.com/place/v2/search?query=ATM機&tag=銀行®ion=北京&output=json&ak=您的ak //GET請求
 

2.關鍵參數說明

query:檢索的關鍵字;

region:檢索行政區劃區域,限制關鍵字的區域範圍;

output:輸出的數據格式,可以是json或xml;

ak:開發者的訪問密鑰;

sn:開發者的權限簽名;

3. 開發者權限簽名sn生成

創建完應用後,會給應用生成一個ak和一個sk,ak的作用大家也知道了,就是在請求的url上當做參數傳給服務端,但sk是幹什麼呢?最終請求百度API時需要的sn又是幹什麼的?是如何生成的呢?

sn就是signature簽名,是為了加強接口的安全性根據入參和sk的值動態計算出來的,這樣就增加了接口被刷的難度,提高了服務的併發性。

sn計算出來後,百度的服務會根據入參和sk也會自動計算出一個簽名,跟請求方傳過去的簽名比對,相等則提供服務,不相等咋拒絕服務,返回錯誤。

根據入參和sk計算sn的代碼:

public static String calSn(final String query, final String region, final String ak, final String sk) {
 // 計算sn跟參數對出現順序有關,get請求請使用LinkedHashMap保存,該方法根據key的插入順序排序;
 // post請使用TreeMap保存,該方法會自動將key按照字母a-z順序排序。
 // 所以get請求可自定義參數順序(sn參數必須在最後)發送請求,但是post請求必須按照字母a-z順序填充body(sn參數必須在最後)。
 // 以get請求為例:http://api.map.baidu.com/geocoder/v2/?address=百度大廈&output=json&ak=yourak,paramsMap中先放入address,再放output,然後放ak,
 // 放入順序必須跟get請求中對應參數的出現順序保持一致。
 Map paramsMap = new LinkedHashMap();
 paramsMap.put("query", query);
 paramsMap.put("region", region);
 paramsMap.put("output", "json");
 paramsMap.put("ak", ak);
 // 調用下面的toQueryString方法,對LinkedHashMap內所有value作utf8編碼
 String paramsStr = toQueryString(paramsMap);
 if (null == paramsStr) {
 return null;
 }
 // 拼接接口
 String wholeStr = new String("/place/v2/search?" + paramsStr + sk);
 // 對上面wholeStr再作utf8編碼
 String tempStr = null;
 try {
 tempStr = URLEncoder.encode(wholeStr, "UTF-8");
 } catch (UnsupportedEncodingException e) {
 e.printStackTrace();
 return null;
 }
 // 調用下面的MD5方法得到最後的sn簽名
 return MD5(tempStr);
}

對Map內所有value做UTF-8轉換,拼接後返回結果:

public static String toQueryString(Map, ?> data) {
 StringBuffer queryString = new StringBuffer();
 try {
 for (Map.Entry, ?> pair : data.entrySet()) {
 queryString.append(pair.getKey() + "=");
 queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8") + "&");
 }
 if (queryString.length() > 0) {
 queryString.deleteCharAt(queryString.length() - 1);
 }
 return queryString.toString();
 } catch (UnsupportedEncodingException e) {
 e.printStackTrace();
 }
 return null;
}

來自stackoverflow的MD5計算方法,調用了MessageDigest庫函數,並把byte數組結果轉換成16進制:

public static String MD5(String md5) {
 try {
 java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5");
 byte[] array = md.digest(md5.getBytes());
 StringBuffer sb = new StringBuffer();
 for (int i = 0; i < array.length; ++i) {
 sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
 }
 return sb.toString();
 } catch (java.security.NoSuchAlgorithmException e) {
 }
 return null;
}

4. 發送請求,調用百度API

拿著第三步生成的簽名,和之前的參數和ak,調用百度的Web API,返回結果。

其實就是個發送http請求的代碼,很簡單,具體如下:

接入百度LBS服務的那些「坑」,你踩過嗎?

整個調用流程就結束了,是不是非常簡單,但其實在寫代碼過程中有很多小坑,大家有興趣的試試就知道了。最後給大家一個返回值的截圖,JSON格式的很容易讀懂:

接入百度LBS服務的那些「坑」,你踩過嗎?

碼子不易,歡迎大家點贊關注,如果感興趣也歡迎留言討論。


分享到:


相關文章: