a.首先要认识到的是这些信息都属于外部接口,我们在进行接入的时候一定要注意到这些接口的参数设置,稍微一不留神就会出现接入失败的问题,而这些问题往往是我们不够认真导致的,所以,接入的时候一定要充分阅读官方的文档和示例。
2.项目需求:最近接到一个项目是工单系统,其中有一项内容是需要用到签到定位功能的,这时候就需要用到地图接口了,我选择了百度地图,当然做的时候最好和前台商量着来,前台最好也去调用百度的地图接口。但是自己做的时候就是出现了上述问题,报错APP SN校验失败,关于这个问题我发帖子和上百度搜索都无果,索性自己研究,最后发现是参数问题,我把ak的值放到了sk的位置,导致去调用接口的时候报错,就下面这一句:
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 & 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 }