全部产品
云市场

Android 接入

更新时间:2019-12-05 15:10:10

Android Mtop网关接入文档

1. 依赖

在当前工程的 build.gradle 文件中添加依赖

  1. compile('com.taobao.android:mtopsdk_allinone:3.0.9.1-open@jar')

2. 初始化

2.1 设置加签实现

根据 appKey、appSecret设置加签实现。

  1. MtopSetting.setISignImpl(Mtop.Id.INNER, new LocalInnerSignImpl(mAppkey, mAppSecret));
2.2 设置appVersion

初始化mtopsdk前设置应用APP的版本appVersion。

  1. MtopSetting.setAppVersion(Mtop.Id.INNER, appVersion)
2.3 设置全局域名

统一设置线上、预发、日常的域名,一般来说,这3个域名完全一致。

注意:当 API网关 和 NativeDevops/跨平台Devops 一起使用时,NativeDevops/跨平台Devops 的业务请求也会走Mtop网络库,此时,这个全局域名应当设置 NativeDevops/跨平台Devops 的业务域名,而API网关使用的域名,延迟到真正请求发起时,通过 setCustomDomain() 接口设置。

  1. MtopSetting.setMtopDomain(Mtop.Id.INNER, onlineDomain, preDomain, dailyDomain);
2.4 初始化实例

MTOP 初始化放在应用 Application 的 onCreate() 方法中

渠道 ttid 可以在初始化时设置,或者在生成实例后设置。

  1. Mtop mtopInstance = Mtop.instance(Mtop.Id.INNER, mApplication.getApplicationContext(), "");
  2. mtopInstance.registerTtid(mTTid);
2.5 环境切换

外部版本一律切换为日常环境。

  1. // 设置日常环境
  2. mtopInstance.switchEnvMode(EnvModeEnum.TEST);
2.6 初始化示例
  1. private void initMtop() {
  2. // 调试日志开关,接入时可以打开调试
  3. TBSdkLog.setTLogEnabled(false);
  4. // 关闭SSL
  5. if (mUseHttp) {
  6. NetworkConfigCenter.setSSLEnabled(false);
  7. }
  8. // [option]关闭MTOP请求长链,调用后Mtop请求直接调用NetworkSDK的HttpNetwork发请求
  9. SwitchConfig.getInstance().setGlobalSpdySwitchOpen(false);
  10. // 关闭MTOPSDK NewDeviceID逻辑
  11. MtopSetting.setEnableProperty(Mtop.Id.INNER, MtopEnablePropertyType.ENABLE_NEW_DEVICE_ID, false);
  12. // 设置自定义全局访问域名
  13. MtopSetting.setMtopDomain(Mtop.Id.INNER, mMtopHost, mMtopHost, mMtopHost);
  14. // 设置自定义签名使用的appKey和appSecret
  15. MtopSetting.setISignImpl(Mtop.Id.INNER, new LocalInnerSignImpl(mAppkey, mAppSecret));
  16. MtopSetting.setAppVersion(Mtop.Id.INNER, BuildConfig.VERSION_NAME);
  17. Mtop mtopInstance = Mtop.instance(Mtop.Id.INNER, mApplication.getApplicationContext(), "");
  18. mtopInstance.switchEnvMode(EnvModeEnum.TEST);
  19. mtopInstance.registerTtid(mTTid);
  20. }

3. 请求构建

3.1 生成MtopRequest实例
  1. MtopRequest request = new MtopRequest();
  2. request.setApiName(String apiName); // API接口名称
  3. request.setVersion(String apiVersion); // API接口版本
  4. // 非透传时:API接口输入参数,接收入参Map<String,String>,调用工具方法ConvertMapToDataStr拼接data字符串
  5. request.setData(ReflectUtil.convertMapToDataStr(Map<String, String> ApiParamsMap));
  6. // 透传时:直接设置需要透传的字符串
  7. request.setData(String passBody);
3.2 生成MtopBuilder实例
  1. MtopBuilder builder = instance.build(MtopRequest request, String ttid);
3.3 设置内容类型
  1. builder.setContentType(MtopContentType.URL_ENCODE | MtopContentType.JSON);
  • MtopContentType.URL_ENCODE(默认):默认使用方式,会对发送数据做编解码处理
  • MtopContentType.JSON:发送时对 MtopRequest 中设置的 Data 部分不作处理直接发送,此时需要设置额外参数请通过3.11中的方式添加
3.4 设置请求级别自定义域名

当 API网关 和 NativeDevops/跨平台Devops 一起使用时,NativeDevops/跨平台Devops 的业务请求也会走Mtop网络库,此时,全局域名应当设置 NativeDevops/跨平台Devops 的业务域名,而API网关使用的域名,延迟到真正请求发起时,通过 setCustomDomain() 接口设置。

  1. builder.setCustomDomain(String customDomain);
3.5 设置HTTP/HTTPS请求协议
  1. builder.protocol(ProtocolEnum protocol);
3.6 设置异步请求回调接口对象
  1. builder.addListener(MtopListener listener);

直接接入 MtopSDK 可以实现以下接口:

  • MtopFinishListener:全部数据接收完毕时响应的事件监听接口;
  • MtopHeaderListener:头部信息接收完毕时响应的事件监听接口;
  • MtopProgressListener:body数据信息接收完毕时响应的事件监听接口;
  • MtopCacheListener:offline离线缓存响应的事件监听接口;
3.7 设置请求方法类型

目前支持 GET 和 POST

  1. builder.reqMethod(MethodEnum.POST);
3.8 设置MTOP请求网络connect超时重试次数

内部默认1次

  1. builder.retryTime(int retryTime);
3.9 设置请求connect和read超时时间
  1. builder.setConnectionTimeoutMilliSecond(int connTimeout);
  2. builder.setSocketTimeoutMilliSecond(int socketTimeout);
3.10 设置自定义请求头 header信息
  1. builder.headers(Map<String, String> requestHeaders);
3.11 设置HTTP请求自定义query参数
  1. builder.addHttpQueryParameter(String key,String value);
3.12 设置请求协议版本

API网关用户请统一设置为V6实现,如果协议版本设置不正确可能出现 6.6.5的签名错误

  1. builder.setRequestProrocolVersion(MtopProtocolVersion.V6);

4. 请求发送

4.1 同步调用
  1. MtopResponse response = builder.syncRequest();
4.2 异步调用
  1. class MyListener implements MtopFinishListener {
  2. @Override
  3. public void onFinished(MtopFinishEvent event, Object context) {
  4. MtopResponse response = event.getMtopResponse();
  5. }
  6. }
  7. }
  8. // 发起异步调用请求
  9. ApiID apiId = builder.addListener(new MyListener).asyncRequest();
  10. // 取消当前异步请求
  11. apiId.cancelApiCall();
  12. // 重试本次请求
  13. apiId.retryApiCall();

5. 结果解析

解析 MTOP 响应对象 MtopResponse

  1. if (response.isApiSuccess()) {
  2. // 请求成功
  3. // 此方法已废弃,服务端下发透传消息情况下可能为空,推荐通过方式一自行判断类型后转换
  4. JSONObject jsonObject = response.getDataJsonObject();
  5. // 方式1 直接获取响应的数据,类型为String,上层根据contentType,确认body为JSON或者透传字符串
  6. String body = response.getDataBody();
  7. // 方式2 返回的是MTOP服务端输出的原始byte数据,可以new String(byte[])自己解析结构
  8. response.getBytedata()
  9. // do something business
  10. } else if(response.isSystemError() || response.isNetworkError() || response.isExpiredRequest()
  11. || response.is41XResult() || response.isApiLockedResult()||response.isMtopSdkError()){
  12. // 系统错误,网络错误,防刷,防雪崩
  13. // do something handle system error.
  14. } else {
  15. // 业务错误
  16. // do something handle api business error.
  17. }

Notice: 解析的 ByteData 数据格式基于业务返回,可能存在部分 JSONField 的值为 null 的情况,需要上层做好容错处理。

6. 错误详解

错误字段名称 Android获取方式(mtopsdk_allinone 3.0.1.4+提供) 说明
错误码retCode mtopResponse.getRetCode() 原始错误码
错误信息retMsg mtopResponse.getRetMsg() 对用户友好的系统错误提示
错误映射码mappingCode mtopResponse.getMappingCode() 错误映射码
网络请求状态码statusCode mtopResponse.getResponseCode() 网络请求状态码

对于 onSystemError 中回调的 MTOP 系统错误,业务可以通过展示 retMsg 和 mappingCode 来优化异常场景错误展示,既对用户友好,又方便定位问题

6.1 网络错误
  1. ANDROID_SYS_NETWORK_ERROR::网络错误
  2. ANDROID_SYS_NO_NETWORK::无网络

MTOPSDK 判断方法

  1. mtopResponse.isNetworkError()
6.2 MTOP Server系统错误 (retCode以“FAIL_SYS”为前缀)

MTOPSDK 判断方法

  1. mtopResponse.isMtopServerError()
6.3 MTOP SDK系统错误 (retCode以“ANDROIDSYS*”开头)

MTOPSDK 判断方法

  1. mtopResponse.isMtopSdkError()
MTOP 防刷错误和限流错误

1.MTOP请求触发服务端TMD防刷(请求频率过高或者用户被TMD判定为黑名单用户),MTOPSDK会拉起验证码页面,用户输入验证码解封

  1. 判断条件:mtopResponse.is41XResult()==true
  2. 此时MTOPSDK errcode"ANDROID_SYS_API_41X_ANTI_ATTACK"

2.MTOP请求触发服务端限流(服务端qps压力过大,sdk会在限流时间段内(默认10s)直接返回MTOP请求,不再访问服务端)

  1. 判断条件 mtopResponse.isApiLockedResult()==true
  2. 此时MTOPSDK errcode为“ANDROID_SYS_API_FLOW_LIMIT_LOCKED
6.4 业务错误BizError

网络请求成功情况下,Mtop返回json结构中ret字段retCode部分不是SUCCESS,同时retCode不是系统错误,统一判断为业务错误

  1. {
  2. "api" : "mtop.order.queryOrderDetail",
  3. "v" : "1.0",
  4. "ret" : [
  5. "ORDER_NOT_FOUND::没有相关订单信息!"
  6. ],
  7. "data" : {
  8. }
  9. }
6.5 Android MTOPSDK 内部错误说明
ERRCODE ERRMSG 错误映射码mappingCode Suffix 说明
ANDROID_SYS_NO_NETWORK 网络竟然崩溃了 EC10000 无网络,网络库返回无网络错误码
ANDROID_SYS_NETWORK_ERROR 网络竟然崩溃了 EC10001 网络错误,网络库返回statusCode小于0的错误码
ANDROID_SYS_API_FLOW_LIMIT_LOCKED 竟然被挤爆了 / 前方拥挤,亲稍等再试试 EC20000 服务端返回420限流状态码,默认后续发起该API请求在10s内都返回此错误码
ANDROID_SYS_API_41X_ANTI_ATTACK 竟然被挤爆了 / 前方拥挤,亲稍等再试试 EC20001 触发TMD防刷解封逻辑
ANDROID_SYS_JSONDATA_BLANK 服务竟然出错了 EC30000 返回JSONDATA为空 网络库返回的响应body为空
ANDROID_SYS_JSONDATA_PARSE_ERROR 服务竟然出错了 EC30001 解析JSONDATA错误 网络库返回的响应body非json格式数据,或者跟返回的json和响应pojo类不匹配
ANDROID_SYS_MTOPSDK_INIT_ERROR 服务竟然出错了 EC40000 MTOPSDK初始化失败
ANDROID_SYS_MTOPCONTEXT_INIT_ERROR 服务竟然出错了 EC40001 MTOPCONTEXT初始化错误,MTOP API请求参数错误
ANDROID_SYS_GENERATE_MTOP_SIGN_ERROR 服务竟然出错了 EC40002 生成Mtop签名sign失败
ANDROID_SYS_NETWORK_REQUEST_CONVERT_ERROR 服务竟然出错了 EC40003 网络Request转换失败
ANDROID_SYS_MTOP_APICALL_ASYNC_TIMEOUT 服务竟然出错了 EC40004 case1 发起同步请求的线程被interrupt或者cancel case2 之前的异步请求回调listener里执行了耗时任务,阻塞了当前请求回调导致超时,超时时间60秒
ANDROID_SYS_INIT_MTOP_ISIGN_ERROR 服务竟然出错了 EC40005 初始化Mtop签名类ISign失败 检查安全保镖依赖是否完整
ANDROID_SYS_MTOP_MISS_CALL_FACTORY 服务竟然出错了 EC40006 Mtop实例没有设置Call Factory
ANDROID_SYS_LOGIN_FAIL 服务竟然出错了 EC40007 登录失败
ANDROID_SYS_LOGIN_CANCEL 服务竟然出错了 EC40008 登录被取消
ANDROID_SYS_ILLEGAL_JSPARAM_ERROR 服务竟然出错了 EC40009 MTOP JSBridge 参数错误
ANDROID_SYS_PARSE_JSPARAM_ERROR 服务竟然出错了 EC40010 MTOP JSBridge 参数解析错误
ANDROID_SYS_BUILD_PROTOCOL_PARAMS_ERROR 服务竟然出错了 EC40011 组装MTOP协议参数过程中出现错误
6.6 服务端相关常见错误排查
6.6.1 FAIL_SYS_SERVICE_INNER_FAULT

服务端内部错误,请联系服务端排查

6.6.2 FAIL_SYS_UNKNOWN_APP

请检查 appkey 是否在平台注册

6.6.3 FAIL_SYS_HSF_INVOKE_ERROR/FAIL_SYS_SERVICE_FAULT

6.6.1处理

6.6.4 FAIL_SYS_SERVLET_ASYNC_TIMEOUT / FAIL_SYS_HSF_TIMEOUT

服务端请求超时,确认请求域名正确,还无法解决请联系服务端排查

6.6.5 FAIL_SYS_ILEGEL_SIGN

非法签名,mtop的请求中使用了摘要信息sign防止业务请求被篡改,请确认appkey、appsecret是否注册和设置正确,同时确定请求协议版本设置正确,具体协议版本请和服务端确认

6.6.6 FAIL_SYS_API_NOT_FOUNDED

API未发布,请确认请求的API已经在平台上注册发布

7. 混淆配置

  1. #mtop
  2. -keep class anetwork.network.cache.**{*;}
  3. -keep class com.taobao.tao.remotebusiness.**{*;}
  4. -keep class mtopsdk.**{*;}
  5. #network
  6. -keep class anet.channel.**{*;}
  7. -keep class anetwork.channel.**{*;}