This article shows you how to use the OkHttp library to send an HTTP GET/POST requests and some frequent used examples.

P.S Tested with OkHttp 4.2.2

pom.xml

	<dependency>
	  <groupId>com.squareup.okhttp3</groupId>
	  <artifactId>okhttp</artifactId>
	  <version>4.2.2</version>
	</dependency>

1. Synchronous Get Request

OkHttpExample1.java

package com.favtuts.http;

import java.io.IOException;

import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class OkHttpExample1 {
    
    // only one client, singleton, better puts it in a factory
    // mutiple instances will create more memory.
    private final OkHttpClient httpClient = new OkHttpClient();

    public static void main(String[] args) throws IOException {
        
        OkHttpExample1 obj = new OkHttpExample1();
        obj.sendGETSync();
        
    }

    private void sendGETSync() throws IOException {

        Request request = new Request.Builder()
            .url("https://httpbin.org/get")
            .addHeader("custom-key", "favtuts")  // add request headers
            .addHeader("User-Agent", "OkHttp Bot")
            .build();
        
        try (Response response = httpClient.newCall(request).execute()) {
            
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            // Get response headers
            Headers responseHeaders = response.headers();
            for (int i = 0; i < responseHeaders.size(); i ++) {
                System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
            }

            // Get response body
            System.out.println(response.body().string());
        }
    }

}

On Android, It crashes because you run network operation on main thread. And you get NetworkOnMainThreadException runtime exception. More details on StackOverflow

To avoid this you need to replace:

try (Response response = client.newCall(request).execute()) {
    return response.body().string();
}

with

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 {
        String url = response.body().string();
        //your code here
    }
});

OkHttpExample11.java

package com.favtuts.http;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

// Performance optimization
public class OkHttpExample11 {
    
    // only one client, singleton, better puts it in a factory
    // mutiple instances will create more memory.
    private final OkHttpClient httpClient = new OkHttpClient();

    public static void main(String[] args) throws IOException {
        
        OkHttpExample11 obj = new OkHttpExample11();
        obj.sendGETSync();
        
    }

    private void sendGETSync() throws IOException {

        Request request = new Request.Builder()
            .url("https://httpbin.org/get")
            .addHeader("custom-key", "favtuts")  // add request headers
            .addHeader("User-Agent", "OkHttp Bot")
            .build();
        
        httpClient.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 {

                // Get response headers
                Headers responseHeaders = response.headers();
                for (int i = 0; i < responseHeaders.size(); i ++) {
                    System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
                }

                 // Get response body
                System.out.println(response.body().string());
            }
        });
    }
}

Performance Issue: Let see the code block below:

String url = "https://example.com";
        for (int i = 0; i < 100; i++) {
            OkHttpClient client = new OkHttpClient();
            Request request = new Request.Builder()
                    .url(url)
                    .build();
            try (Response response = client.newCall(request).execute()) {
                System.out.println(response.body().string());
            }
        }

Avoid init OkhttpClient instance with every requests. We should init this client one time and re-use for mutiple requests.

We can create OkHttpClient in format of Singleton to avoid many objects are created when using multi stream.

OkhttpSingleton.java

package com.favtuts.http;

import okhttp3.OkHttpClient;

public class OkhttpSingleton {
    private static volatile OkHttpClient instance;
    public static OkHttpClient getInstance() {
        // Do something before get instance ...
        if (instance == null) {
            // Do the task too long before create instance ...
            // Block so other threads cannot come into while initialize
            synchronized (OkhttpSingleton.class) {
                // Re-check again. Maybe another thread has initialized before
                if (instance == null) {
                    instance = new OkHttpClient.Builder().build();
                }
            }
        }
        // Do something after get instance ...
        return instance;
    }
}

2. Asynchronous Get Request

OkHttpExample2.java

package com.favtuts.http;

import java.io.IOException;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Headers;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

public class OkHttpExample2 {

    // only one client
    private final OkHttpClient httpClient = new OkHttpClient();

    public static void main(String[] args) throws IOException {
     
        OkHttpExample2 obj = new OkHttpExample2();
        obj.sendGET();

    }
    
    private void sendGET() throws IOException {

        Request request = new Request.Builder()
                .url("https://httpbin.org/get")
                .addHeader("custom-key", "favtuts")  // add request headers
                .addHeader("User-Agent", "OkHttp Bot")
                .build();

        httpClient.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 {
                try (ResponseBody responseBody = response.body()) {
                    if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

                    // Get response headers
                    Headers responseHeaders = response.headers();
                    for (int i = 0, size = responseHeaders.size(); i < size; i++) {
                        System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
                    }

                    // Get response body
                    System.out.println(responseBody.string());
                }
            }
        });

    }
}

3. POST Request – Form Parameters

3.1 Add from parameters in RequestBody

OkHttpExample3.java

package com.favtuts.http;

import java.io.IOException;

import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class OkHttpExample3 {

    private final OkHttpClient httpClient = new OkHttpClient();
    
    public static void main(String[] args) throws IOException {
        OkHttpExample3 obj = new OkHttpExample3();
        obj.sendPOST();
    }

    private void sendPOST() throws IOException {

        // form parameters
        RequestBody formBody = new FormBody.Builder()
                .add("username", "abc")
                .add("password", "123")
                .add("custom", "secret")
                .build();

        Request request = new Request.Builder()
                .url("https://httpbin.org/post")
                .addHeader("User-Agent", "OkHttp Bot")
                .post(formBody)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {

            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            // Get response body
            System.out.println(response.body().string());
        }

    }
}

4. POST Request – JSON

4.1 Create a JSON RequestBody manually.

OkHttpExample4.java

package com.favtuts.http;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class OkHttpExample4 {

    private final OkHttpClient httpClient = new OkHttpClient();

    public static void main(String[] args) throws IOException {
        OkHttpExample4 obj = new OkHttpExample4();
        obj.sendPOST();
    }
    
    private void sendPOST() throws IOException {

        // json formatted data
        String json = new StringBuilder()
                .append("{")
                .append("\"name\":\"favtuts\",")
                .append("\"notes\":\"hello\"")
                .append("}").toString();

		// json request body
        RequestBody body = RequestBody.create(
                json,
                MediaType.parse("application/json; charset=utf-8")
        );

        Request request = new Request.Builder()
                .url("https://httpbin.org/post")
                .addHeader("User-Agent", "OkHttp Bot")
                .post(body)
                .build();

        try (Response response = httpClient.newCall(request).execute()) {

            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            // Get response body
            System.out.println(response.body().string());
        }

    }
}

5. Authentication

Start a simple Spring Security WebApp providing HTTP basic authentication, and test it with the OkHttp library.

5.1 Header authentication at Request directly.

	Request request = new Request.Builder()
		.url("http://localhost:8080/books")
		.addHeader("Authorization", Credentials.basic("user", "password"))
		.build();
				

5.2 Create an Authenticator, more flexible to handle authentication.

	private final Authenticator authenticator = new Authenticator() {
        @Override
        public Request authenticate(Route route, Response response) throws IOException {
            if (response.request().header("Authorization") != null) {
                return null; // Give up, we've already attempted to authenticate.
            }

            System.out.println("Authenticating for response: " + response);
            System.out.println("Challenges: " + response.challenges());
            String credential = Credentials.basic("user", "password");
            return response.request().newBuilder()
                    .header("Authorization", credential)
                    .build();
        }
    };

    private final OkHttpClient httpClient = new OkHttpClient
		.Builder()
		.authenticator(authenticator)
		.build();

6. FAQs

6.1 Disabled Redirect.

HttpClientExample5_1.java

	private final OkHttpClient httpClient = new OkHttpClient.Builder()
            .followRedirects(false)
            .build();

6.2 Timeout, 5 seconds.

	private final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(5, TimeUnit.SECONDS)
            .writeTimeout(5, TimeUnit.SECONDS)
            .readTimeout(5, TimeUnit.SECONDS)
            .build();

Note

More OkHttp Recipes

Download Source Code

$ git clone https://github.com/favtuts/java-core-tutorials-examples

$ cd java-misc/http

References

Leave a Reply

Your email address will not be published. Required fields are marked *