關於java后台接入百度地圖返回參數為{"status":211,"message":"APP SN校驗失敗"}的解決方法


1.關於百度地圖,天氣預報,微信公眾平台等一系列權威機構java接入的認識:

  a.首先要認識到的是這些信息都屬於外部接口,我們在進行接入的時候一定要注意到這些接口的參數設置,稍微一不留神就會出現接入失敗的問題,而這些問題往往是我們不夠認真導致的,所以,接入的時候一定要充分閱讀官方的文檔和示例。

  b.這類的官方平台我們要接入都需要注冊賬號,注冊之后需要在平台上進行設置,按照自己的習慣問題一一去設置該設置的參數,然后再去做自己的開發。

  c.建議接入之前最好進行簡單的接口調用測試,把這些參數都搞清楚再去布局代碼。

2.項目需求:最近接到一個項目是工單系統,其中有一項內容是需要用到簽到定位功能的,這時候就需要用到地圖接口了,我選擇了百度地圖,當然做的時候最好和前台商量着來,前台最好也去調用百度的地圖接口。但是自己做的時候就是出現了上述問題,報錯APP SN校驗失敗,關於這個問題我發帖子和上百度搜索都無果,索性自己研究,最后發現是參數問題,我把ak的值放到了sk的位置,導致去調用接口的時候報錯,就下面這一句:

3.最后附上完整的測試代碼(也是官方的代碼)

  1     //演示get、post請求如何算sn,算得sn如何使用
  2     import java.io.ByteArrayOutputStream;
  3     import java.io.InputStream;
  4     import java.io.UnsupportedEncodingException;
  5     import java.net.URLEncoder;
  6     import java.util.ArrayList;
  7     import java.util.LinkedHashMap;
  8     import java.util.List;
  9     import java.util.Map;
 10     import java.util.Map.Entry;
 11     import java.util.TreeMap;
 12 
 13     //需要httpclient-x.x.jar,httpcore-x.x.jar,commons-logging-x.x.jar,commons-httpclient-x.x.jar,commons-codec-x.x.jar包發http請求
 14     import org.apache.commons.httpclient.URIException;
 15     import org.apache.commons.httpclient.util.URIUtil;
 16     import org.apache.http.HttpEntity;
 17     import org.apache.http.HttpResponse;
 18     import org.apache.http.NameValuePair;
 19     import org.apache.http.client.HttpClient;
 20     import org.apache.http.client.entity.UrlEncodedFormEntity;
 21     import org.apache.http.client.methods.HttpGet;
 22     import org.apache.http.client.methods.HttpPost;
 23     import org.apache.http.impl.client.DefaultHttpClient;
 24 import org.apache.http.message.BasicNameValuePair;
 25 
 26     @SuppressWarnings("deprecation")
 27     public class test02 {
 28         public static void main(String[] args) throws Exception {
 29             test02 test02 = new test02();
 30             test02.testGet();
 31             test02.testPost();
 32         }
 33 
 34         @SuppressWarnings("all")
 35         public void testGet() throws Exception {
 36             /**
 37              * 以http://api.map.baidu.com/geocoder/v2/?address=百度大廈&output=json&ak=yourak為例
 38              * ak設置了sn校驗不能直接使用必須在url最后附上sn值,get請求計算sn跟url中參數對出現順序有關,需按序填充paramsMap,
 39              * post請求是按字母序填充,具體參照testPost()
 40              */
 41             Map paramsMap = new LinkedHashMap<String, String>();
 42             paramsMap.put("address", "百度大廈");
 43             paramsMap.put("output", "json");
 44             paramsMap.put("ak", "XWnIC5k1cguL71ClpinbhmozUsBWY4Xr");
 45 
 46             // 調用下面的toQueryString方法,對paramsMap內所有value作utf8編碼
 47             String paramsStr = toQueryString(paramsMap);
 48 
 49             // 對paramsStr前面拼接上/geocoder/v2/?,后面直接拼接yoursk
 50             String wholeStr = new String("/geocoder/v2/?" + paramsStr + "rbCHDhb9fARPyxGVDhLSifx7IO4vWk");
 51 
 52             // 對上面wholeStr再作utf8編碼
 53             String tempStr = URLEncoder.encode(wholeStr, "UTF-8");
 54 
 55             // 調用下面的MD5方法得到sn簽名值d
 56             String sn = MD5(tempStr);
 57 
 58             // 算得sn后發送get請求
 59             HttpClient client = new DefaultHttpClient();
 60             HttpGet httpget = new HttpGet( "http://api.map.baidu.com/geocoder/v2/?address=百度大廈&output=json&ak=XWnIC5k1cguL71ClpinbhmozUsBWY4Xr&sn=" + sn);
 61             HttpResponse response = client.execute(httpget);
 62             InputStream is = response.getEntity().getContent();
 63             String result = inStream2String(is);
 64             // 打印響應內容
 65             System.out.println(result);
 66         }
 67 
 68         public void testPost() throws Exception {
 69             /**
 70              * 以http://api.map.baidu.com/geodata/v3/geotable/create創建表為例
 71              */
 72             LinkedHashMap<String, String> paramsMap = new LinkedHashMap<String, String>();
 73             paramsMap.put("geotype", "1");
 74             paramsMap.put("ak", "yourak");
 75             paramsMap.put("name", "geotable80");
 76             paramsMap.put("is_published", "1");
 77 
 78             // post請求是按字母序填充,對上面的paramsMap按key的字母序排列
 79             Map<String, String> treeMap = new TreeMap<String, String>(paramsMap);
 80             String paramsStr = toQueryString(treeMap);
 81 
 82             String wholeStr = new String("/geodata/v3/geotable/create?" + paramsStr
 83                     + "yoursk");
 84             String tempStr = URLEncoder.encode(wholeStr, "UTF-8");
 85             // 調用下面的MD5方法得到sn簽名值
 86             String sn = MD5(tempStr);
 87 
 88             HttpClient client = new DefaultHttpClient();
 89             HttpPost post = new HttpPost(
 90                     "http://api.map.baidu.com/geodata/v3/geotable/create");
 91             List<NameValuePair> params = new ArrayList<NameValuePair>();
 92             params.add(new BasicNameValuePair("geotype", "1"));
 93             params.add(new BasicNameValuePair("ak", "yourak"));
 94             params.add(new BasicNameValuePair("name", "geotable80"));
 95             params.add(new BasicNameValuePair("is_published", "1"));
 96             params.add(new BasicNameValuePair("sn", sn));
 97             HttpEntity formEntity = new UrlEncodedFormEntity(params);
 98             post.setEntity(formEntity);
 99             HttpResponse response = client.execute(post);
100             InputStream is = response.getEntity().getContent();
101             String result = inStream2String(is);
102             // 打印響應內容
103             System.out.println(result);
104         }
105 
106         // 對Map內所有value作utf8編碼,拼接返回結果
107         public String toQueryString(Map<?, ?> data)
108                 throws UnsupportedEncodingException, URIException {
109             StringBuffer queryString = new StringBuffer();
110             for (Entry<?, ?> pair : data.entrySet()) {
111                 queryString.append(pair.getKey() + "=");
112                 // queryString.append(URLEncoder.encode((String) pair.getValue(),
113                 // "UTF-8") + "&");
114                 queryString.append(URIUtil.encodeQuery((String) pair.getValue(),
115                         "UTF-8") + "&");
116             }
117             if (queryString.length() > 0) {
118                 queryString.deleteCharAt(queryString.length() - 1);
119             }
120             return queryString.toString();
121         }
122 
123         // MD5計算方法,調用了MessageDigest庫函數,並把byte數組結果轉換成16進制
124         public String MD5(String md5) {
125             try {
126                 java.security.MessageDigest md = java.security.MessageDigest
127                         .getInstance("MD5");
128                 byte[] array = md.digest(md5.getBytes());
129                 StringBuffer sb = new StringBuffer();
130                 for (int i = 0; i < array.length; ++i) {
131                     sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100)
132                             .substring(1, 3));
133                 }
134                 return sb.toString();
135             } catch (java.security.NoSuchAlgorithmException e) {
136             }
137             return null;
138         }
139 
140         // 將輸入流轉換成字符串
141         private static String inStream2String(InputStream is) throws Exception {
142             ByteArrayOutputStream baos = new ByteArrayOutputStream();
143             byte[] buf = new byte[1024];
144             int len = -1;
145             while ((len = is.read(buf)) != -1) {
146                 baos.write(buf, 0, len);
147             }
148             return new String(baos.toByteArray(), "UTF-8");
149         }
150     }

4.總結:總之,我們在調用平台的接口時,一定要注意參數問題,不可再不知道參數的情況下胡亂的粘貼復制,這樣就很難保證代碼的成功率了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM