OkHttp3 source code (2) ------ Request

Chapter I OkHttp3 source code (I) -- OkHttpClient It's a great honor to receive comments and attention.

Next, we will analyze another commonly used class of OkHttp3 - Request. From the name, this class knows that it is a Request. What specific Request information can be set? What is its main purpose? If you don't know much about it, you can take a look at the following source code analysis.

public final class Request {
    final HttpUrl url;
    final String method;
    final Headers headers;
    final RequestBody body;
    final Object tag;
    private volatile CacheControl cacheControl; // Lazily initialized.

    Request(Builder builder) {
        this.url = builder.url;
        this.method = builder.method;
        this.headers = builder.headers.build();
        this.body = builder.body;
        this.tag = builder.tag != null ? builder.tag : this;
    }
    //Return set URL
    public HttpUrl url() {
        return url;
    }
    //Return the set method get or post
    public String method() {
        return method;
    }
    //Return all header objects (the object here can be understood as a key value pair)
    public Headers headers() {
        return headers;
    }
    //Return information with header name
    public String header(String name) {
        return headers.get(name);
    }
    //Return all information with name in the header
    public List<String> headers(String name) {
        return headers.values(name);
    }
    //Return request body
    public RequestBody body() {
        return body;
    }
    //Return the set request label
    public Object tag() {
        return tag;
    }
    //Reconstruct the object according to the parameters set by itself
    public Builder newBuilder() {
        return new Builder(this);
    }
    //Based on the cache related information set in the header, the cache controller is returned,
    public CacheControl cacheControl() {
        CacheControl result = cacheControl;
        return result != null ? result : (cacheControl = CacheControl.parse(headers));
    }
    //HTTPS protocol used or not
    public boolean isHttps() {
        return url.isHttps();
    }

    /**
     * Next is the Builder Design Pattern
     * OkHttp More design patterns used
     * If you don't know about the Builder mode, first understand it. Here is a summary of the Builder pattern: some fields of a class cannot be assigned by itself and need to be delegated to other classes.
     */
    public static class Builder {
        HttpUrl url;
        String method;
        Headers.Builder headers;
        RequestBody body;
        Object tag;

        //It can be seen that the default Request method of Request is GET, and the header is empty
        public Builder() {
            this.method = "GET";
            this.headers = new Headers.Builder();
        }
        //Recreate the object based on the parameters that Resquest has set
        Builder(Request request) {
            this.url = request.url;
            this.method = request.method;
            this.body = request.body;
            this.tag = request.tag;
            this.headers = request.headers.newBuilder();
        }
        //By setting HttpUrl, the encapsulation of String url content is omitted.
        public Builder url(HttpUrl url) {
            if (url == null) throw new NullPointerException("url == null");
            this.url = url;
            return this;
        }

        //To set the url, you need to encapsulate the content of String url as HttpUrl.
        public Builder url(String url) {
            if (url == null) throw new NullPointerException("url == null");

            // Silently replace web socket URLs with HTTP URLs.
            if (url.regionMatches(true, 0, "ws:", 0, 3)) {
                url = "http:" + url.substring(3);
            } else if (url.regionMatches(true, 0, "wss:", 0, 4)) {
                url = "https:" + url.substring(4);
            }

            HttpUrl parsed = HttpUrl.parse(url);
            if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
            return url(parsed);
        }

       //The internal implementation of setting URL is the same as String url.
        public Builder url(URL url) {
            if (url == null) throw new NullPointerException("url == null");
            HttpUrl parsed = HttpUrl.get(url);
            if (parsed == null) throw new IllegalArgumentException("unexpected url: " + url);
            return url(parsed);
        }

        //Set a header (in the form of a key value pair) and clear all headers that are the same as this name.
        public Builder header(String name, String value) {
            headers.set(name, value);
            return this;
        }
        //Add a header (in the form of a key value pair) without clearing other headers
        public Builder addHeader(String name, String value) {
            headers.add(name, value);
            return this;
        }
        //Clear all information with header name
        public Builder removeHeader(String name) {
            headers.removeAll(name);
            return this;
        }
        //Set head object
        public Builder headers(Headers headers) {
            this.headers = headers.newBuilder();
            return this;
        }

        //Set to add the information set in the cache controller to the header
        public Builder cacheControl(CacheControl cacheControl) {
            String value = cacheControl.toString();
            if (value.isEmpty()) return removeHeader("Cache-Control");
            return header("Cache-Control", value);
        }
        //Set get method and null request body
        public Builder get() {
            return method("GET", null);
        }
        //Set the post method and the request body cannot be null
        public Builder post(RequestBody body) {
            return method("POST", body);
        }
        //Set the method. If the method has a request body, the request body must be set
        public Builder method(String method, RequestBody body) {
            if (method == null) throw new NullPointerException("method == null");
            if (method.length() == 0) throw new IllegalArgumentException("method.length() == 0");
            if (body != null && !HttpMethod.permitsRequestBody(method)) {
                throw new IllegalArgumentException("method " + method + " must not have a request body.");
            }
            if (body == null && HttpMethod.requiresRequestBody(method)) {
                throw new IllegalArgumentException("method " + method + " must have a request body.");
            }
            this.method = method;
            this.body = body;
            return this;
        }

        //Label the current request body
        public Builder tag(Object tag) {
            this.tag = tag;
            return this;
        }
        //Create a Request object.
        public Request build() {
            if (url == null) throw new IllegalStateException("url == null");
            return new Request(this);
        }
    }
}

Through the analysis of the above notes, we know that:
The Request class mainly configures the Request body of the network Request,
Related parameters include HttpUrl, method, Headers, RequestBody and CacheControl.
For other parameter classes except method, it is the encapsulation of the information related to the request body of the network request.
We will explain the Headers, RequestBody and CacheControl later.

Tags: network OkHttp socket

Posted on Wed, 01 Apr 2020 14:34:34 -0700 by jesseledwards