因为业务扩展,需要对接第三方公司的服务器接口,然后呢这接口对接的时候还挺好玩的,所以记录一下。
根据对方的接口文档:所有接口返回都是统一 MsgCode + Msg + 其他 的形式。然后登录后Token的有效时间为10分钟,但是从业务流程来看这10分钟啥也干不了😊
行吧,反正用的是OKHttp,写个拦截器呗......
然后实现和一般的Token拦截差不多,只是Token并不是放在header,需要放在请求体中。
1.第一次请求后获取返回数据,判断MsgCode状态码
2.当判断为Token失效的时候,同步请求登录接口获取新的Token
3.更换请求参数中的Token,再次请求数据接口
思路就是这样的,先上代码再吐槽......
class TokenInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request: Request = chain.request()
val originalResponse: Response = chain.proceed(request)
val responseBody: ResponseBody? = originalResponse.body()
val source: BufferedSource? = responseBody?.source()
source?.request(Long.MAX_VALUE)
val buffer: Buffer? = source?.buffer()
val contentType: MediaType? = responseBody?.contentType()
val charset = contentType?.charset(Charsets.UTF_8)
val bodyString: String = buffer?.clone()?.readString(charset) ?: "{}"
Log.d("onResponse", bodyString)
Log.d("onResponse", "----------------------------------")
val jsonObject = JSONObject(bodyString)
// token 过期
if ((jsonObject.has("MsgCode") && ("00002" == jsonObject.getString("MsgCode")))) {
val map = HashMap<String, Any>()
map["UserID"] = Constant.USER_NAME
map["PassWord"] = Constant.ACCOUNT_PASSWORD
val service: Apis = HttpClient.create(Apis::class.java)
val call: Call<TokenBean> = service.getToken(Gson().toJson(map))
// 同步获取新token,再次请求接口
val resultBean: TokenBean? = call.execute().body()
Log.d("onResponse", "new Token --- ${resultBean!!.userToken}")
SPUtils.putString(Constant.USER_TOKEN, resultBean.userToken)
// 获取请求参数,更换token
val body = request.body()
val buffer = Buffer()
body?.writeTo(buffer)
var parameterStr = buffer.readUtf8()
Log.d("111", "请求参数---$parameterStr")
parameterStr = URLDecoder.decode(parameterStr, "UTF-8")
Log.d("111", "解析后的请求参数---${parameterStr.substring(1)}")
val jsonObject = JSONObject(parameterStr.substring(1))
val newMap = HashMap<String, Any>()
val iterator = jsonObject.keys()
while (iterator.hasNext()) {
val key = iterator.next()
if ("Token" == key) {
newMap[key] = resultBean.userToken
} else {
newMap[key] = jsonObject.getString(key)
}
}
Log.d("111", "新的请求参数" + Gson().toJson(newMap))
val requestBody =
RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), "=${Gson().toJson(newMap)}")
val newRequest: Request = request.newBuilder().post(requestBody).build()
originalResponse.body()?.close()
return chain.proceed(newRequest)
}
return originalResponse
}
}
- 请求的表单数据编码Content-Type 指定为 application/x-www-form-urlencoded,这完全不是问题撒,可是我就是怎么提交都不行!为什么!!关键还不好意思去问,不然别人觉得我连提交个表单数据都不会,还是要点面子的:)然后各种测试,终于通了:)表单里键值对就一个,key是空字符串,然后所有的参数是json字符串放在value中:)nice啊老哥,这种特殊的点就不能交代一哈吗:)
- 按照文档写的去请求数据,居然给我返回消息缺少必要参数 :)
- 接口返回的数据居然不是按照接口文档写的那样?!wo diu 这么随意的吗?
网友评论