OKHttp uses Interceptor POST and GET methods to uniformly encapsulate and pass public parameters

Posted by Tewl on Mon, 31 Jan 2022 19:30:29 +0100

In the process of using retrofit networking development, we will encounter API. Every request data will have the same public parameters.
For example:

  • User ID: 1111111
  • Device unique ID: 132131290
  • Client version number: 2.3.0
  • Wait for some parameters

However, there are two ways to request: Post and get. I basically use the get request method in the process of Baidu, which may be mostly for the convenience of testing. In the general development process, I still suggest using post to request data. Here we'll talk a little more about the difference between the two.

GET: the data of the GET request will be attached to the URL (that is, the data will be placed in the HTTP protocol header)? Split URL and transmit data, and connect parameters, such as: http://music.163.com/#/ song? id=436514312&autoplay=true&market=baiduhd. The deeper part is the transmission data of URL.

  1. The data submitted by GET can only be 1024 bytes at most. Because GET submits data through URL, the amount of data submitted by GET is directly related to the length of URL. In fact, the URL does not have the problem of parameter online, and the HTTP protocol specification does not limit the length of the URL. This display is limited by specific browsers and servers. IE limits the URL length to 2083 bytes (2K+35). For other browsers, such as Netscape and FireFox, there is no length limit in theory, which depends on the support of the operating system. Note that the limit is the length of the entire URL, not just the data length of your parameter value.

POST:POST places the submitted data in the body of the HTTP package. The HTTP protocol specification does not limit the size. There is no limit on POST data. What limits is the processing capacity of the server's handler.

1. The Security of post is higher than that of GET. Note: the Security mentioned here is not the same concept as the "Security" mentioned above. The meaning of "Security" above is only that there is no data modification, while the meaning of Security here is the real meaning of Security. For example, when submitting data through GET, the user name and password will appear in clear text on the URL, because (1) the login page may be cached by the browser, (2) others can view the browser's history, so others can GET your account and password, In addition, submitting data using GET may also cause cross site request forge attacks.

To sum up, GET is to obtain / query resource information from the server. POST is generally used to submit data to the server to update resource information. In form (form), the Method defaults to "GET". In essence, GET and POST are just different sending mechanisms, not one by one!

Reference original address: http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html

According to the above overview: we know why we use POST request instead of GET request.

Return to the theme, and what method is used to uniformly realize the transmission of public parameters.

realization

If you use OkHttp as the http request client, this becomes much easier. OkHttp provides a powerful interceptor component:

Interceptors are a powerful mechanism that can monitor, rewrite, and retry calls.

One of OKHttp's interceptor functions is to intercept the request to be sent, transform it, and then send it. The basic params interceptor implements OKHttp3 Interceptor interface.

  • addParam(String key, String value)

    When the post request is made and the body type is x-www-form-urlencoded, the public parameters of key value pairs are inserted into the body parameter, and in other cases, into the url query parameter.

  • addParamsMap(Map paramsMap)

    The same as above, but here the key value pair Map is used as a parameter for batch insertion.

  • addHeaderParam(String key, String value)

Insert a key value pair parameter into the header.

  • addHeaderParamsMap(Map headerParamsMap)

Insert the key value pair Map set in the header and insert it in batch.

  • addHeaderLine(String headerLine)

Insert the headerline string into the header. The string must conform to - 1= headerLine. Indexof (":"), that is, it can be resolved into key value pairs.

  • addHeaderLinesList(List headerLinesList)

The same as above, headerLineList: List is a parameter, and headerLine is inserted in batch.

  • addQueryParam(String key, String value)

Insert key value pair parameters into url query.

  • addQueryParamsMap(Map queryParamsMap)

Insert the key value pair parameter map into url query and insert it in batch.

Basicparamsintector Code:

package com.zy.blogs.blogssample.util;

import android.text.TextUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okio.Buffer;

/**
 * <p/>
 * Author: Zhouyuan on January 4, 2017 14:16
 * <p/>
 * Email: 244370114@qq.com
 * <p/>
 * github Address: https://github.com/jkyeo/okhttp-basicparamsinterceptor
 */
public class BasicParamsInterceptor implements Interceptor {
    Map<String, String> queryParamsMap = new HashMap<>();
    Map<String, String> paramsMap = new HashMap<>();
    Map<String, String> headerParamsMap = new HashMap<>();
    List<String> headerLinesList = new ArrayList<>();

    private BasicParamsInterceptor() {

    }

    @Override
    public Response intercept(Chain chain) throws IOException {

        Request request = chain.request();
        Request.Builder requestBuilder = request.newBuilder();

        // process header params inject
        if (headerParamsMap != null && headerParamsMap.size() > 0) {
            Set<String> keys = headerParamsMap.keySet();
            for (String headerKey : keys) {
                requestBuilder.addHeader(headerKey, headerParamsMap.get(headerKey)).build();
            }
        }

        Headers.Builder headerBuilder = request.headers().newBuilder();
        if (headerLinesList.size() > 0) {
            for (String line : headerLinesList) {
                headerBuilder.add(line);
            }
            requestBuilder.headers(headerBuilder.build());
        }
        // process header params end


        // process queryParams inject whatever it's GET or POST
        if (queryParamsMap.size() > 0) {
            request = injectParamsIntoUrl(request.url().newBuilder(), requestBuilder, queryParamsMap);
        }

        // process post body inject
        if (paramsMap.size() > 0) {
            if (canInjectIntoBody(request)) {
                FormBody.Builder formBodyBuilder = new FormBody.Builder();
                for (Map.Entry<String, String> entry : paramsMap.entrySet()) {
                    formBodyBuilder.add((String) entry.getKey(), (String) entry.getValue());
                }

                RequestBody formBody = formBodyBuilder.build();
                String postBodyString = bodyToString(request.body());
                postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody);
                requestBuilder.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString));
            }
        }

        request = requestBuilder.build();
        return chain.proceed(request);
    }

    private boolean canInjectIntoBody(Request request) {
        if (request == null) {
            return false;
        }
        if (!TextUtils.equals(request.method(), "POST")) {
            return false;
        }
        RequestBody body = request.body();
        if (body == null) {
            return false;
        }
        MediaType mediaType = body.contentType();
        if (mediaType == null) {
            return false;
        }
        if (!TextUtils.equals(mediaType.subtype(), "x-www-form-urlencoded")) {
            return false;
        }
        return true;
    }

    // func to inject params into url
    private Request injectParamsIntoUrl(HttpUrl.Builder httpUrlBuilder, Request.Builder requestBuilder, Map<String, String> paramsMap) {
        if (paramsMap.size() > 0) {
            Iterator iterator = paramsMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                httpUrlBuilder.addQueryParameter((String) entry.getKey(), (String) entry.getValue());
            }
            requestBuilder.url(httpUrlBuilder.build());
            return requestBuilder.build();
        }

        return null;
    }

    private static String bodyToString(final RequestBody request) {
        try {
            final RequestBody copy = request;
            final Buffer buffer = new Buffer();
            if (copy != null)
                copy.writeTo(buffer);
            else
                return "";
            return buffer.readUtf8();
        } catch (final IOException e) {
            return "did not work";
        }
    }

    public static class Builder {

        BasicParamsInterceptor interceptor;

        public Builder() {
            interceptor = new BasicParamsInterceptor();
        }

        public Builder addParam(String key, String value) {
            interceptor.paramsMap.put(key, value);
            return this;
        }

        public Builder addParamsMap(Map<String, String> paramsMap) {
            interceptor.paramsMap.putAll(paramsMap);
            return this;
        }

        public Builder addHeaderParam(String key, String value) {
            interceptor.headerParamsMap.put(key, value);
            return this;
        }

        public Builder addHeaderParamsMap(Map<String, String> headerParamsMap) {
            interceptor.headerParamsMap.putAll(headerParamsMap);
            return this;
        }

        public Builder addHeaderLine(String headerLine) {
            int index = headerLine.indexOf(":");
            if (index == -1) {
                throw new IllegalArgumentException("Unexpected header: " + headerLine);
            }
            interceptor.headerLinesList.add(headerLine);
            return this;
        }

        public Builder addHeaderLinesList(List<String> headerLinesList) {
            for (String headerLine : headerLinesList) {
                int index = headerLine.indexOf(":");
                if (index == -1) {
                    throw new IllegalArgumentException("Unexpected header: " + headerLine);
                }
                interceptor.headerLinesList.add(headerLine);
            }
            return this;
        }

        public Builder addQueryParam(String key, String value) {
            interceptor.queryParamsMap.put(key, value);
            return this;
        }

        public Builder addQueryParamsMap(Map<String, String> queryParamsMap) {
            interceptor.queryParamsMap.putAll(queryParamsMap);
            return this;
        }

        public BasicParamsInterceptor build() {
            return interceptor;
        }

    }
}

Specific usage:

          BasicParamsInterceptor basicParamsInterceptor =
                    new BasicParamsInterceptor.Builder()
                            .addHeaderParam("User-Agent", "xxxxxxxxxxx")
                            .addHeaderParam("Accept", "application/json")
                            .addParam("_t", time)
                            .addParam("_tsp", tsp)
                            .build();

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

            builder.addInterceptor(basicParamsInterceptor);

OkHttpClient okHttpClient = builder.build();
            mRetrofit = new Retrofit.Builder()
                    .baseUrl(ApiStores.BASE_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .client(okHttpClient)
                    .build();

This article is different from the original.

See the specific original text: http://www.jkyeo.com/2016/04/18/BasicParamsInterceptor-%E4%B8%BA-OkHttp-%E8%AF%B7%E6%B1%82%E6%B7%BB%E5%8A%A0%E5%85%AC%E5%85%B1%E5%8F%82%E6%95%B0/

Topics: http