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