retrofit/okhttp如何拦截请求参数(包含get,post请求)

为什么要进行拦截请求参数?
retrofit作为最火的网络请求库,我们经常会用到它。在使用它时有时我们需要对请求参数进行拦截做一些统一的处理,如对请求参数进行拦截并进行签名计算,然后设置统一的header。这种情形怎么进行处理呢?当然最好是使用自定义拦截器了!

但是我们在拦截时,又需要区分get请求和post请求。post请求又有不同的请求方式。

1.retrofit进行get请求

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

如果拼接参数。如
userId=xxx

2.retrofit进行post请求发送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进行post请求发送表单数据

    @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