Guide to OkHttp Library in Java

Introduction

OkHttp is a popular HTTP client library for Java and Android applications. It simplifies making network requests and handles common challenges such as connection pooling, GZIP compression, and response caching. This guide will cover the installation, basic usage, advanced features, and various use cases of OkHttp.

Installation

To use OkHttp, add the following dependency to your pom.xml if you're using Maven:

<dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>okhttp</artifactId>
    <version>4.9.3</version> <!-- or the latest version -->
</dependency>

For Gradle:

implementation 'com.squareup.okhttp3:okhttp:4.9.3' // or the latest version

Basic Usage

Creating an OkHttpClient

The OkHttpClient is the main class for making HTTP requests.

import okhttp3.OkHttpClient;

public class OkHttpClientExample {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();
    }
}

Making a GET Request

To make a GET request, create a Request object and call the newCall method on the OkHttpClient.

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;

public class GetRequestExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts/1")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

Making a POST Request

To make a POST request, use the RequestBody class to send data in the request body.

import okhttp3.*;

import java.io.IOException;

public class PostRequestExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        MediaType JSON = MediaType.get("application/json; charset=utf-8");
        String json = "{\"title\":\"foo\",\"body\":\"bar\",\"userId\":1}";
        RequestBody body = RequestBody.create(json, JSON);

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts")
                .post(body)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

Advanced Features

Asynchronous Requests

OkHttp supports asynchronous requests using callbacks.

import okhttp3.*;

import java.io.IOException;

public class AsyncGetRequestExample {
    public static void main(String[] args) {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts/1")
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    System.out.println(response.body().string());
                } else {
                    System.err.println("Request failed with status code: " + response.code());
                }
            }
        });
    }
}

Handling HTTP Headers

You can add headers to requests and read headers from responses.

import okhttp3.*;

import java.io.IOException;

public class HeadersExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts/1")
                .header("User-Agent", "OkHttp Headers Example")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println("Content-Type: " + response.header("Content-Type"));
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

Working with Query Parameters

You can build URLs with query parameters using HttpUrl.

import okhttp3.*;

import java.io.IOException;

public class QueryParametersExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        HttpUrl.Builder urlBuilder = HttpUrl.parse("https://jsonplaceholder.typicode.com/posts").newBuilder();
        urlBuilder.addQueryParameter("userId", "1");
        String url = urlBuilder.build().toString();

        Request request = new Request.Builder()
                .url(url)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

File Upload

You can upload files using MultipartBody.

import okhttp3.*;

import java.io.File;
import java.io.IOException;

public class FileUploadExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        MediaType MEDIA_TYPE_PNG = MediaType.get("image/png");

        File file = new File("path/to/your/file.png");

        RequestBody requestBody = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("file", file.getName(),
                        RequestBody.create(file, MEDIA_TYPE_PNG))
                .build();

        Request request = new Request.Builder()
                .url("https://yourapi.com/upload")
                .post(requestBody)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

File Download

Downloading files is as simple as making a GET request and saving the response body to a file.

import okhttp3.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Paths;

public class FileDownloadExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient();

        Request request = new Request.Builder()
                .url("https://example.com/file.png")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) {
                System.err.println("Request failed with status code: " + response.code());
                return;
            }

            try (InputStream in = response.body().byteStream();
                 FileOutputStream out = new FileOutputStream("downloaded_file.png")) {
                byte[] buffer = new byte[8192];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    out.write(buffer, 0, bytesRead);
                }
            }
        }
    }
}

Handling Timeouts

You can configure timeouts for connections, reads, and writes.

import okhttp3.*;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

public class TimeoutExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)
                .readTimeout(30, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .build();

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts/1")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

Interceptors

Interceptors can be used to monitor, rewrite, and retry calls. There are two types of interceptors: application interceptors and network interceptors.

Application Interceptor

import okhttp3.*;

import java.io.IOException;

public class ApplicationInterceptorExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request();
                        long startTime = System.nanoTime();
                        System.out.println(String.format("Sending request %s on %s%n%s",
                                request.url(), chain.connection(), request.headers()));

                        Response response = chain.proceed(request);

                        long endTime = System.nanoTime();
                        System.out.println(String.format("Received response for %s in %.1fms%n%s",
                                response.request().url(), (endTime - startTime) / 1e6d, response.headers()));

                        return response;
                    }
                })
                .build();

        Request request =



 new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts/1")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

Network Interceptor

import okhttp3.*;

import java.io.IOException;

public class NetworkInterceptorExample {
    public static void main(String[] args) throws IOException {
        OkHttpClient client = new OkHttpClient.Builder()
                .addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request request = chain.request();
                        System.out.println("Network interceptor: " + request.url());

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

        Request request = new Request.Builder()
                .url("https://jsonplaceholder.typicode.com/posts/1")
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }
}

Complex Examples

Example: Building a REST Client

Let's build a simple REST client using OkHttp to interact with a JSON placeholder API.

import okhttp3.*;

import java.io.IOException;

public class RestClient {
    private static final String BASE_URL = "https://jsonplaceholder.typicode.com";
    private final OkHttpClient client;

    public RestClient() {
        client = new OkHttpClient();
    }

    public void getPost(int postId) throws IOException {
        Request request = new Request.Builder()
                .url(BASE_URL + "/posts/" + postId)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }

    public void createPost(String title, String body, int userId) throws IOException {
        MediaType JSON = MediaType.get("application/json; charset=utf-8");
        String json = String.format("{\"title\":\"%s\",\"body\":\"%s\",\"userId\":%d}", title, body, userId);
        RequestBody requestBody = RequestBody.create(json, JSON);

        Request request = new Request.Builder()
                .url(BASE_URL + "/posts")
                .post(requestBody)
                .build();

        try (Response response = client.newCall(request).execute()) {
            if (response.isSuccessful()) {
                System.out.println(response.body().string());
            } else {
                System.err.println("Request failed with status code: " + response.code());
            }
        }
    }

    public static void main(String[] args) throws IOException {
        RestClient client = new RestClient();
        client.getPost(1);
        client.createPost("New Post", "This is a new post", 1);
    }
}

Output

{
  "userId": 1,
  "id": 1,
  "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
  "body": "quia et suscipit\nsuscipit...
}
{
  "id": 101,
  "title": "New Post",
  "body": "This is a new post",
  "userId": 1
}

Conclusion

OkHttp is a powerful and flexible HTTP client library for Java that simplifies making network requests. This tutorial covered the basics of creating an OkHttp client, making GET and POST requests, handling headers, query parameters, file upload/download, timeouts, and interceptors. Additionally, we explored more advanced features like building a REST client and handling asynchronous requests. By leveraging OkHttp, you can enhance your Java applications' networking capabilities. For more detailed information and advanced features, refer to the official OkHttp documentation.

Comments