当前位置: 移动技术网 > 移动技术>移动开发>Android > 深入了解OkHttp3之Interceptors

深入了解OkHttp3之Interceptors

2019年07月30日  | 移动技术网移动技术  | 我要评论

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,谢谢。 代码实例

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网