自学Android开发 关于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对旧的数据进行修改覆盖等,如添加请求头等操作。

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

​​​​​​​

如果对您有一些意义,希望您给博主一些鼓励(点赞、关注、收藏),如果有错误欢迎大家评论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值