Retrofit2自定义的日志拦截器interceptor

  • 通过Retrofit2 拦截器获取到请求参数和响应内容
  • 兼容了POST和GET请求
  • 返回值以JSON格式展示

1、Retrofit2中使用自定义的日志拦截器:

@Override
public void okHttpClient(OkHttpClient.Builder okHttpClient) {
    okHttpClient.connectTimeout(5000, TimeUnit.MILLISECONDS)
            .writeTimeout(60000, TimeUnit.MILLISECONDS)
            .readTimeout(60000, TimeUnit.MILLISECONDS)
            .addInterceptor(chain -> {
                Request.Builder builder = chain.request().newBuilder();
                AccountBean bean = MainApplication.getInstance().getAccountBean();
                builder.addHeader("user_id", bean.getUserCardNum());//身份证号码

                return chain.proceed(builder.build());
            });

    okHttpClient.addInterceptor(new HttpLogReportInterceptor());//统一日志拦截器
}

2、HttpLogReportInterceptor.java 源码:


import android.net.Uri;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;

import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okio.Buffer;
import okio.BufferedSource;

public class HttpLogReportInterceptor implements Interceptor {
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        int httpCode = response.code();//获取响应码
        String url = request.url().toString();
        String requestParam = "";

        switch (request.method().toLowerCase()) {
            case "post":
                requestParam = getRequestParams4Post(request);//请求参数
                break;
            case "get":
                requestParam = getRequestParams4Get(request.url().toString());
                break;
        }

        String jsonStr = getResponseContent(response);
        int code = -1;//业务逻辑的code

        // 1、接口调用成功(有响应)
        // 2、业务逻辑执行完成
        try {
            HttpBaseResult baseResult = new Gson().fromJson(jsonStr, HttpBaseResult.class);
            code = baseResult.getStatus();
//            LegoLog.d("业务逻辑 Code:" + code);
        } catch (Exception e) {
            LegoLog.w(e.getMessage());
        }
        if (httpCode == 200 && (code == 200)) {
            // 1、接口调用成功(有响应)
            // 2、业务逻辑执行完成

        } else {
            LegoLog.d("Http Code:" + httpCode + ";;业务code:" + code);
        }

        return response;
    }

    private String getRequestParams4Get(String url) {
        Uri uri = Uri.parse(url);
        JsonObject requestJson = new JsonObject();
        for (String paramKey : uri.getQueryParameterNames()) {
            String paramValue = uri.getQueryParameter(paramKey);
            requestJson.addProperty(paramKey, paramValue);
        }
        return requestJson.toString();
    }
    
    /**
     * 获取POST请求参数
     */
    private String getRequestParams4Post(Request request) throws IOException {
        if (request.body() != null && HttpContentTypeUtil.isParseable(request.body().contentType())) {
            return parseRequestParams4Post(request);
        }
        // 说明:multipart/form-data 需要特殊处理
        return "";
    }

    /**
     * 解析请求服务器的请求参数
     */
    private static String parseRequestParams4Post(Request request) throws UnsupportedEncodingException {
        try {
            RequestBody body = request.body();
            if (body == null) return "";
            Buffer requestBuffer = new Buffer();
            body.writeTo(requestBuffer);
            Charset charset = StandardCharsets.UTF_8;
            MediaType contentType = body.contentType();

            if (contentType != null) {
                charset = contentType.charset(charset);
            }
            String text = requestBuffer.readString(charset);

            if (contentType != null && !"json".equals(contentType.subtype())) {
                text = URLDecoder.decode(text, convertCharset(charset));
            }

            return TextUtil.jsonFormat(text);
        } catch (IOException e) {
            e.printStackTrace();
            return "{\"error\": \"" + e.getMessage() + "\"}";
        }
    }

    private static String convertCharset(Charset charset) {
        String s = charset.toString();
        int i = s.indexOf("[");
        if (i == -1)
            return s;
        return s.substring(i + 1, s.length() - 1);
    }
    
    /**
     * 获取返回值内容
     *
     * @param response
     * @return
     */
    private String getResponseContent(Response response) {
        try {
            //读取服务器返回的结果
//            ResponseBody responseBody = response.newBuilder().build().body();
            ResponseBody responseBody = response.body();
            BufferedSource source = responseBody.source();
            source.request(Long.MAX_VALUE); // Buffer the entire body.
            Buffer buffer = source.buffer();

            //获取content的压缩类型
            String encoding = response.headers().get("Content-Encoding");
            //克隆服务器的响应内容()
            Buffer cloneBuffer = buffer.clone();

            //解析response content
            return parseResponseContent(responseBody.contentType(), encoding, cloneBuffer);
        } catch (IOException e) {
            LegoLog.w(e.getMessage());
            return "{\"error\": \"" + e.getMessage() + "\"}";
        }
    }

    /**
     * 解析服务器响应的内容
     *
     * @param contentType
     * @param encoding    编码类型
     * @param cloneBuffer 克隆后的服务器响应内容
     * @return 解析后的响应结果
     */
    private String parseResponseContent(MediaType contentType, String encoding, Buffer cloneBuffer) {
        Charset charset = StandardCharsets.UTF_8;
        if (contentType != null) {
            charset = contentType.charset(charset);
        }
        if (encoding != null && encoding.equalsIgnoreCase("gzip")) {//content使用gzip压缩
            return ZipUtil.decompressForGzip(cloneBuffer.readByteArray(), convertCharset(charset));//解压
        } else if (encoding != null && encoding.equalsIgnoreCase("zlib")) {//content使用zlib压缩
            return ZipUtil.decompressToStringForZlib(cloneBuffer.readByteArray(), convertCharset(charset));//解压
        } else {//content没有被压缩
            return cloneBuffer.readString(charset);
        }
    }
}

HttpBaseResult.java


public class HttpBaseResult<T> {
    private int code;
    private String msg;
    private T data;
	
	//...get/set
}

特别说明:

ResponseBody body = response.body();//获取响应体
// 由于ResponseBody内的bytes()、string()方法调用了closeQuietly方法,此方法会将ResponseBody内的数据源清除,所以仅获取一次内容。
byte[] bytes = body.bytes();//获取字节数组

由于ResponseBody内的 bytes()、string()方法调用了== Util.closeQuietly(source);==,此方法会将ResponseBody内的数据源清除,所以仅获取一次内容。

OkHttp请求回调中response.body().string()只能有效调用一次

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 你可以使用OkHttp的Interceptor拦截参数。在使用Retrofit时,可以通过自定义OkHttpClient并添加Interceptor来实现。以下是一个示例: ``` OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request originalRequest = chain.request(); Request requestWithNewParameter = originalRequest.newBuilder() .addHeader("Your-Header-Name", "Your-Header-Value") .build(); return chain.proceed(requestWithNewParameter); } }) .build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create()) .build(); YourApiService apiService = retrofit.create(YourApiService.class); ``` 在上面的示例中,我们添加了一个Interceptor拦截每个请求并添加一个自定义的Header。你可以根据需要修改拦截的实现来拦截并修改请求参数。 ### 回答2: 在Android开发中,Retrofit是一个非常流行的网络请求库。它提供了拦截Interceptor)的功能,可以对网络请求的参数进行拦截和修改。 拦截是一个接口,可以在请求之前或者响应之后对请求进行处理。在Retrofit中,可以通过实现Interceptor接口来自定义拦截。 通过拦截,我们可以对请求进行一些通用的处理,比如对请求头进行添加、修改、删除等操作。我们可以在拦截的intercept方法中获取到请求的参数,然后根据需求进行修改。 拦截可以被添加到OkHttpClient的拦截链中,通过addInterceptor()方法来添加。当发起网络请求时,拦截会按照添加的顺序进行拦截。这样,我们就可以在请求中添加或修改参数。 拦截还可以对响应进行处理,比如对返回的数据进行解析、转换等操作。拦截可以获取到响应的数据,然后可以对数据进行一些处理,并返回给调用方。 通过使用拦截,我们可以在不修改原有的网络请求代码的情况下,对请求和响应进行一些通用的处理。这样可以提高开发的效率,并且可以保持代码的整洁和可维护性。 总的来说,Android Retrofit拦截功能非常强大,可以非常方便地对网络请求的参数进行拦截和修改,提供了非常灵活的扩展性。 ### 回答3: 在Android中,Retrofit是一个广泛使用的网络请求库,用于方便地从服务获取数据。拦截参数是指在使用Retrofit发送网络请求之前,可以通过拦截对请求的参数进行修改或添加一些额外的信息。 在Retrofit中,可以通过自定义拦截来实现对参数的拦截操作。拦截是一个接口,它提供了两个方法:intercept和proceed。 intercept方法用于处理拦截逻辑,我们可以在这个方法中获取到请求的参数信息,并对其进行修改或添加额外信息。可以使用request.body()方法获取请求体,再通过request.newBuilder()方法创建一个新的请求,最后通过chain.proceed()方法继续请求的发送。 proceed方法表示继续发送原始请求,如果不调用该方法,请求将会被拦截,不会发送到服务。 要使用拦截,首先需要创建一个OkHttpClient对象,并通过addInterceptor方法将拦截添加到OkHttpClient中。然后将创建的OkHttpClient对象传递给Retrofit.Builder的client方法。 以下是一个示例代码,演示如何使用拦截对请求参数进行拦截: ``` OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.addInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Request request = chain.request(); // 获取原始请求的参数 HttpUrl url = request.url().newBuilder() .addQueryParameter("key", "value") .build(); Request newRequest = request.newBuilder() .url(url) .build(); return chain.proceed(newRequest); } }); OkHttpClient client = builder.build(); Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://example.com/") .client(client) .build(); ``` 上述代码创建了一个OkHttpClient对象,并添加了一个拦截。在拦截的intercept方法中,获取了原始请求的参数,然后对其进行了修改(添加了一个名为key值为value的参数),最后调用chain.proceed方法继续发送请求。 通过拦截,我们可以对请求的参数进行灵活处理,例如对请求进行签名、添加公共参数等操作,提高了开发的灵活性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值