Skip to main content

Java Examples

Complete Java examples for integrating OpenFXRates using standard HTTP clients and popular libraries.

Installation

Using Maven

Add the following dependencies to your pom.xml:

<dependencies>
<!-- For Java 11+ HTTP Client (built-in) -->
<!-- Or use OkHttp -->
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.12.0</version>
</dependency>

<!-- JSON parsing -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>

<!-- For environment variables -->
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>dotenv-java</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>

Using Gradle

Add to your build.gradle:

dependencies {
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
implementation 'com.google.code.gson:gson:2.10.1'
implementation 'io.github.cdimascio:dotenv-java:3.0.0'
}

Example 1: Get Latest Rates (Java 11+ HTTP Client)

Using the built-in HTTP client available in Java 11+:

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class LatestRatesExample {
private static final String API_KEY = "your-api-key-here";
private static final String BASE_URL = "https://api.openfxrates.com";

public static void main(String[] args) {
try {
getLatestRates("USD", "EUR,GBP,JPY");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}

public static void getLatestRates(String base, String targets) throws Exception {
HttpClient client = HttpClient.newHttpClient();

String url = String.format("%s/latest_rates?base=%s&targets=%s",
BASE_URL, base, targets);

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("X-API-Key", API_KEY)
.header("Content-Type", "application/json")
.GET()
.build();

HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());

if (response.statusCode() == 200) {
Gson gson = new Gson();
JsonObject data = gson.fromJson(response.body(), JsonObject.class);

System.out.println("Base: " + data.get("base").getAsString());
System.out.println("Date: " + data.get("date").getAsString());
System.out.println("Rates:");

JsonObject rates = data.getAsJsonObject("rates");
rates.keySet().forEach(currency -> {
double rate = rates.get(currency).getAsDouble();
System.out.printf(" %s: %.4f%n", currency, rate);
});
} else {
System.err.println("HTTP Error: " + response.statusCode());
System.err.println(response.body());
}
}
}

Example 2: Convert Currency (OkHttp)

Using OkHttp library for HTTP requests:

import okhttp3.*;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.IOException;

public class CurrencyConverter {
private static final String API_KEY = "your-api-key-here";
private static final String BASE_URL = "https://api.openfxrates.com";
private static final OkHttpClient client = new OkHttpClient();
private static final Gson gson = new Gson();

public static void convertCurrency(String from, String to, double amount)
throws IOException {

HttpUrl url = HttpUrl.parse(BASE_URL + "/convert").newBuilder()
.addQueryParameter("from", from)
.addQueryParameter("to", to)
.addQueryParameter("amount", String.valueOf(amount))
.build();

Request request = new Request.Builder()
.url(url)
.addHeader("X-API-Key", API_KEY)
.build();

try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
String responseBody = response.body().string();
JsonObject data = gson.fromJson(responseBody, JsonObject.class);

System.out.printf("Converting: %.2f %s%n",
amount, data.get("from").getAsString());
System.out.println("Results:");

JsonObject conversions = data.getAsJsonObject("conversions");
conversions.keySet().forEach(currency -> {
double converted = conversions.get(currency).getAsDouble();
System.out.printf(" %s: %.2f%n", currency, converted);
});
} else {
System.err.println("Error: " + response.code());
if (response.body() != null) {
System.err.println(response.body().string());
}
}
}
}

public static void main(String[] args) {
try {
convertCurrency("USD", "EUR,GBP,JPY", 100.0);
} catch (IOException e) {
System.err.println("Conversion error: " + e.getMessage());
e.printStackTrace();
}
}
}

Example 3: Get Historical Rates

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class HistoricalRatesExample {
private static final String API_KEY = "your-api-key-here";
private static final String BASE_URL = "https://api.openfxrates.com";

public static void getHistoricalRates(String base, String date, String targets)
throws Exception {

HttpClient client = HttpClient.newHttpClient();

String url = String.format("%s/historical_rates?base=%s&date=%s&targets=%s",
BASE_URL, base, date, targets);

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("X-API-Key", API_KEY)
.GET()
.build();

HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());

if (response.statusCode() == 200) {
Gson gson = new Gson();
JsonObject data = gson.fromJson(response.body(), JsonObject.class);

System.out.println("Historical rates for " + data.get("date").getAsString());
System.out.println("Base: " + data.get("base").getAsString());
System.out.println("Rates:");

JsonObject rates = data.getAsJsonObject("rates");
rates.keySet().forEach(currency -> {
double rate = rates.get(currency).getAsDouble();
System.out.printf(" %s: %.4f%n", currency, rate);
});
} else {
System.err.println("HTTP Error: " + response.statusCode());
}
}

public static void main(String[] args) {
try {
// Get rates from January 15, 2024
getHistoricalRates("USD", "2024-01-15", "EUR,GBP");
} catch (Exception e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}

Example 4: List All Currencies

import okhttp3.*;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import java.io.IOException;

public class ListCurrencies {
private static final String API_KEY = "your-api-key-here";
private static final String BASE_URL = "https://api.openfxrates.com";
private static final OkHttpClient client = new OkHttpClient();

public static void listCurrencies() throws IOException {
Request request = new Request.Builder()
.url(BASE_URL + "/currencies")
.addHeader("X-API-Key", API_KEY)
.build();

try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
Gson gson = new Gson();
JsonObject data = gson.fromJson(response.body().string(), JsonObject.class);
JsonArray currencies = data.getAsJsonArray("currencies");

System.out.println("Available currencies: " + currencies.size() + "\n");

currencies.forEach(element -> {
JsonObject currency = element.getAsJsonObject();
String code = currency.get("code").getAsString();
String name = currency.get("name").getAsString();
String symbol = currency.has("symbol") ?
" (" + currency.get("symbol").getAsString() + ")" : "";

System.out.println(code + " - " + name + symbol);
});
}
}
}

public static void main(String[] args) {
try {
listCurrencies();
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
e.printStackTrace();
}
}
}

Example 5: API Client Class

Complete reusable client class for OpenFXRates:

import okhttp3.*;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import io.github.cdimascio.dotenv.Dotenv;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

public class OpenFXRatesClient {
private final String apiKey;
private final String baseUrl;
private final OkHttpClient client;
private final Gson gson;

public OpenFXRatesClient(String apiKey) {
this.apiKey = apiKey;
this.baseUrl = "https://api.openfxrates.com";
this.gson = new Gson();
this.client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
}

public OpenFXRatesClient() {
this(Dotenv.load().get("OPENFXRATES_API_KEY"));
}

public Optional<JsonObject> getLatestRates(String base, String targets) {
HttpUrl url = HttpUrl.parse(baseUrl + "/latest_rates").newBuilder()
.addQueryParameter("base", base)
.addQueryParameter("targets", targets)
.build();

return makeRequest(url);
}

public Optional<JsonObject> getHistoricalRates(String base, String date, String targets) {
HttpUrl url = HttpUrl.parse(baseUrl + "/historical_rates").newBuilder()
.addQueryParameter("base", base)
.addQueryParameter("date", date)
.addQueryParameter("targets", targets)
.build();

return makeRequest(url);
}

public Optional<JsonObject> convertCurrency(String from, String to, double amount) {
HttpUrl url = HttpUrl.parse(baseUrl + "/convert").newBuilder()
.addQueryParameter("from", from)
.addQueryParameter("to", to)
.addQueryParameter("amount", String.valueOf(amount))
.build();

return makeRequest(url);
}

public Optional<JsonObject> listCurrencies() {
HttpUrl url = HttpUrl.parse(baseUrl + "/currencies");
return makeRequest(url);
}

private Optional<JsonObject> makeRequest(HttpUrl url) {
Request request = new Request.Builder()
.url(url)
.addHeader("X-API-Key", apiKey)
.addHeader("Content-Type", "application/json")
.build();

try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful() && response.body() != null) {
String responseBody = response.body().string();
return Optional.of(gson.fromJson(responseBody, JsonObject.class));
} else {
System.err.println("HTTP Error: " + response.code());
if (response.body() != null) {
System.err.println(response.body().string());
}
return Optional.empty();
}
} catch (IOException e) {
System.err.println("Request failed: " + e.getMessage());
return Optional.empty();
}
}

public void close() {
client.dispatcher().executorService().shutdown();
client.connectionPool().evictAll();
}
}

Using the Client Class

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

// Get latest rates
client.getLatestRates("USD", "EUR,GBP,JPY").ifPresent(data -> {
System.out.println("Base: " + data.get("base").getAsString());
System.out.println("Rates: " + data.getAsJsonObject("rates"));
});

// Convert currency
client.convertCurrency("USD", "EUR", 100.0).ifPresent(data -> {
System.out.println("Conversions: " + data.getAsJsonObject("conversions"));
});

// Get historical rates
client.getHistoricalRates("USD", "2024-01-15", "EUR,GBP").ifPresent(data -> {
System.out.println("Historical rates for: " + data.get("date").getAsString());
System.out.println("Rates: " + data.getAsJsonObject("rates"));
});

// List all currencies
client.listCurrencies().ifPresent(data -> {
System.out.println("Total currencies: " +
data.getAsJsonArray("currencies").size());
});

client.close();
}
}

Example 6: Async Request with CompletableFuture

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
import com.google.gson.Gson;
import com.google.gson.JsonObject;

public class AsyncExample {
private static final String API_KEY = "your-api-key-here";
private static final String BASE_URL = "https://api.openfxrates.com";
private static final HttpClient client = HttpClient.newHttpClient();
private static final Gson gson = new Gson();

public static CompletableFuture<JsonObject> getLatestRatesAsync(
String base, String targets) {

String url = String.format("%s/latest_rates?base=%s&targets=%s",
BASE_URL, base, targets);

HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.header("X-API-Key", API_KEY)
.header("Content-Type", "application/json")
.GET()
.build();

return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenApply(body -> gson.fromJson(body, JsonObject.class));
}

public static void main(String[] args) {
getLatestRatesAsync("USD", "EUR,GBP,JPY")
.thenAccept(data -> {
System.out.println("Base: " + data.get("base").getAsString());
System.out.println("Date: " + data.get("date").getAsString());
System.out.println("Rates:");

JsonObject rates = data.getAsJsonObject("rates");
rates.keySet().forEach(currency -> {
double rate = rates.get(currency).getAsDouble();
System.out.printf(" %s: %.4f%n", currency, rate);
});
})
.exceptionally(e -> {
System.err.println("Error: " + e.getMessage());
return null;
})
.join(); // Wait for completion
}
}

Error Handling Example

import okhttp3.*;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import java.io.IOException;

public class ErrorHandlingExample {
private static final String API_KEY = "your-api-key-here";
private static final String BASE_URL = "https://api.openfxrates.com";
private static final OkHttpClient client = new OkHttpClient();
private static final Gson gson = new Gson();

public static class ApiException extends Exception {
private final int statusCode;

public ApiException(int statusCode, String message) {
super(message);
this.statusCode = statusCode;
}

public int getStatusCode() {
return statusCode;
}
}

public static JsonObject getLatestRatesWithErrorHandling(
String base, String targets) throws ApiException, IOException {

HttpUrl url = HttpUrl.parse(BASE_URL + "/latest_rates").newBuilder()
.addQueryParameter("base", base)
.addQueryParameter("targets", targets)
.build();

Request request = new Request.Builder()
.url(url)
.addHeader("X-API-Key", API_KEY)
.build();

try (Response response = client.newCall(request).execute()) {
String responseBody = response.body() != null ?
response.body().string() : "";

if (!response.isSuccessful()) {
JsonObject errorData = gson.fromJson(responseBody, JsonObject.class);
String errorMessage = errorData.has("message") ?
errorData.get("message").getAsString() : "Unknown error";

throw new ApiException(response.code(), errorMessage);
}

return gson.fromJson(responseBody, JsonObject.class);
}
}

public static void main(String[] args) {
try {
JsonObject data = getLatestRatesWithErrorHandling("USD", "EUR,GBP,JPY");
System.out.println("Success: " + data.get("base").getAsString());
} catch (ApiException e) {
System.err.printf("API Error (%d): %s%n",
e.getStatusCode(), e.getMessage());
} catch (IOException e) {
System.err.println("Network error: " + e.getMessage());
}
}
}

Best Practices

1. Environment Variables

Store your API key securely:

import io.github.cdimascio.dotenv.Dotenv;

public class Config {
private static final Dotenv dotenv = Dotenv.load();

public static String getApiKey() {
return dotenv.get("OPENFXRATES_API_KEY");
}
}

Create a .env file:

OPENFXRATES_API_KEY=your-api-key-here

2. Connection Pooling

Configure OkHttp for optimal performance:

OkHttpClient client = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.connectionPool(new ConnectionPool(5, 5, TimeUnit.MINUTES))
.build();

3. Retry Logic

Implement exponential backoff:

import okhttp3.*;
import java.io.IOException;

public class RetryInterceptor implements Interceptor {
private final int maxRetries;

public RetryInterceptor(int maxRetries) {
this.maxRetries = maxRetries;
}

@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = null;
IOException exception = null;

for (int i = 0; i <= maxRetries; i++) {
try {
response = chain.proceed(request);
if (response.isSuccessful()) {
return response;
}
response.close();
} catch (IOException e) {
exception = e;
if (i == maxRetries) {
throw exception;
}
}

try {
Thread.sleep((long) Math.pow(2, i) * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new IOException("Retry interrupted", e);
}
}

throw exception;
}
}

// Usage
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new RetryInterceptor(3))
.build();

4. Response Caching

Cache responses to reduce API calls:

import okhttp3.Cache;
import java.io.File;

OkHttpClient client = new OkHttpClient.Builder()
.cache(new Cache(new File("cache"), 10 * 1024 * 1024)) // 10 MB
.build();