WebApiClient百度地图服务接口实践
1. 文章目的
随着WebApiClient的不断完善,越来越多开发者选择WebApiClient替换原生的HttpClient,然而在应用到实际项目中多多少少会遇到一些项目结合上的疑问和困难,本文将以WebApiClient使用者的身份,在Asp.net core mvc项目中使用WebApiClient来请求百度地图服务接口,以展示WebApiClient的使用技巧。
2. 百度地图服务接口
坐标转换接口
http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak=你的密钥
3. 接口分析
通过分析百度地图的接口,我们发现:
- 所有接口都在api.map.baidu.com这个域名上;
- ak参数是一个客户端身份标识的参数,所有请求接口都需要附加这个ak值;
- 接口中需要的116.403874,39.914888这种参数值,实际是(经度,纬度),为两个值组成;
- from和to是枚举数值类型;
在我们进行Coding的时候,应该重点考虑这些共性,以减少重复的工作内容。
4. 接口声明
4.1 公共域名
[HttpHost("http://api.map.baidu.com/")]
public interface IBdMapApi : IHttpApi
{
}
4.2 公共的AK参数
我们要实现一个接口级或方法级的ApiAction特性,用于给请求路径增加公共的ak参数:
/// <summary>
/// 表示百度AK信息
/// </summary>
public class AkAttribute : ApiActionAttribute
{
private readonly string ak;
/// <summary>
/// 百度AK信息
/// 执行时追加到请求query
/// </summary>
/// <param name="ak"></param>
public AkAttribute(string ak)
{
this.ak = ak;
}
/// <summary>
/// 请求前
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task BeforeRequestAsync(ApiActionContext context)
{
context.RequestMessage.AddUrlQuery("ak", this.ak);
await Task.CompletedTask;
}
然后把Ak特性追加到接口上:
[HttpHost("http://api.map.baidu.com/")]
[Ak("qde9uxuEhwMlngvTbWGo3BIQOKfqvjdc")]
public interface IBdMapApi : IHttpApi
{
}
4.3 静态图staticimage接口
参照接口文档,声明最初的StaticImage接口:
[HttpGet("staticimage/v2")]
ITask<Stream> StaticImageAsync(
string center,
int width = 300,
int height = 200,
int zoom = 11,
int mcode = 666666);
目前center参数是string类型,约束性非常弱,与接口要求的(经度,纬度)这种格式数据差异比较大。所以我们应该定一个继承自IApiParameterable的BdLocation类型,将传入的经度和纬度转换为这种文本格式:
/// <summary>
/// 表示位置信息
/// </summary>
public class BdLocation : IApiParameterable
{
/// <summary>
/// 获取位置值
/// </summary>
public string Value { get; private set; }
/// <summary>
/// 位置信息
/// 执行时追加到请求query
/// </summary>
/// <param name="lng">经</param>
/// <param name="lat">纬</param>
public BdLocation(decimal lng, decimal lat)
{
this.Value = $"{lng},{lat}";
}
public override string ToString()
{
return this.Value;
}
/// <summary>
/// 自解释模式
/// </summary>
/// <param name="context"></param>
/// <param name="parameter"></param>
/// <returns></returns>
Task IApiParameterable.BeforeRequestAsync(ApiActionContext context, ApiParameterDescriptor parameter)
{
context.RequestMessage.AddUrlQuery(parameter.Name, this.Value);
return Task.CompletedTask;
}
}
修改后StaticImage接口修改为:
[HttpGet("staticimage/v2")]
ITask<Stream> StaticImageAsync(
BdLocation center,
int width = 300,
int height = 200,
int zoom = 11,
int mcode = 666666);
4.4 坐标转换Geoconv接口
依照文档,编写出最初的接口
[HttpGet("geoconv/v1/")]
ITask<string> GeoconvAsync(
string coords,
int from = 1,
int to = 5);
和StaticImage接口一样,我们还需要合理修改这个接口的参数约束,coords实际为BdLocation类型, from和to可以修改为枚举类型,返回值string修改为强类型的模型,修改后的接口为:
[HttpGet("geoconv/v1/")]
ITask<BdResult<BdPoint[]>> GeoconvAsync(
BdLocation coords,
BdFrom from = BdFrom.wgs84,
BdTo to = BdTo.bd09ll);
4.5 完整的接口声明
/// <summary>
/// 定义百度地图接口
/// </summary>
[Ak("qde9uxuEhwMlngvTbWGo3BIQOKfqvjdc")]
[HttpHost("http://api.map.baidu.com/")]
public interface IBdMapApi : IHttpApi
{
/// <summary>
/// 静态图
/// </summary>
/// <param name="center"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="zoom"></param>
/// <param name="mcode"></param>
/// <returns></returns>
// http://api.map.baidu.com/staticimage/v2?ak=你的密钥&mcode=666666¢er=116.403874,39.914888&width=300&height=200&zoom=11
[HttpGet("staticimage/v2")]
ITask<Stream> StaticImageAsync(
BdLocation center,
int width = 300,
int height = 200,
int zoom = 11,
int mcode = 666666);
/// <summary>
/// 坐标转换
/// </summary>
/// <param name="coords"></param>
/// <param name="from"></param>
/// <param name="to"></param>
/// <returns></returns>
// http://api.map.baidu.com/geoconv/v1/?coords=114.21892734521,29.575429778924&from=1&to=5&ak=你的密钥 //GET请求
[HttpGet("geoconv/v1/")]
ITask<BdResult<BdPoint[]>> GeoconvAsync(
BdLocation coords,
BdFrom from = BdFrom.wgs84,
BdTo to = BdTo.bd09ll);
}
5. 接口的依赖注入
WebApiClient的HttpApiClient创建的代理实例,适合使用单例模式,在支持依赖注入的项目开发中,应尽量使用依赖注入来完成HttpApiClient的创建和生命周期管理。
5.1 Asp.net core的依赖注入
在ConfigureServices方法里添加IBdMapApi的注入配置
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton(HttpApiClient.Create<IBdMapApi>());
......
}
如果项目里声明了很多接口,比如IBaiduApi、ITengxunApi等等,可以循环批量注入:
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
var apis = this.GetType().Assembly.GetTypes().Where(item => typeof(IHttpApi).IsAssignableFrom(item));
foreach (var api in apis)
{
services.AddSingleton(api, HttpApiClient.Create(api, new HttpApiConfig()));
}
}
5.2 接收和使用IBdMapApi代理实例
public class HomeController : Controller
{
private readonly IBdMapApi bdMapApi;
public HomeController(IBdMapApi bdMapApi)
{
this.bdMapApi = bdMapApi;
}
public async Task<IActionResult> Index()
{
var image = await this.bdMapApi.StaticImageAsync(new BdLocation(116.403874m, 39.914888m));
var geoResult = await this.bdMapApi.GeoconvAsync(new BdLocation(116.403874m, 39.914888m));
return View();
}
}
6. 监视请求提交的内容
WebApiClient对Http请求进行的高度抽象,只有声明,没有实现,在没有熟悉WebApiClient的情况下,我们开发中可能需要在请求发送的内容进行监视,从而知道是否符合服务器的接口数据要求。在不使用第三方工具比如Fiddler等的情况下,我们可以为接口修饰一个自定义过滤器,在过滤器里实现访打印求消息内容的能力。
6.1 定义TraceFilter过滤器
/// <summary>
/// 请求内容追踪过滤器
/// </summary>
public class TraceFilter : ApiActionFilterAttribute
{
/// <summary>
/// 打印请求内容
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public override async Task OnBeginRequestAsync(ApiActionContext context)
{
var request = await context.RequestMessage.ToStringAsync();
System.Diagnostics.Debug.Print(request);
}
}
6.2 接口关联TraceFilter
/// <summary>
/// 定义百度地图接口
/// </summary>
[TraceFilter]
[Ak("qde9uxuEhwMlngvTbWGo3BIQOKfqvjdc")]
[HttpHost("http://api.map.baidu.com/")]
public interface IBdMapApi : IHttpApi
{
}
6.3 查看请求内容
开启程序调试,输出窗口里打印
GET /staticimage/v2?ak=qde9uxuEhwMlngvTbWGo3BIQOKfqvjdc¢er=116.403874%2c39.914888&width=300&height=200&zoom=11&mcode=666666 HTTP/2.0
Host: api.map.baidu.com
GET /geoconv/v1/?ak=qde9uxuEhwMlngvTbWGo3BIQOKfqvjdc&coords=116.403874%2c39.914888&from=1&to=5 HTTP/2.0
Host: api.map.baidu.com
7. 结束语
博主为WebApiClient库的作者,致力于站在使用者的角度去设计WebApiClient,欢迎大家给WebApiClient提建议。
WebApiClient百度地图服务接口实践的更多相关文章
- httpclient案例二(调用百度地图的接口)
一,class T package com.http.test; import org.junit.Test; import com.http.BaiduMapProxyService; import ...
- 简单几行代码使用百度地图API接口分页获取信息
首发于: 万能助手扩展开发:使用百度地图API接口分页获取信息_电脑计算机编程入门教程自学 http://jianma123.com/viewthread.aardio?threadid=426 使用 ...
- Angular 调用百度地图API接口
Angular 调用百度地图API接口 参考原文:https://blog.csdn.net/yuyinghua0302/article/details/80624274 下面简单介绍一下如何在Ang ...
- tp5 封装百度地图api接口
//服务器端api extend\Map <?php /** * 百度地图业务封装 */ class Map{ /** * 根据地址来获取经纬度 * @param $address */ pub ...
- 百度云服务接口错误:Parameter invalid, the key input with filter parameter is not searchfilter column key
百度LBS云服务接口: 地址:http://lbsyun.baidu.com/index.php?title=lbscloud/api/geosearch 访问接口:http://api.map.ba ...
- 百度地图API应用实践(一) —— 栅格图(草稿)
概述 运用百度地图JS API,实现了在百度地图上绘制栅格并按统计值渲染栅格颜色.实现的过程是不断补习的过程,其中用到一些技术,是个人首次尝试.包括:(1)简单的jQuery语法,并实现Ajax:(2 ...
- 百度地图HTML接口
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.3
/** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...
- 百度地图LV1.5实践项目开发工具类bmap.util.jsV1.2
/** * 百度地图使用工具类-v1.5 * * @author boonya * @date 2013-7-7 * @address Chengdu,Sichuan,China * @email b ...
随机推荐
- vector作为函数返回类型
在实际的操作中,我们经常会碰到需要返回一序列字符串或者一列数字的时候,以前会用到数组来保存这列的字符串或者数字,现在我们可以用vector来保存这些数据.但是当数据量很大的时候使用vector效率就比 ...
- 【bzoj 3309 】 DZY Loves Math
Description 对于正整数n,定义f(n)为n所含质因子的最大幂指数.例如f(1960)=f(2^3 * 5^1 * 7^2)=3, f(10007)=1, f(1)=0.给定正整数a,b,求 ...
- 关于react组件之间的通信
才开始学react刚好到组件通信这一块,就简单的记录下组件间的通信方式:父到子:props.context,子到父:自定义事件.回调,兄弟组件:共父props传递.自定义事件import React, ...
- ROC曲线的概念和意义
ROC曲线 受试者工作特征曲线 (receiver operating characteristic curve,简称ROC曲线),又称为感受性曲线(sensitivity curve).得此名的原因 ...
- python3环境搭建(uWSGI+django+nginx+python+MySQL)
1.系统环境,必要知识 #cat /etc/redhat-release CentOS Linux release (Core) #uname -r -.el7.x86_64 暂时关闭防护墙,关闭se ...
- TCP报文解析
概述 在<网络基础总结(一)>总结了TCP建立连接和断开连接的流程,然而TCP协议远比我所了解的复杂得多,我所知的可以说就冰山一角,所总结的也只是纸上谈兵,仅仅只能对TCP有个肤浅的认识, ...
- 从壹开始前后端分离[.NetCore] 37 ║JWT完美实现权限与接口的动态分配
缘起 本文已经有了对应的管理后台,地址:https://github.com/anjoy8/Blog.Admin 哈喽大家好呀!又过去一周啦,这些天小伙伴们有没有学习呀,已经有一周没有更新文章了,不过 ...
- Python中os和sys模块中常用的方法
os模块 os模块:该模块提供了一些方便使用操作系统相关功能的函数 os.remove() 删除文件 os.rename() 重命名文件 os.walk() 文件目录遍历器 os.chdir() 改变 ...
- Windows核心编程第二章,字符串的表示以及宽窄字符的转换
目录 Windows核心编程,字符串的表示以及宽窄字符的转换 1.字符集 1.1.双字节字符集DBCS 1.2 Unicode字符集 1.3 UTF-8编码 1.4 UTF - 32编码. 1.5 U ...
- Unity_新手必懂知识点
翻车了!!!一个小例子带你了解闭包.事故现场:场景:6个button,上方1个text.点击button,text会显示button上的数字.代码如下: //在unity里面赋值public List ...