深入了解OkHttp3之Interceptors
okhttp官网上面介绍:拦截器是一种强大的机制,可以监视,重写和重试调用。这里我们主要对拦截器的网络请求头和数据请求的封装。
网络请求头拦截器
在android应用中,我们通常需要获取用户手机的imei值和其他一些常用的参数,如果把他们封装到请求头里面的话会非常的方便。
既然是自定义拦截器,我们首先肯定要继承okhttp的拦截器,把这个自定义类设置成 final 类型的防止其他类继承。
这里需要在父类的intercept(chain chain)方法中进行操作。在方法里面得request.builder对象然后添加请求头。
创建一个baseparam 对象,对请求头的参数进行封装。
public final class headerinterceptortest implements interceptor { /** * 请求头参数基础参数 */ private static final string header_base_param = "baseparam"; private static string base_param; @override public response intercept(chain chain) throws ioexception { request.builder builder = chain.request().newbuilder(); builder.addheader(header_base_param, base_param); return chain.proceed(builder.build()); } public static void initbaseparam(context context) { baseparam baseparam = new baseparam(); string imei; string imsi; try { imei = deviceinfoutil.getimei(context); } catch (exception e) { imei = null; } if (null == imei || imei.equals("")) { imei = deviceinfoutil.getdeviceid(context); imsi = deviceinfoutil.getdeviceid(context); } else { imei = deviceinfoutil.getimei(context); imsi = deviceinfoutil.getimsi(context); } baseparam.setimei(imei); baseparam.setimsi(imsi); baseparam.setmac(deviceinfoutil.getwifimac(context)); baseparam.setversion(deviceinfoutil.getversion(context)); baseparam.setmodel(deviceinfoutil.getmodel()); baseparam.setbrand(deviceinfoutil.getbrand()); base_param = new gson().tojson(baseparam).tostring(); } private static class baseparam { /** * imei : * imsi : * mac : * version : * model : * brand : * city : */ private string imei; private string imsi; private string mac; private string version; private string model; private string brand; private string city; public string getimei() { return imei; } public void setimei(string imei) { this.imei = imei; } public string getimsi() { return imsi; } public void setimsi(string imsi) { this.imsi = imsi; } public string getmac() { return mac; } public void setmac(string mac) { this.mac = mac; } public string getversion() { return version; } public void setversion(string version) { this.version = version; } public string getmodel() { return model; } public void setmodel(string model) { this.model = model; } public string getbrand() { return brand; } public void setbrand(string brand) { this.brand = brand; } public string getcity() { return city; } public void setcity(string city) { this.city = city; } } }
数据请求拦截器
在进行数据请求的时候,一般都会定义一种固定的请求格式。在这里我们直接通过拦截器,将这个固定的格式定义好,这样使用起来可以统一管理。具体的使用方法其实和上面一样。
主要注意的是先得到,请求时设置的请求体,然后让请求的数据封装到和后端设置的请求格式里面。
public class httpdatapackinterceptortest implements interceptor { @override public response intercept(chain chain) throws ioexception { request request = chain.request(); request.builder requestbuilder = chain.request().newbuilder(); //请求数据处理 if (request.url().tostring().contains("uploads")) { //特殊接口的参数不需要处理的 } else { //需要处理请求参数的 if (request.body() instanceof formbody) { formbody.builder newformbody = new formbody.builder(); //得到请求时设置的请求体 formbody oldformbody = (formbody) request.body(); buffer buffer = new buffer(); oldformbody.writeto(buffer); string postparams = jsonutils.getjsonstrfrompostparams(buffer.readstring(charset.forname("utf-8"))); string data = urldecoder.decode(postparams, "utf-8"); if (textutils.isempty(data)) { newformbody.add("data", ""); } else { //将请求的数据封装 newformbody.add("data", data); } requestbuilder.method(request.method(), newformbody.build()); } } return chain.proceed(requestbuilder.build()); } }
代码中调用
在创建okhttpclient 对象的时候,调用 addinterceptor()方法 添加俩个拦截器。
private okhttpclient client; @override protected void oncreate(@nullable bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_okhttp); headerinterceptortest.initbaseparam(this); client= new okhttpclient() .newbuilder() .addinterceptor(new headerinterceptortest()) .addinterceptor(new httpdatapackinterceptortest()) .connecttimeout(60, timeunit.seconds) .writetimeout(60, timeunit.seconds) .readtimeout(60, timeunit.seconds).build(); okhttpasyncpost(); } private void okhttpasyncpost(){ requestbody formbody = new formbody.builder() .add("page", "1") .add("count", "2") .add("type","video") .build(); request request = new request.builder() .url("https://api.apiopen.top/getjoke") .post(formbody) .build(); client.newcall(request).enqueue(new callback() { @override public void onfailure(call call, ioexception e) { } @override public void onresponse(call call, response response) throws ioexception { log.e("error","结果"+response.body().string()); log.e("error","方法"+response.request().tostring()); log.e("error","请求头"+response.request().headers().tostring()); } }); }
打印的日志
结果{"status":200,"msg":"ok","data":"{\"count\":\"2\",\"page\":\"1\",\"type\":\"video\"}"}
方法request{method=post, url=https://www.26uuun.com/list, tags={}}
请求头baseparam: {"brand":"xiaomi","city":"\u4e1c\u4eac","imei":"9fc70b16bf169075f556e6d67be9ef1a","imsi":"9fc70b16bf169075f556e6d67be9ef1a","mac":"02:00:00:00:00:00","model":"mi note 2","version":"1.0"}
ok,okhttp3中interceptors配置完成,小伙伴们,可以设置自己不同需求的其他的拦截器添加到请求中。
最近我会写很多关于android常用控件的使用,里面都是一些很有用的知识,如果你感觉有用,请给我一个star,谢谢。 代码实例
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Android实现横向滑动卡片效果