Introduction to OkHttp

HTTP is commonly used in modern applications as a network method for exchanging data and media. Efficient use of HTTP can make resources load faster and save bandwidth. OkHttp is an excellent network request framework with the following default features:

  • Support for HTTP/2, allowing all requests with the same host address to share the same socket connection
  • Connection pooling reduces request latency
  • Transparent GZIP compression reduces the size of the response data
  • Cache the response content to avoid some completely duplicate requests
: @ @ @.. @ @ @ @ @ @ @ : + @ @ ` @ @ @ @ ` @ @ @ @. @ @ @ @ '@ @ @ @ : + @ @ ` @ @ @ @ ` @ @ @ @ @ @ @ @ @ @ + @ @ ` @ @ @ @ ` @ @ @ @. @ @ @ @ : +@@ @@@ '@@@@' @@@@@@ @@@@@@ @@; @ @ @ @ @ @ @ @ @ @ @ + @ @ @ @ @ ` @ @ @ @ ` @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ @ + @ @ @ @ @ ` @ @ @ @ @ @ @ @ @ @ ` @ @ @ @ @ @ @ : @ @ @ @ @ @ @ @ + @ @ @ @ @ ` @ @ @ @ @ @ @ @ @ @ ` @ @ @ @ @ @ # @ @ + @ @ @ @ @ @ + + ` @ @ @ @ @ @ @ @ @ ` @ @ @ @ @ @ : @ @ # @ @ : . @ @ ` + @ @ @ + @ @ ` @ @ @ @ ` @ @ @ @ @ @ # @ @ + @ @ @.. @ @ @ + @ @ @ @ @ ` @ @ @ @ ` @ @ @ @ @ @ @, @ @ @ @ @ @ @ @ @ @ @ + @ @ @ @ @ ` @ @ @ @ ` @ @ @ @ @ @ @ @ @ @ @ @ # @ @ @ @ @ @ @ @ @ @ @ + @ @ # @ @ ` @ @ @ @ ` @ @ @ @ : @ @ @ @ : @ @ '@ @ @ @ @ @ @ : @ @ : @ @ :Copy the code

Introducing Maven dependencies:

<! -- https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp -->
<dependency>
	<groupid>com.squareup.okhttp3</groupid>
	<artifactid>okhttp</artifactid>
	<version>${laster.version}</version>
</dependency>
Copy the code

The OkHttp project has the following modules:

The module content
okhttp The module that implements the OkHttp library
okhttp-tests OkHttp library unit test module
okhttp-android-support Modules that support the Android platform using the OkHttp library
okhttp-apache Implement the ApacheHttpClient interface (deprecated in the next version)
okhttp-testing-support Modules that support unit testing
okhttp-urlconnection Implement the HttpURLConnection interface (deprecated in the next version)
okhttp-ws Support WebSocket
okhttp-logging-interceptor Implement a Logging interceptor
okcurl Implement OkCurl
mockwebserver Scripted WebServer for testing HTTP clients

The parent module of the OkHttp project mainly contains the following plug-ins:

The plug-in use
maven-compiler-plugin Compile the project
maven-surefire-plugin Perform the test
maven-javadoc-plugin Generating documentation
maven-release-plugin Automate project release
maven-checkstyle-plugin Detecting coding style
animal-sniffer-maven-plugin Test code API

The official introduction

Making the source code

2. Basic use of OkHttp

2.1 Performing Get requests

Making a Get request using OkHttp requires only four steps:

  1. Create the okHttpClient object

    OkHttpClient client = new OkHttpClient();
    Copy the code
  2. Constructing the Request object

    // Create a Request object with at least a URL. You can set more parameters such as header, method, and so on through the Request.Builder
    Request request = new Request.Builder().get().url("https://api.github.com/users/dllwh").build();
    Copy the code
  3. Encapsulate a Request as a Call

    // Construct a Call object from the request object, similar to encapsulating the request as a task
    Call call = client.newCall(request);
    Copy the code
  4. Call synchronous or asynchronous request methods as needed

    // A synchronous call, which returns Response, requires that an IO exception is thrown
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }
    Copy the code

    > Synchronous calls block the main thread until the HTTP response is returned. Execute method in OKHTTP does not apply.

    // Execute the request asynchronously
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {}@Override
        public void onResponse(Call call, final Response response) throws IOException {
            // HTTP response line code, if the access is successful returns 200. This is not set by the server, but is built into the HTTP protocol.
    				final int httpCode = response.code();
            ResponseBody responseBody = response.body();
            // Returns a string that can only be called once. The first call returns a value, and the second call returns null.
            final String res = responseBody.string();
            // The array of binary bytes returned
            final byte[] bytes = responseBody.bytes();
            // Return the InputStream
            finalInputStream inputStream = responseBody.byteStream(); }});Copy the code

    A non-blocking request is executed asynchronously, and the result is usually notified to the caller via an interface callback corresponding to the enqueue method in OKHTTP.

2.2 Performing a Post request

2.2.1 Post Request key and Value pairs

Many times we need to POST key-value pairs to the server, and OkHttp provides a convenient way to do this. Making a Post request using OkHttp is similar to making a Get request. It takes only five steps to complete:

  1. Create the okHttpClient object

    OkHttpClient client = new OkHttpClient();
    Copy the code
  2. Build the FormBody, passing in the parameters

    okhttp3.FormBody.Builder builder = new FormBody.Builder();
    builder.add("username"."admin");
    builder.add("password"."admin");
    FormBody formBody = builder.build();
    Copy the code

    The > post parameter is added by constructing a FormBody with a key-value pair. In fact, what the post method needs to pass in is a RequestBody object that carries the data we want to submit. FormBody is a subclass of RequestBody.

  3. Build the Request, passing in the FormBody as a parameter to the Post method

    Request request = new Request.Builder().url(url).post(formBody).build();
    Copy the code
  4. Encapsulate a Request as a Call

    Call call = client.newCall(request);
    Copy the code
  5. Call synchronous or asynchronous request methods as needed.

    // Call synchronously, return Response, which corresponds to the execute method in OKHTTP, and throw an IO exception.
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }
    Copy the code
    Non-blocking requests are executed asynchronously, and the result is usually notified to the caller via an interface callback, which corresponds to the enqueue method in OKHTTP.
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {}@Override
        public void onResponse(Call call, final Response response) throws IOException {
        	if (response.isSuccessful()) {
    
            }
        }
    });
    Copy the code

2.2.2 The Post request submits a Json file

  1. Create the okHttpClient object

    OkHttpClient client = new OkHttpClient();
    Copy the code
  2. Build the RequestBody, passing in the parameters

    MediaType mediaType = MediaType.parse("application/json; charset=UTF-8");
    RequestBody requestBody = RequestBody.create(mediaType, "{username:admin; password:admin}");
    Copy the code

    The difference between this approach and the previous one is that when we construct the Request object, we need to construct a RequestBody object to carry the data we want to submit. When constructing the RequestBody, you need to specify the MediaType, which describes the content type of the request/response body.

  3. Build the Request, passing in the FormBody as a parameter to the Post method

    Request request = new Request.Builder().url("http://www.jianshu.com/").post(requestBody).build();
    Copy the code
  4. Encapsulate a Request as a Call

    Call call = client.newCall(request);
    Copy the code
  5. Call synchronous or asynchronous request methods as needed.

    // Call synchronously, return Response, and throw AN IO exception
    Response response = call.execute();
    if (response.isSuccessful()) {
        System.out.println(response.body().string());
    }
    Copy the code
    Non-blocking requests are executed asynchronously, and the result is usually notified to the caller via an interface callback, which corresponds to the enqueue method in OKHTTP.
    call.enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {}@Override
        public void onResponse(Call call, final Response response) throws IOException {
            if (response.isSuccessful()) {
    
            }
        }
    });
    Copy the code

2.2.3 Post request submission form

This is a form, so let’s take a look at how to use OkHttp for form submission. The main difference is to construct a different RequestBody to pass to the POST method. Here we’re going to use a MuiltipartBody, which is a subclass of RequestBody, and we’re going to use this class to build a RequestBody when we submit the form, and in the code below we’re going to send a user name and password to the server.

@Test
public void doPostForm(a) throws IOException {
	OkHttpClient okHttpClient = new OkHttpClient();
	okhttp3.MultipartBody.Builder builder = new MultipartBody.Builder();
	// If you are submitting a form, make sure to set this sentence
	builder.setType(MultipartBody.FORM);
	builder.addFormDataPart("username"."admin");
	builder.addFormDataPart("password"."admin");
	RequestBody requestBody = builder.build();

	Request request = new Request.Builder().url("https://en.wikipedia.org/w/index.php").post(requestBody).build();
	Response response = okHttpClient.newCall(request).execute();
	if(! response.isSuccessful()) {throw new IOException("Unexpected code " + response);
	}
	System.out.println(response.body().string());
}
Copy the code

2.3 Uploading and Downloading files

2.3.1 Post Requests to upload files

Next we’ll introduce a RequestBody Builder called MultipartBuilder that can construct requestBodies. We can use it to construct our requestBody whenever we need to do something like a form upload.

2.3.2 GET Requests to download files

@Test
public void doGetFilePro(a) {
    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder()
        .url("http://publicobject.com/helloworld.txt")
        .build();
    Response response = okHttpClient.newCall(request).execute();
    if(! response.isSuccessful()) {throw new IOException("Unexpected code " + response);
    }
    Headers headers = response.headers();
    for (int i = 0; i &lt; headers.size(); i++) {
        System.out.println(headers.name(i) + ":" + headers.value(i));
    }
    System.out.println(response.body().string());
}
Copy the code

2.4 Configuring HTTP Header Attributes

A typical HTTP header is like a Map

, where each field has one or no value. When writing a request header, use header(name, value) to set a unique name and value. If there is already a value, the old one is removed and the new one is added. Use addHeader(name, value) to add multiple values (adding, not removing). When reading the response header, use header(name) to return the last name and value. Usually this is the only name and value. If there is no value, then header(name) will return null. Headers (name) returns a list if you want to read all values for a field.
,>

@Test
public void doHeader(a) throws IOException {
    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder()
            .url("https://api.github.com/repos/square/okhttp/issues")
            .header("User-Agent"."OkHttp Headers.java")
            .addHeader("Accept"."application/json; Q = 0.5")
            .addHeader("Accept"."application/vnd.github.v3+json")
            .build();
    Response response = okHttpClient.newCall(request).execute();
    if(! response.isSuccessful()) {throw new IOException("Unexpected code " + response);
    }
    System.out.println("Server: " + response.header("Server"));
    System.out.println("Date: " + response.header("Date"));
    System.out.println("Vary: " + response.headers("Vary"));
}
Copy the code

Third, summary

As we can see from the example above, OkHttp is very convenient to use in many cases, and a lot of code is duplicated, and the official OkHttp documentation does not recommend that we create multiple OkHttpClients, so we can use one globally.

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import java.io.IOException;
import java.util.Map;

/** * Take today's best performance as the latest starting point for tomorrow... ~ * <p> * Today the best performance as tomorrow newest starter! * * @ Class description: basic use of OkHttp@author: <a href="mailto:[email protected]"> </a@since: the JDK 1.8 *@see< a href = "https://square.github.io/okhttp/" > official introduction < / a > * /
@Slf4j
public final class OkHttpHelper {
    static ObjectMapper mapper = new ObjectMapper();
    /** * Get the operation class */
    private static final OkHttpClient okHttpClient = new OkHttpClient();
    private static final String CHARSET_NAME = "UTF-8";
    private static final MediaType JSONMediaType = MediaType.parse("application/json; charset=UTF-8");

    /** * Synchronous get request **@param url
     * @return
     * @throws IOException
     */
    public static String doGet(String url) throws IOException {
        Request request = new Request.Builder().get().url(url).build();
        Call call = okHttpClient.newCall(request);
        return execute(request);
    }

    /** * Asynchronous get request **@param url
     * @return
     * @throws IOException
     */
    public static void doSyncGet(String url) throws IOException {
        Request request = new Request.Builder().get().url(url).build();
        Call call = okHttpClient.newCall(request);
        enqueue(request);
    }

    /** * Synchronous POST request */
    public static String doPost(String url, Map<string, object> params) throws IOException {
        RequestBody requestBody = RequestBody.create(JSONMediaType, mapper.writeValueAsString(params));
        Request.Builder builder = new Request.Builder();

        Request request = builder.url(url).post(requestBody).build();
        log.info("do post request and url[{}]", mapper.writeValueAsString(request));
        return execute(request);
    }

    /** * Synchronous POST request */
    public static String doPost(String url, String params) throws IOException {
        RequestBody requestBody = RequestBody.create(JSONMediaType, params);
        Request.Builder builder = new Request.Builder();

        Request request = builder.url(url).post(requestBody).build();
        log.info("do post request and url[{}]", mapper.writeValueAsString(request));
        return execute(request);
    }

    /** * Asynchronous POST request */
    public static void doSyncPost(String url, String params) {
        RequestBody body = RequestBody.create(JSONMediaType, params);
        Request request = new Request.Builder().url(url).post(body).build();
        enqueue(request);
    }

    public static String doPostJSON(String url, Map<string, object> params, Headers headers) throws IOException {

        RequestBody requestBody = RequestBody.create(JSONMediaType, mapper.writeValueAsString(params));
        Request.Builder builder = new Request.Builder();

        Request request = builder.url(url).post(requestBody).headers(headers).build();
        log.info("do post request and url[{}]", mapper.writeValueAsString(request));
        return execute(request);
    }

    /** * Synchronous requests do not start asynchronous threads **@param request
     * @return
     * @throws IOException
     */
    private static String execute(Request request) throws IOException {
        log.info("Request start: Request address :{}", request.url());
        Response response = okHttpClient.newCall(request).execute();
        if (response.isSuccessful()) {
            String res = response.body().string();
            log.info("Request returned :{}", res);
            return res;
        } else {
            throw new IOException("Unexpected code "+ response); }}/** * Enable asynchronous thread access **@param request
     * @param responseCallback
     */
    public static void enqueue(Request request, Callback responseCallback) {
        okHttpClient.newCall(request).enqueue(responseCallback);
    }

    /** * Enable asynchronous threads to access the network, and do not care about returning the result (implementing an empty callback) **@param request
     */
    private static void enqueue(Request request) {
        okHttpClient.newCall(request).enqueue(new Callback() {

            @Override
            public void onFailure(Call call, IOException e) {
                log.error("",e);
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {Decide to decideif (response.isSuccessful()) {
                    log.info("Successful data acquisition . . . ");
                    log.info("response.code()==" + response.code());
                    log.info("response.body().string()=="+ response.body().string()); }}}); }}Copy the code