一个后台显示错误而引发的思考:如何将OkHttp的user-agent替换成默认的值

作为一款“认真的”产品,那么就要为用户的数据负责,就要足够的了解用户的行为,掌握一些可以帮助我们分析用户行为的数据。而项目的后台,就是将这些数据展示给我们的运营人员,从而给他们的工作提供数据支持

没错,其实上面的话并不是什么伟人说的,而是我随手写的。

但是,了解用户真的很重要。

所以,在我司的后台就有一些基本的用户数据,其中就包括用户使用的设备平台,型号等等。

然后,某一天负责后台的通知跟我说:“怎么最近有很多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来识别身份)。

文笔不行,得空随手记录一下

请轻喷

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,058评论 19 139
  • 一、简介 Retrofit是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于...
    Devil不加V阅读 603评论 0 0
  • Retrofit用法详解 一、简介 Retrofit是Square公司开发的一款针对Android网络请求的框架,...
    流水潺湲阅读 876评论 0 6
  • 是Square公司开发的一款针对Android网络请求的框架,Retrofit2底层基于OkHttp实现的,现在已...
    Android开发__落岑阅读 1,825评论 0 2
  • 今天Grace分享的是关于榜样,她的分享每次都能开阔我的思维,她又一次把我头脑中的榜样延展到生活中的人、事、物。...
    遁格阅读 302评论 2 0