大家好,给大家伙分享之前,先说两句不相干的话,从事Android开发亦有5年了,以前经常遇到问题,都会在网上查询资料,在众多前辈的指导下,解决了我很多开发遇到的问题,正是有这些前辈的分享,让我们少走了很多弯路,我在想我也遇到了很多开发问题,我为什么不可以分享,所以从今天开始,我要分享一些我遇到的一些问题和经验,包括我之前遇到的一些印象深刻的问题,我都会慢慢去找出来分享,希望大家能够支持,谢谢~
进入主题,可能大家都会遇到这样的一个问题,后台服务接口鉴权,和一些公共的参数上传,如:设备号,设备类型,appkey,appVersion,sign等等...一般来说,这些公共的参数都会放在Head上面。
拦截器的功能就不在多说了,详情看cloud.tencent.com/developer/a…
添加HEAD
这个比较简单
class MyHeadInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder()
builder.addHeader("token", "token123456").build()
builder.addHeader("device", "Android").build()
builder.addHeader("isLogin", "false").build()
return chain.proceed(builder.build())
}
}
GET
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
var request: Request = chain.request()
val url = request.url
val newUrl = url.newBuilder().apply {
addEncodedQueryParameter("add1", "我是新加的")
addEncodedQueryParameter("add2", "我也是")
}.build()
request = request.newBuilder().url(newUrl).build()
return chain.proceed(request)
}
POST
// FormBody和url不太一样,若需添加公共参数,需要新建一个构造器
FormBody.Builder bodyBuilder = new FormBody.Builder(); // 把已有的post参数添加到新的构造器
if (request.body() instanceof FormBody) {
FormBody formBody = (FormBody) request.body();
for (int i = 0; i < formBody.size(); i++) {
bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
}
}
// 这里可以添加一些公共post参数
bodyBuilder.addEncoded("key_xxx", "value_xxx");
FormBody newBody = bodyBuilder.build();
// 打印所有post参数
for (int i = 0; i < newBody.size(); i++) {
Log.d("TEST", newBody.name(i) + " " + newBody.value(i));
}
// 将最终的表单body填充到request中
requestBuilder.post(newBody);
现在get和post现在都比较清楚,如果是json呢,传的json 怎么修改呢??? 现在就遇到一个情况,一般来说sign,appkey这些都应该放在head里面,如果硬要求放在body里面怎么办呢? 比如说:
{
"orderId": "ADDSEE1AA55"
}
我这样的一个json需要变成这样的:
{
"appid":"t9Hf0frozfHdYO41",
"data": {
"orderId": "ADDSEE1AA55"
}
"sign":"安全签名",
}
别慌,我们还是一样的思路,用拦截器把拿到json,然后在对json重新包装就解决啦,那怎么拿到json呢,我们来看看:
private fun bodyToString(request: Request): String {
return try {
val copy = request.newBuilder().build()
val buffer = Buffer()
copy.body!!.writeTo(buffer)
buffer.readUtf8()
} catch (e: IOException) {
""
}
}
这样就可以拿到json数据啦 那我们来试试看吧
val oldJsonObject = JSONObject(bodyToString(request))
val newJSONObject = JSONObject().apply {
put("data",oldJsonObject)
put("sign","123456")
put("appid","123456")
}
val newBody: RequestBody = newJSONObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
request = request.newBuilder().post(newBody).build()
return chain.proceed(request)
贴一下完整的代码:
class TestInterceptor : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
var request: Request = chain.request()
when(request.method){
"GET" -> {
val url = request.url
val newUrl = url.newBuilder().apply {
addEncodedQueryParameter("add1", "我是新加的")
addEncodedQueryParameter("add2", "我也是")
}.build()
request = request.newBuilder().url(newUrl).build()
return chain.proceed(request)
}
"POST" -> {
val oldJsonObject = JSONObject(bodyToString(request))
val newJSONObject = JSONObject().apply {
put("data",oldJsonObject)
put("sign","123456")
put("appid","123456")
}
val newBody: RequestBody = newJSONObject.toString().toRequestBody("application/json".toMediaTypeOrNull())
request = request.newBuilder().post(newBody).build()
return chain.proceed(request)
}
else -> {
return chain.proceed(request)
}
}
}
private fun bodyToString(request: Request): String {
return try {
val copy = request.newBuilder().build()
val buffer = Buffer()
copy.body!!.writeTo(buffer)
buffer.readUtf8()
} catch (e: IOException) {
""
}
}
}
好了,今天的分享就到此结束啦。 有什么不对的地方,欢迎大家指导和交流。谢谢~