Android Mtop网关接入文档
1. 依赖
在当前工程的 build.gradle 文件中添加依赖
compile('com.taobao.android:mtopsdk_allinone:3.0.9.1-open@jar')
2. 初始化
2.1 设置加签实现
根据 appKey、appSecret设置加签实现。
MtopSetting.setISignImpl(Mtop.Id.INNER,newLocalInnerSignImpl(mAppkey,mAppSecret));
2.2 设置appVersion
初始化mtopsdk前设置应用APP的版本appVersion。
MtopSetting.setAppVersion(Mtop.Id.INNER,appVersion)
2.3 设置全局域名
统一设置线上、预发、日常的域名,一般来说,这3个域名完全一致。
注意:当 API网关 和 NativeDevops/跨平台Devops 一起使用时,NativeDevops/跨平台Devops 的业务请求也会走Mtop网络库,此时,这个全局域名应当设置 NativeDevops/跨平台Devops 的业务域名,而API网关使用的域名,延迟到真正请求发起时,通过 setCustomDomain() 接口设置。
MtopSetting.setMtopDomain(Mtop.Id.INNER,onlineDomain,preDomain,dailyDomain);
2.4 初始化实例
MTOP 初始化放在应用 Application 的 onCreate() 方法中
渠道 ttid 可以在初始化时设置,或者在生成实例后设置。
MtopmtopInstance=Mtop.instance(Mtop.Id.INNER,mApplication.getApplicationContext(),"");
mtopInstance.registerTtid(mTTid);
2.5 环境切换
外部版本一律切换为日常环境。
// 设置日常环境
mtopInstance.switchEnvMode(EnvModeEnum.TEST);
2.6 初始化示例privatevoidinitMtop(){
// 调试日志开关,接入时可以打开调试
TBSdkLog.setTLogEnabled(false);
// 关闭SSL
if(mUseHttp){
NetworkConfigCenter.setSSLEnabled(false);
}
// [option]关闭MTOP请求长链,调用后Mtop请求直接调用NetworkSDK的HttpNetwork发请求
SwitchConfig.getInstance().setGlobalSpdySwitchOpen(false);
// 关闭MTOPSDK NewDeviceID逻辑
MtopSetting.setEnableProperty(Mtop.Id.INNER,MtopEnablePropertyType.ENABLE_NEW_DEVICE_ID,false);
// 设置自定义全局访问域名
MtopSetting.setMtopDomain(Mtop.Id.INNER,mMtopHost,mMtopHost,mMtopHost);
// 设置自定义签名使用的appKey和appSecret
MtopSetting.setISignImpl(Mtop.Id.INNER,newLocalInnerSignImpl(mAppkey,mAppSecret));
MtopSetting.setAppVersion(Mtop.Id.INNER,BuildConfig.VERSION_NAME);
MtopmtopInstance=Mtop.instance(Mtop.Id.INNER,mApplication.getApplicationContext(),"");
mtopInstance.switchEnvMode(EnvModeEnum.TEST);
mtopInstance.registerTtid(mTTid);
}
3. 请求构建
3.1 生成MtopRequest实例MtopRequestrequest=newMtopRequest();
request.setApiName(StringapiName);// API接口名称
request.setVersion(StringapiVersion);// API接口版本
// 非透传时:API接口输入参数,接收入参Map,调用工具方法ConvertMapToDataStr拼接data字符串
request.setData(ReflectUtil.convertMapToDataStr(MapApiParamsMap));
// 透传时:直接设置需要透传的字符串
request.setData(StringpassBody);
3.2 生成MtopBuilder实例MtopBuilderbuilder=instance.build(MtopRequestrequest,Stringttid);
3.3 设置内容类型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() 接口设置。
builder.setCustomDomain(StringcustomDomain);
3.5 设置HTTP/HTTPS请求协议builder.protocol(ProtocolEnumprotocol);
3.6 设置异步请求回调接口对象builder.addListener(MtopListenerlistener);
直接接入 MtopSDK 可以实现以下接口:
MtopFinishListener:全部数据接收完毕时响应的事件监听接口;
MtopHeaderListener:头部信息接收完毕时响应的事件监听接口;
MtopProgressListener:body数据信息接收完毕时响应的事件监听接口;
MtopCacheListener:offline离线缓存响应的事件监听接口;
3.7 设置请求方法类型
目前支持 GET 和 POST
builder.reqMethod(MethodEnum.POST);
3.8 设置MTOP请求网络connect超时重试次数
内部默认1次
builder.retryTime(intretryTime);
3.9 设置请求connect和read超时时间builder.setConnectionTimeoutMilliSecond(intconnTimeout);
builder.setSocketTimeoutMilliSecond(intsocketTimeout);
3.10 设置自定义请求头 header信息builder.headers(MaprequestHeaders);
3.11 设置HTTP请求自定义query参数builder.addHttpQueryParameter(Stringkey,Stringvalue);
3.12 设置请求协议版本
API网关用户请统一设置为V6实现,如果协议版本设置不正确可能出现 6.6.5的签名错误
builder.setRequestProrocolVersion(MtopProtocolVersion.V6);
4. 请求发送
4.1 同步调用MtopResponseresponse=builder.syncRequest();
4.2 异步调用classMyListenerimplementsMtopFinishListener{
@Override
publicvoidonFinished(MtopFinishEventevent,Objectcontext){
MtopResponseresponse=event.getMtopResponse();
}
}
}
// 发起异步调用请求
ApiIDapiId=builder.addListener(newMyListener).asyncRequest();
// 取消当前异步请求
apiId.cancelApiCall();
// 重试本次请求
apiId.retryApiCall();
5. 结果解析
解析 MTOP 响应对象 MtopResponse
if(response.isApiSuccess()){
// 请求成功
// 此方法已废弃,服务端下发透传消息情况下可能为空,推荐通过方式一自行判断类型后转换
JSONObjectjsonObject=response.getDataJsonObject();
// 方式1 直接获取响应的数据,类型为String,上层根据contentType,确认body为JSON或者透传字符串
Stringbody=response.getDataBody();
// 方式2 返回的是MTOP服务端输出的原始byte数据,可以new String(byte[])自己解析结构
response.getBytedata()
// do something business
}elseif(response.isSystemError()||response.isNetworkError()||response.isExpiredRequest()
||response.is41XResult()||response.isApiLockedResult()||response.isMtopSdkError()){
// 系统错误,网络错误,防刷,防雪崩
// do something handle system error.
}else{
// 业务错误
// do something handle api business error.
}
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 网络错误ANDROID_SYS_NETWORK_ERROR::网络错误
ANDROID_SYS_NO_NETWORK::无网络
MTOPSDK 判断方法
mtopResponse.isNetworkError()
6.2 MTOP Server系统错误 (retCode以“FAIL_SYS”为前缀)
MTOPSDK 判断方法
mtopResponse.isMtopServerError()
6.3 MTOP SDK系统错误 (retCode以“ANDROIDSYS*”开头)
MTOPSDK 判断方法
mtopResponse.isMtopSdkError()
MTOP 防刷错误和限流错误
1.MTOP请求触发服务端TMD防刷(请求频率过高或者用户被TMD判定为黑名单用户),MTOPSDK会拉起验证码页面,用户输入验证码解封
判断条件:mtopResponse.is41XResult()==true
此时MTOPSDK errcode为"ANDROID_SYS_API_41X_ANTI_ATTACK"
2.MTOP请求触发服务端限流(服务端qps压力过大,sdk会在限流时间段内(默认10s)直接返回MTOP请求,不再访问服务端)
判断条件mtopResponse.isApiLockedResult()==true
此时MTOPSDK errcode为“ANDROID_SYS_API_FLOW_LIMIT_LOCKED”
6.4 业务错误BizError
网络请求成功情况下,Mtop返回json结构中ret字段retCode部分不是SUCCESS,同时retCode不是系统错误,统一判断为业务错误
{
"api":"mtop.order.queryOrderDetail",
"v":"1.0",
"ret":[
"ORDER_NOT_FOUND::没有相关订单信息!"
],
"data":{
}
}
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. 混淆配置#mtop
-keepclassanetwork.network.cache.**{*;}
-keepclasscom.taobao.tao.remotebusiness.**{*;}
-keepclassmtopsdk.**{*;}
#network
-keepclassanet.channel.**{*;}
-keepclassanetwork.channel.**{*;}