How does retrofit/okhttp intercept request parameters (including get, post requests)

Why intercept request parameters?
As the most popular network request library, retrofit is often used by us. When using it, sometimes we need to intercept the request parameters and do some unified processing, such as intercepting the request parameters and performing signature calculation, and then setting a unified header. How to deal with this situation? Of course it is best to use a custom interceptor!

But when we intercept, we need to distinguish between get requests and post requests. There are different request methods for post requests.

1. Retrofit makes a get request

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

If splicing parameters. Such as
userId=xxx

2. Retrofit makes a post request to send json data

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

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

Both requests will send the following data format to the server:
{“username”: “xxx”, “password”: “xxx”}

3. Retrofit makes a post request to send form data

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

This kind of request will send the following data format to the server:
username=xxx&password=xxx
4. How to get the request parameters in the interceptor
is all in the code:

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. use

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

Guess you like

Origin blog.csdn.net/qq_36162336/article/details/126171307
Recommended