Retrofit/okhttp はリクエスト パラメータ (get、post リクエストを含む) をどのようにインターセプトしますか?

なぜリクエストパラメータをインターセプトするのでしょうか?
Retrofit は、最も人気のあるネットワーク リクエスト ライブラリとして、弊社でもよく使用されています。これを使用する場合、リクエスト パラメーターをインターセプトして署名計算を実行し、統一ヘッダーを設定するなど、リクエスト パラメーターをインターセプトして統一処理を行う必要がある場合があります。この状況にどう対処すればよいでしょうか? もちろん、カスタム インターセプターを使用するのが最善です。

ただし、インターセプトするときは、get リクエストと post リクエストを区別する必要があります。投稿リクエストにはさまざまなリクエスト方法があります。

1. Retrofit が取得リクエストを行う

    @GET("message/getUnReadMessageList")
    fun getUnReadMessageList(@Query("userId") userId: String): Observable<BaseResponse<ArrayList<MsgInfoBean>>>

パラメータを結合する場合。
userId=xxxなど

2. Retrofit は JSON データを送信するためのポストリクエストを作成します

    @POST("user/ticket")
    fun login1(
        @Body body: RequestBody,
    ): Observable<BaseResponse<UserInfo>>

    @POST("user/ticket")
    fun login2(
        @Body body: User,
    ): Observable<BaseResponse<UserInfo>>

どちらのリクエストも次のデータ形式をサーバーに送信します:
{“username”: “xxx”, “password”: “xxx”}

3. Retrofit はフォーム データを送信するためのポスト リクエストを作成します

    @FormUrlEncoded
    @POST("user/ticket")
    fun login3(@Field("username") user: String, @Field("password") password: String) : Observable<BaseResponse<UserInfo>>

この種類のリクエストは、次のデータ形式をサーバーに送信します:
username=xxx&password=xxx
4. インターセプタでリクエスト パラメータを取得する方法は
すべてコード内にあります。

public class HeaderInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Request.Builder requestBuilder = request.newBuilder();
        //requestBuilder.addHeader("Content-Type", "application/json");
        requestBuilder.addHeader("X-Co-Sign", signFn(request));
        
        request = requestBuilder.build();
        return chain.proceed(request);
    }

    /**
     * 拦截请求参数并签名
     */
    private String signFn(Request request) {
        String signStr;
        String type = request.method();
        
        if (type.equals("GET") && request.url().encodedQuery() != null) {//获取get请求的参数
            String encodedQuery = request.url().encodedQuery();
            String[] querys = encodedQuery.split("&");
            Map<String, String> queryMap = new HashMap<>();
            for (String query : querys) {
                String[] split = query.split("=");
                queryMap.put(split[0], split[1]);
            }
            //获取get请求参数后可进行排序
            List<Map.Entry<String, String>> entryList = new ArrayList<>(queryMap.entrySet());
            Collections.sort(entryList, new Comparator<Map.Entry<String, String>>() {
                @Override
                public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                    return o1.getKey().compareTo(o2.getKey());
                }
            });
            /*省略签名计算*/
        } else if (type.equals("POST")) {//获取POST请求的参数
            String paramsStr = bodyToString(request);
            /*省略签名计算*/
        }
        return signStr;
    }

    /**
     * post 请求参数获取
     */
    private String bodyToString(final Request request) {
        final Request copy = request.newBuilder().build();
        final Buffer buffer = new Buffer();
        try {
            copy.body().writeTo(buffer);
        } catch (IOException e) {
            return "something error,when show requestBody";
        }
        return buffer.readUtf8();
    }
    
    /**
     * post 表单请求参数也可以这样获取
     */
    private HashMap<String, String> bodyToString(final Request request) {
        HashMap<String, String> map = new HashMap<>();
        if (request.body() instanceof FormBody) {
            FormBody body = (FormBody) request.body();
            for (int i = 0; i < body.size(); i++) {
                map.put(body.encodedName(i), body.encodedValue(i));
            }
        }
        return map;
    }
}

5.使用する

		OkHttpClient.Builder builder= new OkHttpClient.Builder();
		...
		builder.addInterceptor(new HeaderInterceptor())
		...

おすすめ

転載: blog.csdn.net/qq_36162336/article/details/126171307