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