首页 > 系统 > Android > 正文

深入了解OkHttp3之Interceptors

2019-10-21 21:31:16
字体:
来源:转载
供稿:网友

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

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


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表