作为一款“认真的”产品,那么就要为用户的数据负责,就要足够的了解用户的行为,掌握一些可以帮助我们分析用户行为的数据。而项目的后台,就是将这些数据展示给我们的运营人员,从而给他们的工作提供数据支持
没错,其实上面的话并不是什么伟人说的,而是我随手写的。
但是,了解用户真的很重要。
所以,在我司的后台就有一些基本的用户数据,其中就包括用户使用的设备平台,型号等等。
然后,某一天负责后台的通知跟我说:“怎么最近有很多desktop的用户,而且使用的OS还是无法识别的?”
这的确是个奇怪的现象,但是奇怪归奇怪,问题还是要解决的。我问了一些后台的同志,是怎么识别设备平台的,答曰:根据用户请求中的header中的user-agent来识别的。
解决问题前:确定为什么会出问题
研究一下出问题的user的请求数据
发现原来真的是Android设备的锅了
其中user-agent是okhttp,这个就是前阵子才换上的一个网络请求库(这个真的好用)。
那么问题就明显了:因为我前阵子自己封装了Okhttp+retrofit+rxjava,所以自那之后所以经过OkHttp的请求中的user-agent就被修改成Okhttp自己的标志了。然后人家后台的同志都不认识你,所以就给标上了Other OS。。。
对于解决方案的思考
既然已经发现了问题所在,那么自然就要想办法解决问题了。解决问题的核心无外乎就是对症下药
方法一:
让后台的同志认识一下okhttp,以后只要遇到okhttp就不管三七二十一,直接当做Android OS来对付就行了。
后台的同志就有意见了:明明是你的锅,为何我来背?
好吧,好像很有道理。
方法二:
那就换回原生的网络请求库咯!what???这简直就有点zz了,先不说现在okhttp的优越性,单单换回去也是要成本的,更何况当初集成okhttp+retrofit+rxjava都已经花了一些时间了。
那么这个方法也pass!
方法三:
那既然是okhttp请求的user-agent的问题,那就换掉它的user-agent咯!
bingo,这才是正解!!!
接下来就开始正文了,如何替换okhttp中的user-agent?
让我们撸起袖子开始干吧
问题找到了,解决方案也敲定了,那么就可以开始开工了。
first
要替换okhttp请求的user-agent,就要先拦截okhttp的请求,在请求真正发出去之前我们先给它弄一下
根据okhttp的文档,我们知道在创建Okhtpp client时是可以添加一个拦截器的:
okHttpClientBuilder.addNetworkInterceptor();
因此我们就可以在请求前先拿到request了,如下
okHttpClientBuilder.addNetworkInterceptor(new Interceptor() {
@Override
public Responseintercept(Chain chain)throws IOException {
Request original = chain.request();
Request.Builder builder = original.newBuilder();
//在此修改就可以开始修改user_agent
builder.method(original.method(), original.body());
Request request = builder.build();
return chain.proceed(request);
}
});
second
拿到request的build之后,就可以准备动个小手术了
//修改成默认的user_agent
builder.removeHeader("User-Agent").addHeader("User-Agent", getUserAgent()).build();
third
你可能会问getUserAgent()是什么鬼?
其实这只是一个获取Android默认user-agent的函数罢了,如下
private static StringgetUserAgent() {
String userAgent ="";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
try {
userAgent = WebSettings.getDefaultUserAgent(TalkpalApplication.getContext());
}catch (Exception e) {
userAgent = System.getProperty("http.agent");
}
}else {
userAgent = System.getProperty("http.agent");
}
StringBuffer sb =new StringBuffer();
for (int i =0, length = userAgent.length(); i < length; i++) {
char c = userAgent.charAt(i);
if (c <='\u001f' || c >='\u007f') {
sb.append(String.format("\\u%04x", (int) c));
}else {
sb.append(c);
}
}
return sb.toString();
}
last
打包、编译、测试之后
终于是正常了!
结束语
其实在日常的开发过程中,最好的学习方法就是上手去做。
这只是一个小小的例子,通过研究一个小小的bug,我们更加的了解了okhttp,甚至举一反三,在日后要对请求做身份识别之类的限制,也都可以很快的运用上(例如每个用户都要有自己的token,请求时要在header中加上token来识别身份)。
文笔不行,得空随手记录一下
请轻喷