关于OkHttp3的request和respond拦截打印Log

一、需求和问题

在开发Android项目时,一定需要和后端对接网络请求,但在因为现在都JSON格式的数据结构,在数据字段前后不一致是Android端是无法判断是是字段错误还是数据本身没有值。所有在数据还没有被Gson反序列前拦截 回应并打印body 就可以知道后端传过来的知道和值的真实情况。

这样就很清楚是Android端的问题还是后端的问题,也可以减少debug的时间。

二、依赖和配置

//retrofit2
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
//Gson
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
//Jackson
//implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
//RxJava3的适配器
implementation 'com.squareup.retrofit2:adapter-rxjava3:2.9.0'

//OkHttp3
implementation 'com.squareup.okhttp3:okhttp:4.9.3'


//Rxjava3 + RxAndroid3
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxjava:3.0.0'



// Logger 日志插件
implementation 'com.orhanobut:logger:2.2.0'

关于Okhttp3+retrofit2+Rxjava3的具体配置可以参考自学Android开发 我的Retrofit2+RxJava3的封装

三、代码示例

拦截器代码:

public class OkHttpInterceptor implements Interceptor {
private final Charset UTF8 = Charset.forName("UTF-8");

@Override
public Response intercept(Chain chain) throws IOException {
    Request request = chain.request();
    RequestBody requestBody = request.body();

    String bodyStr = "";
    if (requestBody != null) {
        Buffer buffer = new Buffer();
        requestBody.writeTo(buffer);
        Charset charset = UTF8;
        MediaType contentType = requestBody.contentType();
        if (contentType != null) {
            charset = contentType.charset(UTF8);
        }
        bodyStr = buffer.readString(charset);
    }
    String header = GsonUtil.Companion.getGson().toJson(request.headers());
    bodyStr = bodyStr == "" ? "无参数" : bodyStr;

    Response response = chain.proceed(request);
    ResponseBody responseBody = response.body();
    String bodyStrRespon = "";
    BufferedSource source = responseBody.source();
    source.request(Long.MAX_VALUE);
    Buffer buffer = source.getBuffer();

    Charset charset = UTF8;
    MediaType contentType = responseBody.contentType();
    if (contentType != null) {
        try {
            charset = contentType.charset(UTF8);
        } catch (UnsupportedCharsetException e) {
            e.printStackTrace();
        }
    }
    bodyStrRespon = buffer.clone().readString(charset);
    bodyStrRespon = bodyStrRespon == "" ? "无响应Body" : bodyStrRespon;

    String url = GsonUtil.Companion.getGson().toJson(response.request().url());
    String msg = "{\"Response\":{\"code\":" + response.code()
            + ",\"method\":\" " + request.method()+"\""
            + ",\"请求url\":" + url
            + ",\"请求头\":" + header
            + ",\"请求参数\":" + bodyStr
            + ",\"响应body\":" + bodyStrRespon
            + "}}";
    if (response.code() == 200)
        LogUtil.Companion.gsonToInfo(msg);
    else
        LogUtil.Companion.error(msg);
    return response;
}

}
LogUtil.Companion.gsonToInfo使用的是Kotlin 封装的logger 工具类,这里虽然使用的是Logger日志工具包,这个log工具包 有好处也有坏处,具体打印工具选择熟悉的。

Interceptor在这里虽然只做了拦截打印请求参数和回应数据,但是如果有前后端需要对数据进行加密时,就只需要更改这里就能完成请求加密和响应结果的解密的处理。

在一些需要对请求头有特殊要求的也可以在这里使用request().newBuilder() 新建一个request又携带旧request的数据,但你可以在这个新的request对旧的数据进行修改覆盖等,如添加请求头等操作。

注意:在打印请求和回复参数时,要注意文件上传时,不要使用这个拦截器,不然会打印文件编码符的,所以建议编写两个拦截器,上传文件时使用不打印请求体 只打印回复体参数。

你可能感兴趣的:(关于OkHttp3的request和respond拦截打印Log)