前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

接入百度LBS服务的那些「坑」,你踩过吗?

qiguaw 2024-09-11 06:12:38 资源文章 17 ℃ 0 评论

说起百度地图,国人可是无人不知无人不晓的,就连幼童和老人都知道打开百度地图来搜索目的地和导航路线,可见百度地图在采集路网数据、更新路况实时情况上是多么的准确和及时。

关于百度地图的详细讲解,大家可以移步到百度百科,上面对其有详细的说明。

作为国内第二大地图厂商,百度地图这几年发展迅猛,在LBS服务上更是加快了前行的脚步,所以一些第三方公司为了加快自己在地图和LBS方面的发展,都会选择接入百度地图、高德地图或腾讯地图的服务,这样可以最简单最快的深耕自己细分领域的业务,毕竟是「专业的人干专业的事儿」。

首先先给一下百度地图支持的接入服务全景图,从前端H5,安卓和IOS SDK到后端的Web API一应俱全。本文主要讲一下如何接入百度地图服务,主要涉及到前端、后端(Java)的详细配置,并以代码来详细介绍下后端接入百度地图Web API的流程。

控制台创建应用

用百度账号登录后,进入到百度地图开发平台的控制台界面,在里面点击创建应用,就会弹出下图中的页面,填入应用名称,选择好自己的应用类型(H5选浏览器端,Android选Android SDK,IOS选IOS SDK,服务端选服务端,微信小程序就选微信小程序),启用服务会根据自己选的应用类型不同,动态展示出对应的服务项目,比如默认是服务端,下面就列出了服务端提供的服务列表。

下面就是给个应用类型下,相对应的地图服务项目,大家可以根据自己实际的业务需求选择合适的服务项目。

创建好应用后,就可以在查看应用中看到新建好的应用,而且会给每个应用分配一个AK,用来控制访问应用,但需要注意的是之前申请的AK是可以直接用来访问应用中的API接口的,但现在百度升级了校验机制后,需要再拿一个SK来做一下复杂的生产sn的过程,稍后我会详细讲解下代码。

下面是我们项目中创建的应用,可以看出有安卓、iOS和Java后端,大家根据实际需求创建即可,当然每个项目都是收费的。

应用接入服务

下面我就以一个「地址检索」的接口为例详细说下Java后端如何接入地址服务。

1. 仔细查看后端API,确定「地址检索」服务API是哪个?

经过确认,地址检索的Web API接口为行政区划区域检索接口,姓名Url为:

http://api.map.baidu.com/place/v2/search?query=ATM机&tag=银行&region=北京&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,value>,该方法根据key的插入顺序排序;
 // post请使用TreeMap保存<key,value>,该方法会自动将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<String, String>();
 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请求的代码,很简单,具体如下:

整个调用流程就结束了,是不是非常简单,但其实在写代码过程中有很多小坑,大家有兴趣的试试就知道了。最后给大家一个返回值的截图,JSON格式的很容易读懂:

码子不易,欢迎大家点赞关注,如果感兴趣也欢迎留言讨论。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表